Автоматическое подключение по ssh из скрипта
При первом подключении к серверу, нужно ответить «yes», что означает — мы доверяем этому серверу. Кроме того, при изменении ключа сервера, надо удалить старый ключ из файла known_hosts
. Если аутентификация по ключу в силу каких-то причин невозможна, нужно как-то передать пароль ssh-клиенту. При подключении к серверу из shell-скрипта, нам нужно решить эти три задачи.
Первая задача
Для предотвращения атак «человек посередине» при подключении к серверу, ключ которого ещё не известен ssh-клиенту, будет показан «слепок ключа» (key fingerprint). Нам нужно сравнить этот слепок со слепком ключа сервера, который мы получили по надежному каналу связи. И только после этого ответить «yes» — мы доверяем этому серверу. Выглядит это примерно так:
$ ssh evgeniy@123.123.123.123 The authenticity of host 'server.com (123.123.123.123)' can't be established. ECDSA key fingerprint is SHA256:l8UgO9Gw44QPlLOGq1wyPQR3vfVdiWWbMwZQhqkq3V8. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '123.123.123.123' (ECDSA) to the list of known hosts. evgeniy@123.123.123.123's password: пароль Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-76-generic x86_64)
При утвердительном ответе yes
, ssh-клиент продолжит подключение, сохранив ключ сервера в файле ~/.ssh/known_hosts
. В противном случае подключение к серверу будет прервано. Чтобы это обойти, нужно добавить опцию StrictHostKeyChecking
, которая отключает проверку и сразу добавляет ключ сервера в файл ~/.ssh/known_hosts
.
$ ssh -o StrictHostKeyChecking=no evgeniy@123.123.123.123 Warning: Permanently added '123.123.123.123' (ECDSA) to the list of known hosts. evgeniy@123.123.123.123's password: пароль Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-76-generic x86_64)
Вторая задача
При попытке подключения после изменения ключа на удаленном сервере (это происходит при переустановке операционной системы или пакета openssh-server
), появляется сообщение с ошибкой:
$ ssh evgeniy@123.123.123.123 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the ECDSA key sent by the remote host is SHA256:BcWqgw+jx6NFmMcnBSXplEWVG33lCbDRShwY1zT1qk8. Please contact your system administrator. Add correct host key in /home/evgeniy/.ssh/known_hosts to get rid of this message. Offending ECDSA key in /home/evgeniy/.ssh/known_hosts:2 remove with: ssh-keygen -f "/home/evgeniy/.ssh/known_hosts" -R "123.123.123.123" Password authentication is disabled to avoid man-in-the-middle attacks. Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks. evgeniy@123.123.123.123: Permission denied (publickey,password).
known_hosts
хранится в привязке к ip-адресу.
В сообщении можно увидеть, что вторая строка файла ~/.ssh/known_hosts
содержит неправильный ключ. И подсказку, как удалить этот ключ (неправильную строку):
$ ssh-keygen -f "/home/evgeniy/.ssh/known_hosts" -R "123.123.123.123" Host 123.123.123.123 found: line 2 /home/evgeniy/.ssh/known_hosts updated. Original contents retained as /home/evgeniy/.ssh/known_hosts.old
Неправильная строка теперь удалена, а исходный файл на всякий случай сохранён под именем known_hosts.old
. Еще раз пробуем подключиться:
$ ssh -o StrictHostKeyChecking=no evgeniy@123.123.123.123 Warning: Permanently added '123.123.123.123' (ECDSA) to the list of known hosts. evgeniy@123.123.123.123's password: пароль Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-76-generic x86_64)
Но удаление записи в файле known_hosts
требует ручного вмешательства, а нам нужно, чтобы подключение к серверу происходило из скрипта, без нашего участия. И здесь на помощь приходит еще одна опция — UserKnownHostsFile
. Можно вообще не записывать ключ сервера в файл known_hosts
, указав значение этой опции как /dev/null
. Тогда и удалять неправильный ключ будет не нужно:
$ ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null evgeniy@123.123.123.123 Warning: Permanently added '123.123.123.123' (ECDSA) to the list of known hosts. evgeniy@123.123.123.123's password: пароль Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-101-generic x86_64)
Третья задача
Теперь почти все хорошо, осталось еще решить вопрос с паролем. В этом нам поможет утилита sshpass
:
$ sudo apt install sshpass
Вот так можно передать пароль ssh-клиенту, чтобы он мог подключиться к серверу:
$ sshpass -p 'qwerty' ssh -o StrictHostKeyChecking=no \ > -o UserKnownHostsFile=/dev/null evgeniy@123.123.123.123 Warning: Permanently added '123.123.123.123' (ECDSA) to the list of known hosts. Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-101-generic x86_64)
Также, пароль можно записать в файл, только не забыть выставить для него права:
$ sshpass -f /home/evgeniy/server.secret ssh -o StrictHostKeyChecking=no \ > -o UserKnownHostsFile=/dev/null evgeniy@123.123.123.123 Warning: Permanently added '123.123.123.123' (ECDSA) to the list of known hosts. Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-101-generic x86_64)
Опции StrictHostKeyChecking
и UserKnownHostsFile
могут быть заданы постоянно в ~/.ssh/config
(для текущего пользователя) или в /etc/ssh/ssh_config
(для всех пользователей).
$ nano /home/evgeniy/.ssh/config
Host some-server HostName 123.123.123.123 User evgeniy StrictHostKeyChecking no UserKnownHostsFile /dev/null
Теперь подключаться к серверу 123.123.123.123
можно так:
$ sshpass -p 'qwerty' ssh some-server
Но тут надо учитывать, от имени какого пользователя будет запускаться скрипт. Например, если скрипт запускается от root
, то и файл конфигурации должен быть размещен в /root/.ssh/config
. Иначе нужно явно указать, где расположен файл с настройками ssh-клиента:
# sshpass -f /home/evgeniy/some-server.secret ssh -F /home/evgeniy/.ssh/config some-server
Поиск: Bash • CLI • SSH • Ключ • Команда • Сервер • sshpass • Скрипт • Сценарий • shell • Пароль • Клиент • Linux