Передача вывода ssh sudo

Иногда мне нужно запускать команды от имени пользователя 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

Я уверен, что должно быть хорошее решение для этого, поскольку это не кажется необычным. Есть идеи?


person Richard Smith    schedule 09.05.2019    source источник
comment
Почему вы используете sudo вместо ssh в первую очередь?   -  person jww    schedule 10.05.2019
comment
Как еще вы предлагаете мне выполнить код от имени пользователя root на удаленном сервере, который не позволяет войти в систему с правами root (т. е. имеет PermitRootLogin no в /etc/ssh/sshd_config), @jww? Может быть, есть лучшее решение, но я не могу сразу придумать его.   -  person Richard Smith    schedule 10.05.2019


Ответы (1)


Лучшее решение, которое я придумал, - использовать sudo -S и отключить локальное эхо, чтобы пароль не отображался при его вводе:

$ { stty -echo; ssh remote sudo -S echo hello; stty echo; echo 1>&2; }
[sudo] password for user:
hello

Это оставляет sudo ответственным за запрос пароля, поэтому он работает правильно, если пользователь вводит пароль неправильно.

Я не думаю, что любое решение, использующее ssh -t, когда-либо сможет работать должным образом, поскольку оно сочетает в себе stderr и stdout.

person SystemParadox    schedule 21.08.2019
comment
После 1>&2 отсутствует точка с запятой. - person Richard Smith; 24.08.2019
comment
Если вы хотите, чтобы новая строка отображалась в нужном месте, вы хотите сделать это эхо перед отображением удаленного содержимого: т. е. { stty -echo; ssh remote sudo -S "echo 1>&2; echo bar"; stty echo; } | tr bar foo - person Richard Smith; 24.08.2019
comment
Исправлена ​​отсутствующая точка с запятой. Спасибо! - person SystemParadox; 26.08.2019
comment
Это полезный пример, когда вам нужен вывод на терминал. Если вы перенаправляете вывод в файл или команду, которая не дает никакого вывода, то не имеет значения, где появляется новая строка, и вы можете использовать мою немного более простую версию (без кавычек). - person SystemParadox; 26.08.2019