У меня есть удаленный компьютер Raspberry Pi, который подключается из-за ограничительного брандмауэра к моему серверу через обратный туннель SSH. Представьте, что этот Raspberry Pi находится на труднодоступной крыше здания в другой стране (возможно, во время шторма), поэтому я хочу, чтобы его подключение было надежным.

Чтобы подключиться к серверу, Raspberry Pi запускает такой процесс:

while true; do
    ssh -R 19999:localhost:22 www.sern.pro
    sleep 30
done

Часть 19999:localhost:22 основном означает, что весь трафик через порт 19999 на сервере должен быть перенаправлен на порт 22 Raspberry Pi. Итак, я могу подключиться к Raspberry Pi, используя SSHing к серверу, а затем выполнив команду, подобную следующей:

ssh localhost -p 19999

Обычно это работает просто отлично, и на сервере такая команда, как netstat --all --timers --program --numeric | egrep '127.0.0.1:*(LISTEN|.*)' | sort перечисляет обратное соединение SSH примерно так:

tcp        0      0 127.0.0.1:19999         0.0.0.0:*               LISTEN      2972/5           off (0.00/0/0)

Однако иногда я обнаруживал, что этот список на сервере исчезает, а Raspberry Pi поддерживает SSH-соединение с сервером. То есть команда ssh localhost -p 19999 сообщение об ошибке, подобное следующему:

ssh: connect to host localhost port 19999: Connection refused

Тем не менее, соединение Raspberry Pi SSH остается идеальным, способным выполнять команды на сервере. Я не знаю правильных слов, чтобы описать, что происходит не так, когда это происходит.

Итак ... если не считать бронирование рейса и восхождение на крышу здания, как я могу снова подобрать это активное соединение SSH как правильный обратный туннель SSH? Как я могу снова получить доступ к локальному порту?

2 ответа2

1

Более десяти лет назад для таких целей была написана утилита autossh .

Вы можете использовать следующий скрипт подключения

#!/bin/sh
export AUTOSSH_GATETIME=0 

autossh -M 0
-o "PubkeyAuthentication=yes" \
-o "StrictHostKeyChecking=false" \
-o "PasswordAuthentication=no" \
-o "ExitOnForwardFailure=yes" \
-o "ServerAliveInterval 60" \
-o "ServerAliveCountMax 3" \
-fNR 19999:localhost:22 www.sern.pro

Конечно, вам нужно установить аутентификацию на основе ключей перед запуском этого скрипта.

0

Проблема, с которой вы сталкиваетесь, означает, что соединение недоступно. Если в конце команды вы увидите список всех соединений, вы, возможно, увидите, что соединение для этого порта больше не находится в режиме LISTEN и теперь время ожидания или ЗАКРЫТЬ-ПОДОЖДИТЕ, это означает, что соединения все еще «живы», но только как запущенный процесс в малине.

Чтобы это работало, вы можете создать скрипт, который проверяет наличие обратного соединения, если не настроил его.

Чтобы решить эту проблему, вы можете добавить код в скрипт, чтобы проверить, есть ли на модуле идентификатор процесса ssh, и если у вас есть файл маркера, вы убьете этот процесс, чтобы снова запустить туннель.

Например, у вас есть пустой файл с именем RESTARTSSH, в своем скрипте вы можете проверить, существует ли этот файл, если да, то найдите идентификатор процесса ssh и уничтожьте его, а затем перезапустите туннель.

Для проверки идентификатора процесса вы можете использовать:

ps -ef | grep ServerAliveInterval | grep -v grep | awk '{print $2}'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .