Jak działa tunelowanie zwrotne SSH?

350

Jak rozumiem, zapory ogniowe (zakładając ustawienia domyślne) odrzucają cały ruch przychodzący, który nie ma wcześniejszego ruchu wychodzącego.

Bazując na odwróceniu połączenia ssh i łatwym tunelowaniu SSH, odwrotnego tunelowania SSH można użyć do ominięcia przykrych ograniczeń zapory.

Chciałbym wykonywać polecenia powłoki na zdalnym komputerze. Zdalna maszyna ma własną zaporę i znajduje się za dodatkową zaporą (routerem). Ma adres IP jak 192.168.1.126 (lub coś podobnego). Nie jestem za zaporą ogniową i znam adres IP zdalnego komputera widziany z Internetu (nie adres 192.168.1.126). Dodatkowo mogę ssh (something)najpierw poprosić kogoś o wykonanie jako root na zdalnym komputerze.

Czy ktoś mógłby mi wyjaśnić, krok po kroku, jak działa tunelowanie zwrotne SSH, aby ominąć zapory ogniowe (zapory lokalne i zdalne komputerów oraz dodatkowa zapora między nimi)?

Jaka jest rola przełączników ( -R, -f, -L, -N)?

Ali
źródło

Odpowiedzi:

402

Uwielbiam wyjaśniać tego rodzaju rzeczy poprzez wizualizację. :-)

Pomyśl o swoich połączeniach SSH jak o lampach. Duże rurki. Zwykle sięgasz przez te rurki, aby uruchomić powłokę na zdalnym komputerze. Powłoka działa w terminalu wirtualnym (tty). Ale znasz już tę część.

Pomyśl o swoim tunelu jak o rurze w rurze. Nadal masz duże połączenie SSH, ale opcja -L lub -R pozwala ustawić w nim mniejszą rurkę.

Każda rura ma początek i koniec. Duża rura, twoje połączenie SSH, zaczęło się od klienta SSH i kończy na serwerze SSH, z którym się połączyłeś. Wszystkie mniejsze rurki mają te same punkty końcowe, z tym wyjątkiem, że rola „początku” lub „końca” zależy od tego, czy je utworzyłeś ( -Llub -R).

(Nie powiedziałeś, ale założę, że „zdalna” maszyna, o której wspomniałeś, ta za zaporą, może uzyskać dostęp do Internetu za pomocą translacji adresów sieciowych (NAT). Jest to trochę ważne, więc popraw to założenie, jeśli jest fałszywe).

Podczas tworzenia tunelu podajesz adres i port, na który będzie on odpowiadał, oraz adres i port, na który zostanie dostarczony. Ta -Lopcja informuje tunel, aby odpowiedział po lokalnej stronie tunelu (host, na którym działa klient). Ta -Ropcja informuje tunel, aby odpowiedział po stronie zdalnej (serwer SSH).

kierunki tunelu ssh

Więc ... Aby móc połączyć się z Internetem przez SSH na maszynie za zaporą ogniową, potrzebujesz tego komputera, aby otworzyć połączenie SSH ze światem zewnętrznym i dołączyć -Rtunel, którego punktem wejścia jest „zdalna” strona jego połączenie.

Z dwóch modeli pokazanych powyżej chcesz ten po prawej.

Z hosta zaporowego:

ssh -f -N -T -R22222:localhost:22 yourpublichost.example.com

To mówi Twojemu klientowi, aby założył tunel z -Rpunktem wejścia emotki. Wszystko, co zostanie dołączone do portu 22222 na drugim końcu tunelu, faktycznie osiągnie „port localhost 22”, gdzie „localhost” jest z punktu widzenia punktu wyjścia tunelu (tj. Klienta ssh).

Inne opcje to:

  • -f mówi ssh, aby sam się w tle po uwierzytelnieniu, więc nie musisz siedzieć i uruchamiać czegoś na zdalnym serwerze, aby tunel pozostał przy życiu.
  • -Nmówi, że chcesz mieć połączenie SSH, ale tak naprawdę nie chcesz uruchamiać żadnych zdalnych poleceń. Jeśli wszystko, co tworzysz, to tunel, to włączenie tej opcji oszczędza zasoby.
  • -T wyłącza alokację pseudo-tty, co jest odpowiednie, ponieważ nie próbujesz utworzyć interaktywnej powłoki.

