Автоматический ввод пароля SSH с помощью скрипта


194

Мне нужно создать скрипт, который автоматически вводит пароль для sshклиента OpenSSH .

Допустим, мне нужен SSH myname@somehostс паролем a1234b.

Я уже попробовал ...

#~/bin/myssh.sh
ssh myname@somehost
a1234b

... но это не работает.

Как я могу получить эту функциональность в сценарий?

Ответы:


278

Сначала вам нужно установить sshpass .

  • Ubuntu / Debian: apt-get install sshpass
  • Fedora / CentOS: yum install sshpass
  • Arch: pacman -S sshpass

Пример:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM

Пример пользовательского порта:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM:2400

Ноты:

  • sshpassтакже может прочитать пароль из файла, когда -fфлаг передан.
    • Использование -fпредотвращает видимость пароля при выполнении psкоманды.
    • Файл, в котором хранится пароль, должен иметь безопасные разрешения.

12
Это намного лучше, чем использовать Expect.
Пер Меджал Расмуссен

5
просто имейте в виду, что, хотя sshpass блокирует ваш пароль от таких команд, как ps -auxобычно, вы не должны запускать команды, набирая ваш пароль, потому что другие пользователи на том же компьютере могут видеть пароль при запуске ps -aux. если это целесообразно, вы также хотите использовать аутентификацию с открытым ключом, как указано в другом ответе. это позволяет вам отделить информацию аутентификации от вашего скрипта, чтобы вы могли без проблем делиться своим скриптом с другими, а затем решите включить шифрование в вашей папке ~ / .ssh без шифрования вашего скрипта.
Александр Тейлор

2
К сожалению, это не работает для меня на сервере с пользовательским портом ssh ... почему ssh не может просто дать нам возможность вставить пароль в командной строке?
Энди

2
для работы нестандартного порта добавьте «-p номер порта» в конце команды
Ye Lwin Soe


96

После нескольких месяцев поиска ответа на вопрос я наконец нашел лучшее решение: написание простого сценария.

#!/usr/bin/expect

set timeout 20

set cmd [lrange $argv 1 end]
set password [lindex $argv 0]

eval spawn $cmd
expect "assword:"
send "$password\r";
interact

Поместите это /usr/bin/exp, тогда вы можете использовать:

  • exp <password> ssh <anything>
  • exp <password> scp <anysrc> <anydst>

Готово!


2
Этот ответ должен получить больше голосов IMO, это отличная обертка. Просто попробовал несколько общих операций, таких как rsyncing с различными флагами и удаленное выполнение команд, и это работало каждый раз. Добавлено в мой набор полезных скриптов, Спасибо @damn_c!
user2082382

7
Возможно это не получило больше голосов, потому что люди не ожидали этого?
ясный свет

7
Причина, по которой ИМО не очень хороший ответ, заключается в том, что пароль написан в сценарии, который является наименее безопасным методом ...
PierreE

8
Пароль будет виден любому, кто запускает ps на машине.
Даниэль Перссон

22
"задница" удивительна :-)
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

71

Использовать аутентификацию с открытым ключом: https://help.ubuntu.com/community/SSH/OpenSSH/Keys

На исходном хосте выполните это только один раз:

ssh-keygen -t rsa # ENTER to every field
ssh-copy-id myname@somehost

Вот и все, после этого вы сможете делать ssh без пароля.


21
Понимаю. Но я ОБЯЗАН ssh с паролем. Это потому, что «Я» может иметь скрипт на флэш-накопителе и должен запускать его с любого компьютера; при этом не отключая необходимость в пароле.
user1467855

3
@ user1467855, я думаю, тебе нужно лучше объяснить свои требования. Никто не предполагает, что у вас небезопасная сеть. В подходе с открытым ключом пользователи все еще могут войти в систему с паролем. Но вы должны скопировать закрытый ключ на ваш флэш-накопитель, что означает, что флэш-накопитель будет единственным, что может войти в систему без пароля.
Аарон МакДейд

5
К сожалению, я нахожусь в OP-ситуации, потому что системный администратор запрещает аутентификацию с помощью ключей rsa / dsa и требует наличия паролей. Что ты собираешься делать.
Карел Билек

27
Понижено, потому что это даже не пытается ответить на фактически заданный вопрос.
Парфянский выстрел

2
Это все еще требует первого входа в систему и не может быть использовано в сценарии!
Мердад Мирреза

29

Вы могли бы использовать сценарий ожидает. Я не писал ни разу довольно давно, но это должно выглядеть так, как показано ниже. Вам нужно будет руководить сценарием с#!/usr/bin/expect

#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact

Я сделал, как вы предложили, но получил следующие ошибки:/bin/myssh.sh: 2: spawn: not found /bin/myssh.sh: 3: expect: not found /bin/myssh.sh: 4: send: not found /bin/myssh.sh: 5: expect: not found /bin/myssh.sh: 6: send: not found
user1467855

