правильный способ sudo над ssh


150

У меня есть скрипт, который запускает другой скрипт через SSH на удаленном сервере, используя sudo. Однако, когда я набираю пароль, он появляется на терминале. (В остальном работает нормально)

ssh user@server "sudo script"

Какой правильный способ сделать это, чтобы я мог ввести пароль для sudo через SSH без пароля, появляющегося при вводе?


2
что касается меня, причина искать способ sudoing через ssh заключалась в том, что он не работал при попытке что-то вроде ssh <user@server> sudo <script>, так как я получал ошибкуsudo: no tty present and no askpass program specified
knocte

Ответы:


244

Другой способ - использовать -tпереключатель для ssh:

ssh -t user@server "sudo script"

Смотрите man ssh:

 -t      Force pseudo-tty allocation.  This can be used to execute arbi-
         trary screen-based programs on a remote machine, which can be
         very useful, e.g., when implementing menu services.  Multiple -t
         options force tty allocation, even if ssh has no local tty.

2
Хорошо, я знал об опции -t, просто не знал, что она работает для приглашений sudo.

3
для чего нужна опция -t?
Винс


3
Это не работает здесь: ssh -t localhost <<< "sudo touch file;"РЕДАКТИРОВАТЬ Очевидно, что вы действительно предоставляете команду как параметр, а не через стандартное (что имеет смысл задним числом).
Ограниченное искупление

-tметод также покажет цветной вывод команд , которые обычно сделать это.
Кармаказе

24

Я смог полностью автоматизировать его с помощью следующей команды:

echo pass | ssh -tt user@server "sudo script"

Преимущества:

  • без пароля
  • не будет показывать пароль в истории удаленной машины

Относительно безопасности: как сказал Курт , выполнение этой команды покажет ваш пароль в вашей локальной истории bash, и лучше сохранить пароль в другом файле или сохранить команду all в файле .sh и выполнить ее. ПРИМЕЧАНИЕ. Файл должен иметь правильные разрешения, чтобы доступ к нему имели только разрешенные пользователи.


8
Он будет отображаться в истории локальной системы, включая пароль. Лучше хранить пароль в файле и катать файл.
Курт Фитцнер

4
Чувак, я знал об этом -t, но я не прочитал руководство достаточно внимательно, чтобы увидеть, что ты мог пройти его дважды! Это то, что я искал месяцами! В качестве дополнения безопасности, я просто установил переменную пароля перед запуском read -s -p "Password: " pw, а затем сделал echo "$pw" | ..... Я сейчас свернул это в удобный сценарий для себя :).
каэль

Работал как шарм для меня!
MiKr13

Почему бы вам просто не настроить sudo без пароля для каких-либо конкретных пользователей и команд, которые вам нужно выполнить? Это не проблема SSH ...
номен

@nomen ваше решение также действительно, но требует дополнительных шагов. Если у меня много устройств без пользователя sudo без пароля, я могу создать скрипт автоматизации с помощью этого решения. Иногда вы работаете в системе, которой вы не владеете, и вы не хотите или не можете вносить изменения, иногда есть другие соображения.
офируле

6

Предполагая, что вы не хотите запрашивать пароль :

ssh $HOST 'echo $PASSWORD | sudo -S $COMMMAND'

пример

ssh me@localhost 'echo secret | sudo -S echo hi' # outputs 'hi'

14
Это / очень / опасно, так как незашифрованный пароль заканчивается в командной строке. Командные строки являются общедоступными и могут быть просмотрены любым другим пользователем и процессом в системе. Например, «ps auxwwwww» непривилегированного пользователя покажет каждый запущенный процесс и командные строки, которые его запускали.
Курт Фитцнер

3
Не говоря уже о введении вашего пароля (в виде открытого текста) в файл bash_history.
Лэйн Бернардо

5

Sudo over SSH с передачей пароля, tty не требуется:

Вы можете использовать sudo поверх ssh, не заставляя ssh иметь псевдо-tty (без использования ключа ssh "-t"), указав sudo не требовать интерактивный пароль и просто получить пароль от стандартного ввода. Вы делаете это с помощью переключателя "-S" на sudo. Это заставляет sudo прослушивать пароль на stdin и прекращать прослушивание, когда видит новую строку.

Пример 1 - Простая удаленная команда

В этом примере мы отправляем простую whoamiкоманду:

$ ssh user@server cat \| sudo --prompt="" -S -- whoami << EOF
> <remote_sudo_password>
root

Мы говорим sudo не выдавать приглашение и принимать его от stdin. Это делает пароль sudo абсолютно бесшумным, поэтому единственный ответ, который вы получите, - это вывод whoami.

Преимущество этого метода заключается в том, что вы можете запускать программы через sudo по ssh, которые сами требуют ввода stdin. Это связано с тем, что sudo использует пароль в первой строке стандартного ввода, а затем разрешает любой программе, которая запускается, продолжать захват стандартного ввода.

Пример 2 - Удаленная команда, которая требует своего собственного стандартного ввода

В следующем примере удаленная команда «cat» выполняется через sudo, и мы предоставляем несколько дополнительных строк через stdin для отображения удаленной кошкой.

$ ssh user@server cat \| sudo --prompt="" -S -- "cat" << EOF
> <remote_sudo_password>
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2

Выходные данные демонстрируют, что <remote_sudo_password>строка используется sudo, и что удаленно выполняемый cat отображает дополнительные строки.

Пример того, где это может быть полезно, - это если вы хотите использовать ssh для передачи пароля привилегированной команде без использования командной строки. Скажем, если вы хотите смонтировать удаленный зашифрованный контейнер поверх ssh.

Пример 3 - Монтирование удаленного контейнера VeraCrypt

В этом примере сценария мы удаленно монтируем контейнер VeraCrypt через sudo без дополнительного текста запроса:

#!/bin/sh
ssh user@server cat \| sudo --prompt="" -S -- "veracrypt --non-interactive --stdin --keyfiles=/path/to/test.key /path/to/test.img /mnt/mountpoint" << EOF
SudoPassword
VeraCryptContainerPassword
EOF

Следует отметить, что во всех приведенных выше примерах командной строки (все, кроме сценария) << EOFконструкция командной строки будет приводить к тому, что все набранное, включая пароль, будет записано в .bash_history на локальной машине. Поэтому настоятельно рекомендуется, чтобы для реального использования вы использовали либо полностью, через скрипт, как в примере с veracrypt выше, либо, если в командной строке, поместили пароль в файл и перенаправили этот файл через ssh.

Пример 1a - Пример 1 без локального пароля командной строки

Таким образом, первым примером станет:

$ cat text_file_with_sudo_password | ssh user@server cat \| sudo --prompt="" -S -- whoami
root

Пример 2a - Пример 2 без локального пароля командной строки

и второй пример станет:

$ cat text_file_with_sudo_password - << EOF | ssh va1der.net cat \| sudo --prompt="" -S -- cat
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2

Поместить пароль в отдельный файл не нужно, если вы помещаете все это в сценарий, так как содержимое сценариев не попадает в вашу историю. Тем не менее, это может быть полезно, если вы хотите разрешить пользователям, которые не должны видеть пароль, выполнять скрипт.


В удаленной команде ssh, почему вам нужно выполнить catи передать результаты в sudo? Вы можете просто использовать sudoв качестве основной команды SSH Remote?
Joanpau

@joanpau Начальная буква catиспользуется для передачи пароля пользователя к sudo с другой стороны. Если пользователь может запустить sudo без пароля, то это не требуется, но я не предлагаю эту конфигурацию. Причина этого в том, что пароль не отображается в командной строке удаленного sysrtem. Командные строки небезопасны, любой пользователь может видеть каждую командную строку с помощью ps auxwww.
Курт

Я прошу catв команде ssh cat \| sudo --prompt="" -S.... Если -Sзаставляет sudoчитать пароль со стандартного ввода, нужен ли вообще кот и труба? Может ли команда ssh просто быть sudo --prompt="" -S...?
Joanpau

@jonpau Эта команда cat берет стандартный ввод и передает его через sudo, чтобы передать ему пароль sudo. Он показывает, как можно безопасно передать пароль sudo через ssh через stdin.
Курт

1

Лучший способ ssh -t user@server "sudo <scriptname>", например ssh -t user@server "sudo reboot". Сначала будет запрашиваться пароль для пользователя, а затем для пользователя root (поскольку мы запускаем скрипт или команду с привилегиями root.

Я надеюсь, что это помогло и очистило ваши сомнения.




-1

Я столкнулся с проблемой,

user1@server1$ ssh -q user1@server2 sudo -u user2 rm -f /some/file/location.txt

Output:
sudo: no tty present and no askpass program specified

Тогда я попробовал с

#1
vim /etc/sudoers
Defaults:user1    !requiretty

не работал

#2
user1   ALL=(user2)         NOPASSWD: ALL

это работало правильно!


Это действительно не выполняет то, что просят. Идея состоит в том, чтобы по-прежнему требовать пароль, но разрешить его ввод через ssh. То, что вы сделали, это просто предоставили пользователю user1 полный доступ к пользователю sudo без пароля. Это хорошо для конкретных приложений, но не лучшая идея в качестве общего решения.
Поссум

-7

В зависимости от вашего использования, я имел успех со следующим:

ssh root@server "script"

Это запросит пароль root и затем правильно выполнит команду.


26
Yikes, SSH как root? Это плохая идея по разным причинам.
Darkfeline

12
Помните, что ssh - это не telnet. Для ssh от имени root не более опасно, чем для ssh от имени другого пользователя и запуска sudo. Ваш пароль зашифрован таким же образом через соединение ssh.
Стефан

22
Стефан абсолютно прав в отношении безопасности паролей. Однако, используя root вместо sudo, вы теряете контрольный журнал, который идет с sudo. Кроме того, root-доступ может быть недоступен.
djeikyb
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.