Nie będzie hasła, chyba że skonfigurujesz klucze DSA lub RSA do logowania bez hasła.

Pamiętaj, że jest zdecydowanie zalecane, abyś używał konta „wyrzucanego” (nie własnego loginu), które skonfigurowałeś tylko dla tego tunelu / klienta / serwera.

Teraz z poziomu swojej powłoki na swoim serwerze publicznym nawiąż połączenie z hostem zaporowym przez tunel:

ssh -p 22222 username@localhost

Dostaniesz główne wyzwanie hosta, ponieważ prawdopodobnie nigdy wcześniej nie trafiłeś na tego hosta. Następnie otrzymasz wyzwanie dla hasła do usernamekonta (chyba że skonfigurowałeś klucze do logowania bez hasła).

Jeśli zamierzasz regularnie uzyskiwać dostęp do tego hosta, możesz również uprościć dostęp, dodając kilka wierszy do ~/.ssh/configpliku:

host remotehostname
    User remoteusername
    Hostname localhost
    Port 22222

Dostosuj remotehostnamei dopasuj remoteusername. remoteusernamePole musi dopasować swoją nazwę użytkownika na zdalnym serwerze, ale remotehostnamemoże być dowolna nazwa hosta, który ci odpowiada, że nie ma nic, aby dopasować rozpoznawana.

(Aby ujawnić odwrotny punkt końcowy na nielokalnym adresie IP hosta , sprawdź ten post )

ghoti
źródło
2
co z ssh -D. Proszę wyjaśnić za pomocą tej samej metody.
BigSack
6
Proxy SOCKS to nie to samo, co tunele. Jeśli masz pytanie, jak z nich korzystać, zadaj je .
ghoti
12
Mam bardzo trudny czas po tym wyjaśnieniu ze względu na luźne użycie terminów: serwer, klient, komputer lokalny, komputer zdalny, host, twoja publikacja, localhost, nazwa zdalnego hosta. Przy tych wszystkich luźnych i niezdefiniowanych warunkach można założyć, że ktoś będzie potrzebował aż 8 komputerów, aby to skonfigurować. Stwierdzam to, ponieważ we wszystkich innych aspektach wydaje się to bardzo dobrym wyjaśnieniem. Zmniejsz i zdefiniuj warunki.
Rucent88
4
@ Rucent88, nie jestem pewien, jaka redukcja byłaby możliwa. Klient nawiązuje połączenie z serwerem. To powszechna terminologia w całym świecie sieci. Lokalne i zdalne maszyny wydają się dość oczywiste. Jeśli po przeczytaniu dokumentacji nie rozumiesz terminologii SSH lub ogólnej terminologii unixowej, jestem pewien, że nie będziesz miał problemu ze znalezieniem osób chętnych do udzielenia odpowiedzi na wszelkie pytania.
ghoti
9
@ghoti To jest rzeczywiście mylące, ponieważ maszyny lokalne i zdalne są względne. Kiedy siedzę w miejscu pracy, mój komputer domowy jest zdalny, a kiedy siedzę w domu, komputer w miejscu pracy jest zdalny. Serwer i klient są również mylące, mówiąc o tunelowaniu. Na przykład jeśli podłączę się do domu z pracy za pomocą ssh -R. Łączę się z pracą z komputera domowego, podłączając localhost. Tak więc z perspektywy gniazd serwer jest samym komputerem domowym. Ale logicznie podłączyłem się do mojego komputera roboczego. To mylące.
Calmarius,
357

Narysowałem kilka szkiców

Maszyna, na której wpisano polecenie tunelu ssh, nosi nazwę »twój host« .

tunel ssh zaczynający się od lokalnego


tunel ssh zaczynający się zdalnie

