Як створити скрипт bash для перевірки з'єднання SSH?


86

Я в процесі створення скрипту bash, який входив би у віддалені машини та створював приватні та відкриті ключі.

Моя проблема полягає в тому, що віддалені машини не дуже надійні, і вони не завжди працюють. Мені потрібен скрипт bash, який перевіряв би, чи встановлено з'єднання SSH. Перш ніж створювати ключі для подальшого використання.


2
Як правило, один запускається ssh-keygenдля створення пари ключів на локальній машині, а потім ssh-copy-idдля копіювання відкритого ключа на віддалені машини. Здається, ви робите речі інакше. Чому, яка ваша мета?
ефемієнт

1
Оскільки ви, очевидно, змінюєте спосіб встановлення з'єднань на віддалених машинах, подумайте про розгортання mosh . mosh.mit.edu Призначений для доповнення SSH при нестабільних з'єднаннях. У мене з цим дуже хороший досвід.
Aeyoun

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

Відповіді:


170

Ви можете перевірити це за допомогою поверненого значення ssh, яке дає вам:

$ ssh -q user@downhost exit
$ echo $?
255

$ ssh -q user@uphost exit
$ echo $?
0

РЕДАГУВАТИ: Іншим підходом було б використання nmap (вам не потрібно мати ключі або матеріали для входу):

$ a=`nmap uphost -PN -p ssh | grep open`
$ b=`nmap downhost -PN -p ssh | grep open`

$ echo $a
22/tcp open ssh
$ echo $b
(empty string)

Але вам доведеться grep повідомлення (nmap не використовує return-value, щоб показати, чи порт був відфільтрований, закритий чи відкритий).

EDIT2:

Якщо ви зацікавлені в фактичний стан SSH-порт, ви можете замінити grep openз egrep 'open|closed|filtered':

$ nmap host -PN -p ssh | egrep 'open|closed|filtered'

Просто щоб бути повним.


Щоб бути повним, чи можете ви вказати, який код повернення означає успіх, а який - відмова SSH?
Henley Chiu

Цікаво, а якщо спроба SSH просто зависне там?
Sibbs Gambling

2
Чудова відповідь! Тим не менш, ви не згадуєте, що спроба зайти sshна вихідний хост зазнає невдачі лише через тайм-аут, наприклад, 60 секунд - що може бути непосильним для деяких звичок. Крім того, якщо ім'я хосту, якщо воно визначено в ~/.ssh/config, перший sshпідхід працює, тоді як другий nmapспосіб не працює Failed to resolve "<hostname>".
ssc

1
взагалі немає пояснень щодо команд ... або того, що ви насправді робите .. що це $?? і т. д.
Тоскан

Ще більш лаконічна форма №1: ssh -q user@downhost exit | echo $? перевести результат з'єднання в ехо
передайте philn5d

22
ssh -q -o "BatchMode=yes" -i /home/sicmapp/.ssh/id_rsa <ID>@<Servername>.<domain> "echo 2>&1" && echo $host SSH_OK || echo $host SSH_NOK

2
Вихід в один рядок: (ssh -q -o "BatchMode = yes" -o "ConnectTimeout = 3" user@host.com "echo 2> & 1" && echo SSH_OK || echo SSH_NOK) | tail -n1
Xdg

21

Ви можете використовувати щось подібне

$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)

Це виведе "ok", якщо з'єднання ssh буде нормальним


14

Доповнивши відповідь @Adrià Cidreви можете:

status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)

if [[ $status == ok ]] ; then
  echo auth ok, do something
elif [[ $status == "Permission denied"* ]] ; then
  echo no_auth
else
  echo other_error
fi

7

Спробуйте:

echo quit | telnet IP 22 2>/dev/null | grep Connected

1
Проблема цього підходу полягає в тому, що він не розпізнає хости, визначені в ssh_config (тобто / etc / ssh / config або ~ / .ssh / config)
Ding-Yi Chen

