ssh: проверить, жив ли туннель

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

echo "Please open an ssh tunnel using 'ssh -L 6000:localhost:5432 example.com'"

Я хотел бы проверить, открыл ли пользователь этот туннель, и выйти с сообщением об ошибке, если туннеля не существует. Есть ли способ запросить туннель ssh, т.е. проверить, действительно ли локальный порт 6000 туннелирован на этот сервер?


person Adam Matan    schedule 04.01.2010    source источник
comment
это может частично помочь lsof -i | grep ssh   -  person qartal    schedule 28.02.2018


Ответы (9)


Это мой тест. Надеюсь, это полезно.

# $COMMAND is the command used to create the reverse ssh tunnel
COMMAND="ssh -p $SSH_PORT -q -N -R $REMOTE_HOST:$REMOTE_HTTP_PORT:localhost:80 $USER_NAME@$REMOTE_HOST"

# Is the tunnel up? Perform two tests:

# 1. Check for relevant process ($COMMAND)
pgrep -f -x "$COMMAND" > /dev/null 2>&1 || $COMMAND

# 2. Test tunnel by looking at "netstat" output on $REMOTE_HOST
ssh -p $SSH_PORT $USER_NAME@$REMOTE_HOST netstat -an | egrep "tcp.*:$REMOTE_HTTP_PORT.*LISTEN" \
   > /dev/null 2>&1
if [ $? -ne 0 ] ; then
   pkill -f -x "$COMMAND"
   $COMMAND
fi
person Tommy    schedule 04.01.2010
comment
Похоже, в приведенном выше коде есть ошибка. если [$? -ne 0 ], 0, вероятно, должен быть 1. удаленный egrep установит $? на 0, если он успешно находит совпадение. В любом случае мне нужно было использовать 1, чтобы эта команда перестала убивать существующий туннель каждый раз, когда я запускал команду. - person milesvp; 11.01.2018

Netcat — ваш друг:

nc -z localhost 6000 || echo "no tunnel open"
person rxw    schedule 22.06.2014
comment
Вау, это чертовски полезно. Я делаю скрипт, который в первую очередь создает туннель ssh, и теперь я использую netcat, чтобы узнать, когда он готов принимать соединения. Работает как шарм. - person Hubro; 23.06.2015

Autossh - лучший вариант - процесс проверки не работает во всех случаях (например, процесс зомби, проблемы, связанные с сетью)

пример:

autossh -M 2323 -c arcfour -f -N -L 8088:localhost:80 host2
person Jeff    schedule 19.10.2010

Это больше похоже на вопрос о сбое сервера, но вы можете использовать netstat.

что-то типа:

 # netstat -lpnt | grep 6000 | grep ssh

Это скажет вам, есть ли процесс ssh, прослушивающий указанный порт. он также сообщит вам PID процесса.

Если вы действительно хотите перепроверить, что процесс ssh был запущен с правильными параметрами, вы можете найти процесс по PID в чем-то вроде

# ps aux | grep PID
person Igor Serebryany    schedule 04.01.2010
comment
Обратите внимание, что это решение не работает в OS X, потому что netstat в OS X отличается. - person hlin117; 12.02.2016

Используйте autossh. Это инструмент, предназначенный для мониторинга ssh-соединения.

person plaes    schedule 17.08.2010

Мы можем проверить с помощью команды ps

# ps -aux | grep ssh

Покажет все запущенные службы shh, и мы сможем найти службу туннеля в списке.

person Javeed Shakeel    schedule 16.01.2018

stunnel — хороший инструмент для создания полупостоянных соединений между хостами.

http://www.stunnel.org/

person Antti Rytsölä    schedule 22.09.2012

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

Начнем с самого начала. Предположим, что есть машина, которая будет называться local с IP-адресом 10.0.0.1, а другая, называемая remote, с IP-адресом 10.0.3.12. Я добавлю эти имена хостов к приведенным ниже командам, чтобы было очевидно, где они выполняются.

Цель состоит в том, чтобы создать туннель, который будет перенаправлять TCP-трафик с адреса обратной связи на удаленной машине через порт 123 на локальную машину через порт 456. Это можно сделать с помощью следующей команды на локальной машине:

local:~# ssh -N -R 123:127.0.0.1:456 10.0.3.12

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

local:~# ps aux | grep ssh

Если вы видите команду в выводе, мы можем продолжить. В противном случае убедитесь, что ключ SSH установлен на удаленном компьютере. Обратите внимание, что исключение имени пользователя перед удаленным IP-адресом заставляет ssh использовать текущее имя пользователя.

Далее мы хотим проверить, открыт ли туннель на удаленном компьютере:

remote:~# netstat | grep 10.0.0.1

Мы должны получить вывод, подобный этому:

tcp  0  0  10.0.3.12:ssh  10.0.0.1:45988  ESTABLISHED

Было бы неплохо на самом деле увидеть, что некоторые данные передаются от удаленного компьютера к хосту. Здесь на помощь приходит netcat. В CentOS его можно установить вместе с yum install nc.

Сначала откройте прослушивающий порт на локальной машине:

local:~# nc -l 127.0.0.1:456

Затем выполните подключение на удаленном компьютере:

remote:~# nc 127.0.0.1 123

Если вы откроете второй терминал на локальном компьютере, вы увидите соединение. Что-то вроде этого:

local:~# netstat | grep 456
tcp  0  0 localhost.localdom:456 localhost.localdo:33826 ESTABLISHED
tcp  0  0 localhost.localdo:33826 localhost.localdom:456 ESTABLISHED

А еще лучше, наберите что-нибудь на пульте:

remote:~# nc 127.0.0.1 8888
Hallo?
anyone there?

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

local:~# nc -l 127.0.0.1:456
Hallo?
anyone there?

Туннель работает! Но что, если у вас есть приложение с именем appname, которое должно прослушивать порт 456 на локальном компьютере? Завершите nc с обеих сторон, затем запустите приложение. Вы можете проверить, что он прослушивает правильный порт с помощью это:

local:~# netstat -tulpn | grep LISTEN | grep appname
tcp  0  0  127.0.0.1:456  0.0.0.0:* LISTEN  2964/appname

Кстати, запуск той же команды на удаленном компьютере должен показать, что sshd прослушивает порт 127.0.0.1:123.

person Nagev    schedule 03.11.2017

Если вы используете ssh в фоновом режиме, используйте это:

sudo lsof -i -n | egrep '\<ssh\>'
person Alex Montoya    schedule 14.03.2019