Wprowadzenie

  1. lokalny: -L Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

    ssh -L sourcePort:forwardToHost:onPort connectToHostoznacza: połącz się z ssh do connectToHosti przekieruj wszystkie próby połączenia do lokalnego sourcePort na port onPortna wywoływanej maszynie forwardToHost, do którego można dotrzeć z connectToHostmaszyny.

  2. zdalny: -R Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.

    ssh -R sourcePort:forwardToHost:onPort connectToHostoznacza: połącz się z ssh do connectToHosti przekaż wszystkie próby połączenia do pilota sourcePort do portu onPortna wywoływanym komputerze forwardToHost, do którego można dotrzeć z twojego komputera lokalnego.

Dodatkowe opcje

  • -f mówi ssh, aby sam się w tle po uwierzytelnieniu, więc nie musisz siedzieć i uruchamiać czegoś na zdalnym serwerze, aby tunel pozostał przy życiu.
  • -Nmówi, że chcesz mieć połączenie SSH, ale tak naprawdę nie chcesz uruchamiać żadnych zdalnych poleceń. Jeśli wszystko, co tworzysz, to tunel, to włączenie tej opcji oszczędza zasoby.
  • -T wyłącza alokację pseudo-tty, co jest odpowiednie, ponieważ nie próbujesz utworzyć interaktywnej powłoki.

Twój przykład

Trzeci obraz przedstawia ten tunel. Ale niebieski komputer o nazwie „twój host” reprezentuje komputer, na którym ktoś rozpoczyna tunel ssh, w tym przypadku zaporę maszynową.

Poproś kogoś, aby rozpoczął połączenie tunelowe ssh z twoim komputerem. Polecenie powinno w zasadzie wyglądać

ssh -R 12345:localhost:22 YOURIP

Teraz tunel jest otwarty. Możesz teraz połączyć się przez ssh z zaporą ogniową przez tunel za pomocą polecenia

ssh -p 12345 localhost

który połączy się z twoim localhost(twoim komputerem) na porcie 12345, ale port 12345jest przekierowywany przez tunel do portu 22 lokalnego hosta zapory ogniowej (tj. samego zapory ogniowej).

erik
źródło
9
Świetna odpowiedź! Użyję tego w prezentacji.
Isaiah Turner
4
Dziękuję Ci. Nie ma za co. Jeśli chcesz obrazy wektorowe (svg lub pdf) napisz do mnie wiadomość.
erik
1
@erik, jak narysowałeś te obrazy?
Pacerier
31
o rany, chciałbym, aby strony podręcznika mogły mieć takie wyjaśnienia! dzięki!
Lucas Pottersky,
30
Wiesz co ? Nie musiałem nawet czytać wyjaśnienia tekstu. Świetna robota !
deppfx,
21

Tunelowanie ssh działa przy użyciu już ustanowionego połączenia ssh do wysyłania dodatkowego ruchu.

Kiedy łączysz się ze zdalnym serwerem, zwykle masz tylko 1 kanał do normalnej interakcji użytkownika (lub 3 kanały, jeśli uważasz, że STDIN / STDOUT / STDERR są osobne). W dowolnym momencie lokalny lub zdalny proces ssh może otworzyć dodatkowe kanały dla istniejącego połączenia. Kanały te następnie wysyłają / odbierają ruch tunelowy. Podczas wysyłania lub odbierania jakiegokolwiek ruchu, proces ssh po prostu mówi „ten ruch jest dla foobar kanału”.

Zasadniczo działa tak:

  1. Mówisz ssh, aby zaczął nasłuchiwać na porcie XXXX i że każdy otrzymany ruch powinien zostać tunelowany, a następnie ustawiony na YYYY na porcie ZZZZ.
  2. Lokalny ssh zaczyna nasłuchiwać na porcie XXXX (ogólnie włączony 127.0.0.1, ale można go zmienić).
  3. Niektóre aplikacje otwierają połączenie z portem XXXX na komputerze lokalnym.
  4. Lokalny ssh otwiera kanał na zdalnym ssh i mówi „każdy ruch na tym kanale trafia do RRRR: ZZZZ
  5. Zdalny ssh łączy się z YYYY: ZZZZ i odsyła „OK, kanał jest otwarty”
  6. Teraz wszelki ruch przesyłany wzdłuż połączenia do portu XXXX na komputerze lokalnym jest przekazywany przez ssh do YYYY: ZZZZ.

