правильний спосіб судо над ssh


150

У мене є сценарій, який запускає інший скрипт через SSH на віддаленому сервері за допомогою sudo. Однак, коли я набираю пароль, він відображається на терміналі. (Інакше це добре працює)

ssh user@server "sudo script"

Який правильний спосіб це зробити, щоб я міг вводити пароль для sudo над SSH, не з'являючись при введенні пароля?


2
що стосується мене, то причиною пошуку способу судоутворення через 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, просто не знав, що він працює для судо-підказки.

3
для чого варіант -t?
Вінс


3
Тут це не працює: ssh -t localhost <<< "sudo touch file;"EDIT Мабуть, важливо, щоб ви фактично надавали команду як параметр, а не через стандарт в (що має сенс у задньому огляді).
Обмежене спокутування

-tметод також покаже кольоровий висновок команд , які зазвичай зробити це.
karmakaze

24

Мені вдалося повністю автоматизувати його за допомогою наступної команди:

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

Переваги:

  • немає запиту про введення пароля
  • не відображатиметься паролем у історії баш віддаленої машини

Що стосується безпеки: як сказав Курт , запуск цієї команди покаже ваш пароль у вашій локальній історії bash, і краще зберегти пароль в іншому файлі або зберегти всю команду у .sh-файлі та виконати її. ПРИМІТКА. Файл повинен мати правильні дозволи, щоб доступ до нього мали лише дозволені користувачі.


8
Він відображатиметься в історії баш локальної системи, включаючи пароль. Краще зберігати пароль у файлі та котувати файл.
Курт Фіцнер

4
Людина, я знав про це -t, але я не прочитав посібник достатньо уважно, щоб побачити, що ти можеш передати його двічі! Це те, що я шукав місяцями! Як додаток до безпеки, я просто встановив змінну пароля перед запуском read -s -p "Password: " pw, потім зробив echo "$pw" | ..... Зараз я переклав це на зручний сценарій для себе :).
Кель

Працювало як шарм для мене!
MiKr13

Чому ви просто не встановите бездоглядний sudo для будь-яких конкретних користувачів та команд, які вам потрібно виконати? Це не проблема SSH ...
номен

@nomen ваше рішення також дійсне, але вимагає додаткових кроків. Якщо у мене багато пристроїв без безоплатного користувача sudo, я можу створити сценарій автоматизації за допомогою цього рішення. Іноді ви працюєте в системі, якій ви не володієте, і ви не хочете або не можете вносити зміни, іноді виникають інші міркування.
ofirule

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.
Layne Bernardo

4

Судо над SSH, передаючи пароль, не потрібно:

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

Приклад 1 - Проста віддалена команда

У цьому прикладі ми надсилаємо просту whoamiкоманду:

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

Ми говоримо sudo не видавати підказку, а брати його з stdin. Це робить пароль sudo абсолютно безшумним, тому єдиною відповіддю, яку ви отримуєте, є вихід whoami.

Цей прийом має перевагу, що дозволяє запускати програми через sudo over ssh, які самі потребують введення stdin. Це тому, що sudo споживає пароль через перший рядок stdin, а потім дозволяє будь-якій програмі, яку він запускає, продовжувати захоплювати stdin.

Приклад 2 - Віддалена команда, яка потребує власного stdin

У наступному прикладі віддалена команда "кішка" виконується через 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, а потім віддалений виконаний кіт демонструє додаткові лінії.

Приклад, де це було б корисно, якщо ви хочете використовувати 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

Приклад 2а - Приклад 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?
joanpau

@joanpau Початковий catвикористовується для передачі пароля користувача через sudo з іншого боку. Якщо користувач може запускати sudo без пароля, це не потрібно, але я не пропоную цю конфігурацію. Причина, по якій це відбувається, полягає в тому, щоб запобігти появі пароля у командному рядку віддаленого sysrtem. Командні рядки не захищені, будь-який користувач може бачити кожен командний рядок ps auxwww.
Курт Фіцнер

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

@jonpau Ця команда кішки приймає stdin і пропускає її через 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. Що ви зробили, це щойно наданий користувачеві1 повний доступ до sudo для користувача2 без пароля. Це добре для конкретних програм, але не найкраща ідея як загальне рішення.
Опосум

-7

Залежно від вашого використання, я мав успіх у наступному:

ssh root@server "script"

Після цього буде введено кореневий пароль, а потім виконано команду правильно.


26
Yikes, SSH як корінь? Це погана ідея з усіляких причин.
darkfeline

12
Пам'ятайте, що ssh - це не telnet. Це не небезпечніше для ssh як root, ніж для ssh як іншого користувача та запуску sudo. Ваш пароль шифрується аналогічно через ssh-з'єднання.
Стефан

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