Спасибо Аарон за изменение моего ответа, чтобы быть правильным. Возможно, вам придется выполнить приведенную ниже команду, чтобы найти правильный путь для ожидаемого. which expect
Липонго

1
Вы также можете использовать эту линию #!/usr/bin/env expect
Шебанга

1
Я добавил interactв конец, чтобы ssh-сессия была на самом деле интерактивной
Карел Билек,

-1 из-за огромной угрозы безопасности, связанной с сохранением простого текстового пароля в скрипте.
Аарон Дигулла

21

Вариант I

sshpass -p PASSWORD ssh USER@SERVER

Вариант II

#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact

-pФлаг для указания номера порта.
Kookerus

4
Нет, sshpass - это не ssh. SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
RemiZOffAlex

Чтобы запустить sshpass в Linux CentOS, необходимо, yum -y install epel-releaseа затемyum -y install sshpass
Junior Mayhé

В этом контексте эти данные могут быть проигнорированы
RemiZOffAlex

Хотя я знаю, что это старый пост, стоит отметить, что метод Variant II оставит пароль, заданный для сеанса, уязвимым в истории Bash, что сделает его крайне нежелательным.
Киркланд

11

sshpass + autossh

Одним из приятных бонусов уже упоминавшегося sshpassявляется то, что вы можете использовать его autossh, устраняя еще больше интерактивной неэффективности.

sshpass -p mypassword autossh -M0 -t myusername@myserver.mydomain.com

Это позволит выполнить автоматическое повторное подключение, если, например, ваш Wi-Fi прерывается при закрытии ноутбука.


2
Обратите внимание, что вы не можете добавить опцию -fautossh в этой комбинации, потому что when used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txt также superuser.com/questions/1278583/…
allenyllee

9

sshpass с лучшей безопасностью

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

(И если до боли не ясно: если сервер находится в этом состоянии, слишком поздно настроить регистрацию с открытым ключом.)

sshpassдля спасения. Тем не менее, есть лучшие способы обойти это, чем sshpass -p.

Моя реализация пропускает непосредственно к интерактивной подсказке пароля (не теряя времени на просмотр возможности обмена открытым ключом) и никогда не раскрывает пароль в виде простого текста.

#!/bin/sh
# preempt-ssh.sh
# usage: same arguments that you'd pass to ssh normally
echo "You're going to run (with our additions) ssh $@"

# Read password interactively and save it to the environment
read -s -p "Password to use: " SSHPASS 
export SSHPASS

# have sshpass load the password from the environment, and skip public key auth
# all other args come directly from the input
sshpass -e ssh -o PreferredAuthentications=keyboard-interactive -o PubkeyAuthentication=no "$@"

# clear the exported variable containing the password
unset SSHPASS

1
Примечание для себя: обновите скрипт, чтобы trapпредотвратить утечку SSHPASSпеременной ctrl-C
Ян

1
Я обнаружил, что PreferredAuthentications=keyboard-interactiveэто не сработало, но заменить его на PreferredAuthentications=passwordработало.
Майк Партридж

8

Так я захожу на свои серверы.

ssp <server_ip>
  • псевдоним ssp = '/ home / myuser / Documents / ssh_script.sh'
  • cat /home/myuser/Documents/ssh_script.sh

#! / Bin / Баш

sshpass -p mypassword ssh root @ $ 1

И поэтому...

ssp server_ip

5
# create a file that echo's out your password .. you may need to get crazy with escape chars or for extra credit put ASCII in your password...
echo "echo YerPasswordhere" > /tmp/1
chmod 777 /tmp/1

# sets some vars for ssh to play nice with something to do with GUI but here we are using it to pass creds.
export SSH_ASKPASS="/tmp/1"
export DISPLAY=YOURDOINGITWRONG
setsid ssh root@owned.com -p 22

ссылка: https://www.linkedin.com/pulse/youre-doing-wrong-ssh-plain-text-credentials-robert-mccurdy?trk=mp-reader-card


3
Я думаю, что эта статья просто саркастична!
Ян Фото

5

Я не думаю, что видел, чтобы кто-то предложил это, и ОП просто сказал "сценарий", так что ...

Мне нужно было решить ту же проблему, и мой самый удобный язык - это Python.

Я использовал библиотеку paramiko. Кроме того, мне также нужно было выдавать команды, для которых мне понадобятся расширенные разрешения sudo. Оказывается, sudo может принять свой пароль через стандартный ввод через флаг "-S"! Увидеть ниже:

import paramiko

ssh_client = paramiko.SSHClient()

# To avoid an "unknown hosts" error. Solve this differently if you must...
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# This mechanism uses a private key.
pkey = paramiko.RSAKey.from_private_key_file(PKEY_PATH)