Ten proces jest dokładnie taki sam dla tunelowania do przodu i do tyłu (wystarczy zamienić słowa „lokalny” i „zdalny” w powyższej procedurze). Każda ze stron może rozpocząć tunel. Nie musi tak być nawet przy pierwszym uruchomieniu ssh. Możesz otwierać tunele, gdy ssh jest już uruchomiony (patrz ESCAPE CHARACTERSw szczególności ~C).

Do roli -R, -f, -L, i -N, naprawdę powinni po prostu skonsultować stronę man, to daje najlepsze możliwe wyjaśnienie. Ale wspomnę -Ri -L.
-Rmówi zdalnemu ssh, aby nasłuchiwał połączeń, a lokalny ssh powinien połączyć się z rzeczywistym miejscem docelowym. -Lmówi lokalnemu ssh, aby nasłuchiwał połączeń, a ten zdalny ssh powinien połączyć się z rzeczywistym miejscem docelowym.

Uwaga: jest to bardzo przybliżony opis, ale powinien dostarczyć wystarczającej ilości informacji, aby wiedzieć, co się dzieje

Patrick
źródło
16

Jest to wyjaśnione w instrukcji SSH, zwłaszcza różnice między -L(lokalnymi) a -R(zdalnymi).


-L

-L [bind_address:]port:host:hostport

Określa, że dany port na hoście lokalnym (klienckim) ma być przekazany do danego hosta i portu po stronie zdalnej .

Działa to poprzez przydzielenie gniazda do nasłuchiwania portu po stronie lokalnej, opcjonalnie powiązanego z określonym adresem bind_address.

Za każdym razem, gdy zostanie nawiązane połączenie z tym portem, połączenie zostanie przekazane bezpiecznym kanałem, a połączenie zostanie nawiązane z hostportem hostportze zdalnego komputera .

Poniższy przykład tuneluje sesję IRC z komputera klienta 127.0.0.1( localhost) przy użyciu portu 1234 do zdalnego serwera server.example.com:

$ ssh -f -L 1234:localhost:6667 server.example.com sleep 10

Uwaga: Określono -fopcję tła ssh i komendę zdalną, sleep 10aby dać czas na uruchomienie usługi, która ma być tunelowana.

Przykład:

ssh `-N` -L 22000:localhost:11000 remote.server.com
  • -N Po podłączeniu po prostu poczekaj (nie pojawi się monit powłoki)

    Nie wykonuj polecenia zdalnego.

  • -L 22000Połączenie będzie pochodzić na porcie 22000 swojego osobistego, L maszynie OCAL

  • localhost:11000- remote.server.comupewni się, że drugim końcem tunelu jest localhostport11000

ssh -N -L 22000: 192.168.1.2: 11000 remote.server.com

Źródło: Ilustrowany przewodnik, samouczek, porady dotyczące tunelowania ssh .


-R

-R [bind_address:]port:host:hostport

Określa, że dany port na zdalnym hoście (serwerze) ma być przekazywany do danego hosta i portu po stronie lokalnej .

Działa to poprzez przydzielenie gniazda do nasłuchiwania portpo stronie zdalnej, a za każdym razem, gdy połączenie jest nawiązywane z tym portem, połączenie jest przekazywane przez bezpieczny kanał, a połączenie jest nawiązywane z hostportem hostportz komputera lokalnego .

Przykład:

ssh -N -R 22000:localhost:11000 remote.server.com
  • -N Po podłączeniu po prostu poczekaj (nie pojawi się monit powłoki)

    Nie wykonuj polecenia zdalnego.

  • -R22000 Połączenie powstanie na porcie 22000 komputera zdalnego R (w tym przypadku remote.server.com)

  • localhost:11000Twój osobisty komputer lokalny upewni się, że drugim końcem tunelu jest localhostport11000

ssh -N -R 22000: localhost: 11000 remote.server.com

Źródło: Ilustrowany przewodnik, samouczek, porady dotyczące tunelowania ssh .

kenorb
źródło
6
ucho i usta wyraźnie mówią, kto mówi, a kto słucha!
Thufir
1
Uwielbiam twoje ilustracje!
mcantsin