Jak skonfigurować odwrotne połączenie SSH z podłączanym komputerem?

20

W najbliższej przyszłości zamierzam wdrożyć wiele maszyn, które będą za routerami. Konfigurowanie dynamicznego DNS na każdym routerze i przekierowaniu portów nie będzie możliwe, więc istnieje sposób, w jaki mogę skonfigurować te maszyny, aby zainicjowały połączenie TCP z moim komputerem, a następnie kazały komputerowi zainicjować połączenie SSH z komputerem zdalnym przez to połączenie?

TO ZNACZY:

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

Czy to możliwe, a jeśli tak, to jak mogę to zrobić?

Naftuli Kay
źródło
2
Powiązane (jak i dlaczego to działa): Jak działa tunelowanie zwrotne SSH?
Gilles 'SO - przestań być zły'

Odpowiedzi:

21

W /etc/ssh/sshdna komputerze B zestawie:

AllowTcpForwarding yes
TCPKeepAlive yes

Z komputera A :

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

Z komputera B :

$ ssh localhost -p 2222

Zauważ, że 2222 to arbitralny numer wysokiego portu, który wybrałem. Ten port na komputerze B zostanie następnie tunelowany z powrotem przez połączenie SSH zainicjowane na komputerze A do portu 22. Jeśli masz wiele komputerów, powinieneś użyć innego portu dla każdego komputera.

W twoim przypadku prawdopodobnie będziesz chciał uruchomić to ze skryptu, aby uczynić go demonem i okresowo próbować łączyć się ponownie, jeśli połączenie zostanie zerwane. Prawdopodobnie będziesz potrzebować specjalnego konta z powłoką tylko /bin/truena komputerze B do obsługi połączeń przychodzących. Następnie możesz skonfigurować jeden klucz lub wiele kluczy dla każdego urządzenia, które mogą „zadzwonić do domu”.

Na komputerze A można znaleźć -n, -Na -Topcje użyteczne odłączyć go od wejścia lokalnego (więc może działać w tle), nie próbować uruchomić żadnego polecenia zdalnego, wystarczy otworzyć tunel, a nie tworzyć tty.

Większość normalnych metod odradzania demona nie działa zbyt dobrze przy konfigurowaniu tunelu sieciowego w ten sposób. Problem z łącznością sieciową spowodowałby, że próbowała zburzyć mur, aby się przedostać. Prosta pętla ze snem do oczekiwania powinna załatwić sprawę. Dziesięć minut to niezła liczba, ponieważ nie powoduje zalania sieci i plików dziennika z próbami, jeśli występuje problem (na przykład, gdy komputer B jest w trybie offline), ale mimo to połączenie jest dość szybkie.

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

Taki skrypt można uruchomić podczas rozruchu /etc/rc.local. Twoja pierwsza zmiana zalogować się do urządzenia rozpocznie około dziesięciu minut po komputerze z butami.

Caleb
źródło
1
Ładny. Więc w zasadzie chciałbym, aby każda zdalna maszyna tunelowała lokalny port SSH do portu na maszynie lokalnej? Rozsądnie byłoby, gdyby każda maszyna tunelowała połączenie tylko na żądanie. Mogę być w stanie kazać każdemu komputerowi otworzyć utrzymywane połączenie HTTP i wypychać dane XML, kiedy chcę, aby spróbowało nawiązać połączenie odwrotne, aby ułatwić zarządzanie (i nie blokować wszystkich moich portów;]). Dzięki!
Naftuli Kay
@TKKocheran: Istnieje wiele portów do wyboru ... konkretnie więcej niż będziesz miał kioski. W jaki sposób utrzymywanie tunelu SSH otwartego jest gorsze niż utrzymywanie połączenia HTTP otwartego?
Caleb
Myślę, że masz rację, mógłbym to zrobić, ale musiałbym mapować porty na maszyny i pamiętać, który jest który, podczas gdy druga trasa byłaby leniwie utworzona, tj. Utworzyłby tunel SSH tylko na żądanie.
Naftuli Kay
1
@TKKocheran: Musiałbyś wykonać mapowanie w obu kierunkach, w przeciwnym razie nawet twoja leniwa instancja wpadłaby na sytuacje, w których próbowali się nawzajem zatkać.
Caleb
1
Nie wiem, czy ma to ogólne zastosowanie, ale moja konfiguracja sshd jest teraz włączona/etc/ssh/sshd_config
gc5