Jak zestawić tunel przy pomocy ssh?

Wprowadzenie.

Protokół ssh dostarcza kilku mechanizmów pozwalających na uzyskanie połączenia sieciowego między dwoma, normalnie nie widzącymi się wzajemnie, komputerami. Najpopularniejszymi wydają się dwa mechanizmy pozwalające na.:

  • Tunelowanie całego ruchu z zadanego portu na maszynie klienckiej (czyli na maszynie na której jest uruchamiany klient ssh)  na inny port na maszynie widzianej z poziomu serwera ssh, ale nie widzianej z maszyny klienckiej.
  • Tunelowanie całego ruchu z zadanego portu na serwerze ssh na inny port na maszynie widzianej z poziomu maszyny klienckiej, ale nie widzianej bezpośrednio z poziomu serwera ssh.

Tunel z lokalnej maszyny do maszyny “schowanej” za serwerem ssh.

Do połączenia się z serwerem ssh wraz z jednoczesnym zestawieniem tunelu pierwszego typu używamy klienta ssh z następującymi przełącznikami:

gdzie:

-4 W ten sposób wskazujemy, że chcemy działać w ramach czwartej wersji protokołu IP. Jawną specyfikację wersji protokołu można pominąć i wtedy nastąpi również próba zestawienia tunelu po protokole IPv6.
-L Uwaga następuje definicja tunelu między lokalną maszyną kliencką a zdalną maszyną widoczną z poziomu serwera ssh.
local_bind_address Parametr opcjonalny. Adres interfejsu sieciowego na maszynie klienckiej, na którym ssh będzie nasłuchiwać na porcie wskazanym w parametrze local_port. Można w ten sposób ograniczyć interfejsy które będą “punktem wejścia” do tunelu.
local_port Port na maszynie klienciej (czyli na której uruchamiamy klienta ssh), z którego ruch będzie tunelowany na zdalną maszynę.
destination_host Adres maszyny docelowej, na którą ma być tunelowany ruch. Chodzi tu o maszynę osiągalną z poziomu serwera ssh. Można użyć nazwy domenowej lub postaci numerycznej. Rozwiązanie adresu następuje po stronie serwera ssh, dlatego należy pamiętać, że podajemy tu adres który jest osiągalny z poziomu serwera i który ma znaczenie w kontekście serwera. Przykładowo, podanie localhost będzie oznaczać localhost widziany z serwera ssh, czyli de facto sam serwer ssh, tyle że po interfejsie loopbcack.
destination_port Port na maszynie docelowej, na który będzie tunelowany ruch.
user Nazwa użytkownika na serwerze ssh
host Adres serwera ssh.

Jeśli chcemy zestawić tunel z pominięciem nawiązywania interaktywnej sesji z serwerem ssh, to należy użyć przełączników N i f, które oznaczają odpowiednio: nie uruchamiaj żadnego programu na serwerze (w domyśle, nie uruchamiaj shella) oraz przenosi klienta ssh w tło:

UWAGA: Powyższa komenda uruchamia klienta w tle i odłącza go od terminala. Oznacza to że zamknięcie terminala (czyli np. zamknięcie połączenia terminalowego) nie zakończy działającego w tle programu ssh i nie zamknie zestawionego tunelu. Zamknięcie tunelu nastąpi dopiero po jawnym zatrzymaniu programu ssh przy pomocy komendy kill. Do znalezienia PID-u programu ssh można użyć np. polecenia:

Wyświetlona w ten sposób lista programów ssh wraz z ich argumentami uruchomieniowymi powinna pozwolić szybko odnaleźć odpowiedni PID.

Do odnalezienia i zatrzymania programu o odpowiednim numerze PID można też użyć programów pgrep i pkill.

Tunel z serwera ssh do maszyny osiągalnej z maszyny klienckiej.

Do połączenia się z serwerem ssh wraz z jednoczesnym zestawieniem tunelu drugiego typu używamy klienta ssh z następującymi przełącznikami:

gdzie:

-4 W ten sposób wskazujemy, że chcemy działać w ramach czwartej wersji protokołu IP. Jawną specyfikację wersji protokołu można pominąć i wtedy nastąpi również próba zestawienia tunelu po protokole IPv6.
-R Uwaga, następuje definicja tunelu między serwerem ssh a maszyną widoczną z poziomu lokalnej maszyny na której jest uruchamiany klient ssh.
server_side_bind_address Parametr opcjonalny. Adres interfejsu sieciowego na serwerze ssh, na którym ssh będzie nasłuchiwać na porcie wskazanym w parametrze server_side_port. Można w ten sposób ograniczyć interfejsy które będą “punktem wejścia” do tunelu.
server_side_port Port na serwerze ssh, z którego ruch będzie tunelowany na maszynę osiągalną z lokalnej maszyny klienckiej.
local_side_host Adres maszyny docelowej, na którą ma być tunelowany ruch. Chodzi tu o maszynę osiągalną z poziomu maszyny z klientem ssh. Można użyć nazwy domenowej lub postaci numerycznej. Rozwiązanie adresu następuje po stronie klienta ssh, dlatego należy pamiętać, że podajemy tu adres który jest osiągalny z poziomu klienta i który ma znaczenie w kontekście maszyny klienckiej. Przykładowo, podanie localhost będzie oznaczać localhost widziany z klienta ssh, czyli de facto maszynę kliencką, tyle że po interfejsie loopbcack.
local_side_port Port na maszynie docelowej, na który będzie tunelowany ruch. Chodzi o maszynę dostępną z poziomu klienta ssh.
user Nazwa użytkownika na serwerze ssh.
host Adres serwera ssh.

Analogicznie do poprzedniego scenariusza, zestawienie tunelu z pominięciem uruchomienia interaktywnej sesji z serwerem ssh uzyskuje się przez opcje N i f:

UWAGA: Powyższa komenda uruchamia klienta w tle i odłącza go od terminala. Obowiązują te same uwagi co w poprzednim scenariuszu.

Przykłady

Poniższy przykład zakłada tunelowanie lokalnego portu 8888 do portu 80 (domyślny port http)  na maszynie widocznej z poziomu serwera example.pl jako 10.10.0.100.

Po zestawieniu takiego tunelu, połączenie z poziomu klienta z usługą http, na normalnie nie widocznym dla klienta węźle 10.10.0.100, następuje poprzez URL:

http://localhost:8888/

Kolejny przykład zakłada tunelowanie portu 2222 z serwera ssh na port 22 (domyślny port ssh) na maszynie widzianej z klienta jako localhost czyli na samego klienta. Tego typu tunel pozwala na łączenie się z usługą ssh uruchomioną na kliencie nawet jeśli maszyna kliencka jest schowana za NAT-em i teoretycznie nie ma możliwości nawiązania połączenia z tą maszyną z poziomu sieci publicznej.

Napisano w Administracja, Bezpieczeństwo