Как я могу настроить обратное SSH-соединение с подключенным компьютером?

20

Я собираюсь развернуть несколько машин в ближайшем будущем, которые будут позади маршрутизаторов. Невозможно настроить динамический DNS на каждом маршрутизаторе и перенаправлении портов, поэтому есть способ, которым я могу настроить эти машины для инициирования соединения TCP с моим компьютером, а затем заставить мой компьютер инициировать соединение SSH с удаленным компьютером через это соединение?

IE:

COMPUTER A OPENS TCP CONNECTION TO COMPUTER B
COMPUTER B OPENS SSH CONNECTION OVER THE EXISTING TCP CONNECTION TO COMPUTER A
COMPUTER B NOW HAS SSH CONNECTION TO COMPUTER A

Возможно ли это, и если да, то как я могу это сделать?

Нафтули Кей
источник
2
Связанный (как и почему это работает): Как работает обратное туннелирование SSH?
Жиль "ТАК - перестать быть злым"

Ответы:

21

В комплект /etc/ssh/sshdдля компьютера Б :

AllowTcpForwarding yes
TCPKeepAlive yes

С компьютера А :

$ ssh -R 2222:localhost:22 ip.of.computer.b

С компьютера Б :

$ ssh localhost -p 2222

Обратите внимание, что 2222 - это произвольный номер порта, который я выбрал. Этот порт на компьютере B будет затем туннелирован обратно через соединение SSH, инициализированное на компьютере A с портом 22. Если у вас есть несколько машин, вы должны использовать разные порты для каждой машины.

Для вашего случая использования вы, вероятно, захотите запустить его из скрипта, чтобы вы могли сделать его демоном и периодически пытаться повторно подключиться, если ссылка была удалена. Вы, вероятно, захотите специальную учетную запись с оболочкой только /bin/trueна компьютере B для обработки входящих соединений. Затем вы можете настроить либо одну клавишу, либо несколько клавиш для каждой машины, которой разрешено «звонить домой».

На компьютере А вы могли бы найти -n, -Nи -Tопции полезных отключить его от локального ввода (так что он может работать в фоновом режиме), а не пытаться выполнить любую удаленную команду, просто открыть туннель, а не создавать терминал.

Большинство обычных методов порождения демона не очень хорошо работают с настройкой сетевого туннеля, подобного этому. Проблема с сетевым подключением заставила бы его попытаться сломать стену, чтобы пройти. Простая петля с ожиданием сна должна помочь. Десять минут - это хорошее число, потому что оно не затопляет сеть и не регистрирует файлы с попытками, если есть проблема (например, компьютер B находится в автономном режиме), но все равно возвращает вас достаточно быстро, если соединение разорвано.

#/bin/sh
while true; do
    sleep $((60*10))
    ssh -nNT -R 2222:localhost:22 ip.of.computer.b
done

Такой скрипт можно запустить при загрузке /etc/rc.local. Ваше первое изменение для входа в систему начнется примерно через десять минут после загрузки компьютера А.

Калеб
источник
1
Ницца. Таким образом, я хотел бы, чтобы каждая удаленная машина туннелировала локальный порт SSH к порту на локальной машине? Возможно, было бы целесообразно, чтобы каждая машина только туннелировала соединение по требованию. Я мог бы позволить каждой машине открывать поддерживающее соединение HTTP и выдавать данные XML, когда я хотел бы попытаться установить обратное соединение, чтобы упростить управление (и не забивать все мои порты;]). Благодарность!
Нафтули Кей
@TKKocheran: Есть довольно много портов на выбор ... особенно больше, чем у вас будут киоски. Как поддерживать открытый туннель SSH хуже, чем поддерживать открытое http-соединение?
Калеб
Я предполагаю, что вы правы, я мог бы просто сделать это, но тогда мне нужно было бы сопоставить порты с машинами и вспомнить, какой из них какой, а другой маршрут лениво создавался бы, то есть создавал туннель SSH только по запросу.
Нафтули Кей
1
@TKKocheran: Вы должны были бы сделать отображение в любом случае, иначе даже ваше ленивое создание могло бы столкнуться с ситуациями, когда они пытались забить друг друга.
Калеб
1
Я не знаю, применимо ли это вообще, но мой /etc/ssh/sshd_config
конфиг