Иногда мне нужно запускать команды от имени пользователя root на удаленном сервере и анализировать вывод команды на моем локальном сервере. Удаленный сервер не разрешает вход в систему root с помощью ssh
, но sudo
настроен таким образом, что требуется пароль. Упрощенный пример того, что мне нужно сделать, это
ssh remote sudo echo bar | tr bar foo
(Очевидно, что в этом упрощенном примере нет веских причин запускать echo
на другой машине, чем tr
: это просто игрушечный пример, объясняющий, что я пытаюсь сделать.)
Если я запускаю приведенную выше команду, я получаю сообщение об ошибке, что sudo не может запросить пароль:
richard@local:~$ ssh remote sudo echo bar | tr bar foo
sudo: no tty present and no askpass program specified
Один из способов исправить это — добавить параметр -t
к ssh
. Если я это сделаю, sudo
будет ожидать и принять пароль, но вывод псевдотерминала ssh
пойдет на стандартный вывод, что означает, что подсказка sudo передается на tr
и не отображается пользователю. Если пользователь не знает, что sudo
ожидает ввода пароля, он решит, что скрипт завис, и передача подсказки в конвейер, вероятно, нарушит дальнейшую обработку:
richard@local:~$ ssh -t remote sudo echo bar | tr bar foo
[sudo] posswood foo oichood:
foo
(Этот заведомо глупый пример показывает, что приглашение было обработано командой tr
, на которую передаются выходные данные.)
Другой способ, который я вижу, чтобы попытаться исправить это, — добавить параметр -S
к sudo
. Если я это сделаю, sudo
запрашивает пароль на stderr, поэтому запрос не передается по конвейеру. Это хорошо, но sudo
также принимает пароль при стандартном вводе, что означает, что он отображается на терминале, где любой, кто смотрит через плечо пользователя, может его прочитать:
richard@local:~$ ssh remote sudo -S echo bar | tr bar foo
[sudo] password for richard: p8ssw0rd
foo
Я нашел неэлегантные способы обойти проблемы с этими двумя вариантами, но мои обходные пути столкнулись с проблемой, если пользователь в первый раз неправильно ввел свой пароль. Это само по себе является проблемой. Примеры этого:
richard@local:~$ echo "[sudo] password for $USER:"; \
ssh -t remote sudo echo bar | tail +2 | tr bar foo
richard@local:~$ (read -s password; echo $password; echo >&2) \
| ssh remote sudo -S echo bar | tr bar foo
Я уверен, что должно быть хорошее решение для этого, поскольку это не кажется необычным. Есть идеи?
sudo
вместоssh
в первую очередь? - person jww   schedule 10.05.2019PermitRootLogin no
в/etc/ssh/sshd_config
), @jww? Может быть, есть лучшее решение, но я не могу сразу придумать его. - person Richard Smith   schedule 10.05.2019