Автоматично вводити пароль 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
  • Арка: 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.
Пер Mejdal Rasmussen

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
Ця відповідь повинна отримати більше голосів, і це чудова обгортка. Просто спробував кілька поширених операцій, таких як rsyncing з різними прапорами та віддалене виконання команд, і це працювало кожен раз. Додано до моєї панелі інструментів корисних сценаріїв, дякую @damn_c!
користувач2082382

7
Можливо, він не отримав більше відгуків, тому що люди цього не очікували?
clearlight

7
Причина, чому це ІМО, не дуже хороша відповідь - це те, що пароль записаний у сценарії, що є найменш безпечним методом ...
PierreE

8
Пароль буде видимий кожен, хто працює з PS на машині.
Даніель Перссон

22
"assword" дивовижно :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

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 з паролем. Це тому, що "Я" може мати сценарій на великому диску, і його потрібно запустити з будь-якого комп'ютера; при цьому не відключаючи необхідність пароля.
користувач1467855

3
@ user1467855, я думаю, вам потрібно краще пояснити свої вимоги. Ніхто не припускає, що у вас є незахищена мережа. За підходу з відкритим ключем користувачі все одно могли б увійти за допомогою пароля. Але ви скопіювали приватний ключ на свій накопичувач, а це означає, що привід великого пальця - це єдине, що може ввійти без пароля.
Аарон Мак-Дейд

5
На жаль, я опинився в ситуації з ОП, тому що sysadmin забороняє аутентифікацію за допомогою клавіш 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
Ви також можете скористатися цією лінією shebang:#!/usr/bin/env expect
glenn jackman

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 дозволить залишити пароль сеансу вразливим в історії баш, зробивши його вкрай недоцільним.
Кіркленд

11

sshpass + autossh

Один із приємних бонусів уже згаданого sshpass- це те, що ви можете ним користуватися autossh, усуваючи ще більше інтерактивної неефективності.

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

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


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

(І якщо це не болісно зрозуміло: із сервером у такому стані налаштовувати вхід із відкритим ключем ще занадто пізно.)

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
Ian

1
Я виявив, що PreferredAuthentications=keyboard-interactiveце не працює, але замінивши його на PreferredAuthentications=passwordвідпрацьоване.
Майк Партрідж

8

Ось так я входжу на свої сервери.

ssp <server_ip>
  • alias ssp = '/ home / myuser / Documents / ssh_script.sh'
  • cat /home/myuser/Documents/ssh_script.sh

#! / бін / баш

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.

Я користувався бібліотекою параміко. Крім того, мені також потрібно було видавати команди, для яких мені потрібні ескалаційні дозволи sudo. Виявляється, sudo може прийняти свій пароль через stdin через прапор "-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, і на це знадобилося близько 5 годин!


"Я за брандмауером, тому не переживаю за підроблені ключі ssh". Брандмауер в цьому випадку абсолютно нічого не робить. HostKeyCheck - це ви можете переконати, що хост не є троянським хостом. Тобто той, який просто видає себе там, де ви хочете підключитися. Якщо ви підключитесь до невідомого хоста і зробите щось чутливе, як-от написати файл, який містить облікові дані або маркер, або введіть пароль, ця інформація зараз фактично є загальнодоступною інформацією. Ви знаходитесь за брандмауером - це не має значення.
JCGB

2

Якщо ви робите це в системі Windows, ви можете використовувати Plink (частина PuTTY).

plink your_username@yourhost -pw your_password




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 / очікувати встановити пропуск [lindex $ argv 1] встановити хост [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вхідні значення , які необхідно надати в сценарії, або , якщо ми хочемо , щоб забезпечити у використанні під час виконання «читати» команду.


5
Що ця відповідь показує поверх існуючих відповідей? + Ніколи ніколи не пропоную комусь користуватися, StrictHostKeyChecking=noне пояснюючи наслідків.
Мартін Прикрил

-5
sudo ssh username@server_ip_address -p port_number

натисніть клавішу enter, а потім введіть пароль вашої системи, а потім нарешті введіть пароль вашого сервера

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.