1

sshКоманда нижче повинна мати код виходу при 0успішному підключенні та ненульове значення в іншому випадку.

ssh -q -o BatchMode=yes user@remote.com exit

if [ $? != "0" ]; then
    echo "Connection failed"
fi

Чудово! Я також рекомендую додати -o ConnectTimeout = 5 для швидшого виходу у випадках, коли порт призначення отримує фільтр.
Даніель

0

Про всяк випадок, якщо хтось хоче лише перевірити, чи відкритий порт 22 на віддаленій машині, ця проста команда netcat корисна. Я використовував його, оскільки nmap та telnet для мене були недоступні. Більше того, моя конфігурація ssh використовує автентифікацію пароля клавіатури.

Це варіант рішення, запропонований GUESSWHOz.

nc -q 0 -w 1 "${remote_ip}" 22 < /dev/null &> /dev/null && echo "Port is reachable" || echo "Port is unreachable"

0

Якщо ви хочете перевірити, чи існує віддалена папка, або будь-який інший файл-тест:

if [ -n "$(ssh "${user}@${server}" [ -d "$folder" ] && echo 1; exit)" ]; then
    # exists
else
    # doesn't exist
fi

Не забувайте про цитати в "$(ssh ...)".


Це не відповідає на питання. OP хоче перевірити, чи можна встановити з'єднання SSH, не перевіряючи файл у віддаленому розташуванні ssh.
Ракіб Фіха

0

Для підключення до сервера з декількома інтерфейсами

ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.61;[ $? = 1 ] || ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.51

0

Приклад використання сценарію BASH 4+:

# -- ip/host and res which is result of nmap (note must have nmap installed)
ip="192.168.0.1"
res=$(nmap ${ip} -PN -p ssh | grep open)

# -- if result contains open, we can reach ssh else assume failure) --
if [[ "${res}" =~ "open" ]] ;then
    echo "It's Open! Let's SSH to it.."
else
    echo "The host ${ip} is not accessible!"
fi

0

https://onpyth.blogspot.com/2019/08/check-ping-connectivity-to-multiple-host.html

Вище посилання - створити скрипт Python для перевірки підключення. Ви можете використовувати подібний метод і використовувати:

ping -w 1 -c 1 "IP Address" 

Команда для створення сценарію bash.


2
Це пінгує лише віддалений IP. Не гарантує, якщо можливе з'єднання ssh.
RJ

Дякуємо, що вказали , ось код для ssh xlinu.blogspot.com/2019/09/… export user = "username" export pass = "password" export i = "hostname" export SSHPASS = $ pass sshpass -e ssh $ користувач @ $ i -q "echo $ i є доступним"
Dheeraj Kumar

-7

Мені здається, ти тут намагаєшся вирішити неправильну проблему. Чи не варто намагатися зробити демони ssh більш стабільними? Спробуйте запустити щось на зразок monit , який перевірить, чи запущений демон, і перезапустить його, якщо ні (даючи вам час знайти кореневу проблему, що виникла sshd). Або послуга мережі клопітна? Спробуйте подивитисяman ifup . Чи ціла проклята річ просто хоче закрити вас? Ну, це ще більша проблема ... спробуйте переглянути ваші журнали (починайте з syslog), щоб знайти збої обладнання або служби, які вимикають ваш бокс (можливо, монітор температури?).

Робити ваші сценарії стійкими до несправностей - це чудово, але ви можете також захотіти зробити свій Boxen стійким до несправностей.


3
Сем: існують допустимі випадки використання сценарію, який перевіряє це. Наприклад (як і я): у мене на машині запущена робота cron для резервного копіювання даних через rsync до мого домашнього NAS. Зараз я перебуваю на вулиці або навіть досить часто відключаюся, і мені потрібно перенести час, якщо з’єднання було недоступне. Мій бокс працює досить добре, але як говориться: це завжди кабель (він же мережевий)
stwissel
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.