# This mechanism uses a password.
# Get it from cli args or a file or hard code it, whatever works best for you
password = "password"

ssh_client.connect(hostname="my.host.name.com",
                       username="username",
                       # Uncomment one of the following...
                       # password=password
                       # pkey=pkey
                       )

# do something restricted
# If you don't need escalated permissions, omit everything before "mkdir"
command = "echo {} | sudo -S mkdir /var/log/test_dir 2>/dev/null".format(password)

# In order to inspect the exit code
# you need go under paramiko's hood a bit
# rather than just using "ssh_client.exec_command()"
chan = ssh_client.get_transport().open_session()
chan.exec_command(command)

exit_status = chan.recv_exit_status()

if exit_status != 0:
    stderr = chan.recv_stderr(5000)

# Note that sudo's "-S" flag will send the password prompt to stderr
# so you will see that string here too, as well as the actual error.
# It was because of this behavior that we needed access to the exit code
# to assert success.

    logger.error("Uh oh")
    logger.error(stderr)
else:
    logger.info("Successful!")

Надеюсь, это кому-нибудь поможет. Моим примером использования было создание каталогов, отправка и распаковка файлов и запуск программ на ~ 300 серверах одновременно. Таким образом, автоматизация была первостепенной. Я попробовал sshpass, expectа потом придумал это.


2

Я получил это работает следующим образом

.ssh / config был изменен, чтобы исключить приглашение да / нет - я нахожусь за брандмауэром, поэтому я не беспокоюсь о подделанных ключах ssh

host *
     StrictHostKeyChecking no

Создайте файл ответов для ожидаемого, т.е. answer.expect

set timeout 20
set node [lindex $argv 0]
spawn ssh root@node service hadoop-hdfs-datanode restart

expect  "*?assword {
      send "password\r"   <- your password here.

interact

Создайте свой bash-скрипт и просто ожидайте в файле

#!/bin/bash
i=1
while [$i -lt 129]    # a few nodes here

  expect answer.expect hadoopslave$i

  i=[$i + 1]
  sleep 5

done

Получает 128 катодов данных hadoop, обновленных с помощью новой конфигурации - при условии, что вы используете монтирование NFS для файлов hadoop / conf

Надеюсь, что это кому-то поможет - я Windows Numpty, и это заняло у меня около 5 часов, чтобы выяснить!


«Я нахожусь за брандмауэром, поэтому меня не беспокоит подделка ключей SSH». Брандмауэр в этом случае ничего не делает. HostKeyCheck позволяет проверить, что хост на другом конце не является троянским хостом. Т.е. тот, кто просто притворяется, что находится там, где вы хотите подключиться. Если вы подключаетесь к неизвестному хосту и делаете что-то деликатное, например, пишете файл с учетными данными или токеном или вводите пароль, эта информация теперь фактически становится общедоступной. Вы находитесь за брандмауэром не имеет значения.
JCGB





0

В приведенном ниже примере я напишу решение, которое я использовал:

Сценарий: я хочу скопировать файл с сервера, используя скрипт sh:

#!/usr/bin/expect
$PASSWORD=password
my_script=$(expect -c "spawn scp userName@server-name:path/file.txt /home/Amine/Bureau/trash/test/
expect \"password:\"
send \"$PASSWORD\r\"
expect \"#\"
send \"exit \r\"
")

echo "$my_script"

-2

Используйте этот скрипт, чтобы включить его в скрипт. Первый аргумент - это имя хоста, а второй - пароль.

#!/usr/bin/expect
set pass [lindex $argv 1]
set host [lindex $argv 0]
spawn ssh -t root@$host echo Hello
expect "*assword: " 
send "$pass\n";
interact"

Что это показывает поверх существующих ответов? В частности, от damn_c, Lipongo или RemiZOffAlex и других ...
Мартин Прикрыл,

Выполнение скрипта вместе с ssh #! / usr / bin / Ожидайте set pass [lindex $ argv 1] set host [lindex $ argv 0] spawn ssh -t root @ $ host sh /tmp/anyscript.sh Ожидайте «* assword:» отправить "$ pass \ n"; взаимодействовать "
Шивам Мехротра

-3

Чтобы подключить удаленный компьютер через сценарии оболочки, используйте следующую команду:

sshpass -p PASSWORD ssh -o StrictHostKeyChecking=no USERNAME@IPADDRESS

где IPADDRESS, USERNAMEи PASSWORDявляются входными значениями, которые необходимо предоставить в сценарии, или, если мы хотим предоставить во время выполнения, используйте команду «read».


5
Что этот ответ показывает поверх существующих ответов? + Никогда не предлагайте кому-либо использовать StrictHostKeyChecking=noбез объяснения последствий.
Мартин Прикрыл

-5
sudo ssh username@server_ip_address -p port_number

нажмите клавишу ввода и затем введите пароль вашей системы и, наконец, введите пароль вашего сервера

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.