Potęga tunelowania SSH

Potęga tunelowania SSH

W skrócie – Tunelowanie SSH polega na zestawieniu pomiędzy dwoma serwerami dwukierunkowego, szyfrowanego połączenia za pomocą SSH. Choć brzmi to niewinne, daje potężne możliwości. Rozpoczynając od najprostszych tuneli, wraz z zagłębianiem się w temat, przejdziemy do tych bardziej zaawansowywanych.

1. Szyfrowanie kanału komunikacji

Wyobraźmy sobie sytuację, w której mamy zaimplementowanie jakieś oprogramowanie typu klient-serwer. W już działającym rozwiązaniu pojawia się wymóg zaszyfrowania komunikacji między klientem a serwerem. Zastanówmy się zatem przez chwilę… Co można zrobić w takiej sytuacji?

Jeśli oprogramowanie na to pozwala, to można oczywiście skonfigurować szyfrowanie – zabezpieczając tym samym kanał komunikacji.

A co w sytuacji, gdy twórca oprogramowania nie przewidział możliwościowi szyfrowania komunikacji? Jeśli mamy dostęp do kodu źródłowego, to można oczywiście zaimplementować szyfrowanie bezpośrednio w omawianym oprogramowaniu. Nie zawsze jednak mamy taką sposobność, a dodatkowo sama implementacja takiego szyfrowania wcale nie musi być łatwa.

1.1. Użycie przekierowania portów w celu zabezpieczenia kanału komunikacji

Alternatywą jest zestawienie tunelu SSH, który z natury jest szyfrowany, a następnie przekierować przez niego ruch klient-serwer. Rozwiązanie jest proste, mało awaryjne i warte rozważenia.

Załóżmy zatem, że serwer nasłuchuje na porcie 2080.

Aby wykorzystać ssh do zabezpieczenia kanału komunikacji, możemy na maszynie klienckiej otworzyć port 1080, z którego ruch zostanie przekierowany, poprzez szyfrowane połączenie SSH na port 2080 serwera. W tym celu za pomocą przychodzi nam poniższe polecenie:

ssh -nNT -L 1080:localhost:2080 user@server

Powyższe polecenie należy czytać następująco:

  • ssh user@server – otwórz połączenie SSH na user@server
  • -nNT – ustaw dodatkowe opcje wyłączające/blokujące zbędne funkcje ssh, które nie są wykorzystywane podczas przekierowywania portów. Warto je stosować również ze względów bezpieczeństwa.
  • -L 1080:localhost:2080 – odpowiada poleceniu -L localhost :1080:localhost:2080 – na maszynie, na której uruchamiam polecenie ssh otwórz port 1080 na interfejsie localhost (Uwaga! w tym przypadku interface localhost nie jest jawnie podany w poleceniu). W momencie połączenia na ten port niech serwer, na który się loguję(server) otworzy połączenie na localhost port 2080 oraz przekieruje tam ruch przychodzący i powracający.

2. Przykłady użycia przekierowania portów

Wykorzystanie tunelowania SSH w celu przekierowania portów, może przysparzać nieco problemów, szczególnie osobom, które dopiero zaczynają swoją przygodę ze światem linux’ów. Dlatego też, postanowiłem omówić kilka podstawowych konfiguracji tuneli, których znajomość może pozwolić Ci zaoszczędzić mnóstwo czasu w przyszłości.

W dalszej części będziemy w zasadzie posługiwać się dwoma trybami przekierowania portów -L oraz -R. Na rysunkach znaczyłem kolorem żółtym porty, które są właśnie otwierane, a kolorem purpurowym porty na które przekierowywany jest ruch.

Polecenie ssh -L port1:adressIP:port2 user@server można odczytać jako:

  • ssh user@server – otwórz połączenie SSH na user@server
  • -L port1:adressIP:port2 – na maszynie, na której uruchamiam polecenie ssh otwórz port port1(żółty) na interfejsie localhost. W momencie połączenia na ten port niech serwer, na który się loguję(server) otworzy połączenie na adressIP port port2(purpurowy) oraz przekieruje tam ruch przychodzący i powracający.

Polecenie ssh -R interfaceIP:port1:adressIP:port2 user@server można odczytać jako:

  • ssh user@server – otwórz połączenie SSH na user@server
  • -R interfaceIP:port1:adressIP:port2 – na zdalnej maszynie (do której się łączę), otwórz port port1(żółty)na interfejsie interfaceIP . W momencie połączenia na ten port niech klient SSH(maszyna na której uruchomiłem komendę ssh) nawiąże połączenie na adressIP port2(purpurowy) oraz tam przekieruje ruch z portu zdalnego serwera(2180).

2.1. Przekierowanie portów w obrębie jednej maszyny

Załóżmy, że mamy serwer http nasłuchujący na porcie 1080 na interfejsie localhost. W takiej konfiguracji nie możemy w prosty sposób dostać się do serwera z zewnątrz. Najprościej tę sytuację można zobrazować jak poniżej – czyli wszystko co wystawione jest na interfejsie wewnętrznym jest jakby pod szklaną kopułą i można się dostać do niego tylko z wewnątrz.

Załóżmy, że nie możemy zmienić konfiguracji serwera, a mimo wszystko chcielibyśmy móc się do niego dostać z zewnątrz. W tym celu możemy użyć polecenia:

ssh -nNT -L 192.168.1.1:1180:localhost:1080 user@localhost

W wyniku powyższego polecenia na interfejsie 192.168.1.1 serwera na którym wykonujemy polecenie zostanie otwarty port 1180. Następnie cały ruch z niego zostanie przekierowany na port 1080 interfejsu localhost serwera do którego się łączymy(localhost).

2.2. Przekierowanie porów na zdalny server

Pora skomplikować nieco problem. Załóżmy, że chcemy przekierować lokalny port 1080 serwera(server1) na publiczny interfejs innego serwera(server2). Sytuację tę można zobrazować jak poniżej.

Tu również z pomocą przychodzi nam tunel SSH, jednak nieco inaczej zestawiony.

ssh -nNT -R 192.168.1.2:2180:localhost:1080 user@server2

Powyższe polecenie należy czytać następująco:

  • ssh user@server2 – otwórz połączenie SSH na user@server2
  • -nNT – ustaw dodatkowe opcje wyłączające/blokujące zbędne funkcje ssh, które nie są wykorzystywane podczas przekierowywania portów. Warto je stosować również ze względów bezpieczeństwa.
  • -R 192.168.1.2:2180:localhost:1080 – na zdalnej maszynie(Remote), do której się łączę, otwórz port 2180 na interfejsie 192.168.1.2. W momencie połączenia na ten port niech klient SSH(server1) nawiąże połączenie na localhost 1080 oraz tam przekieruje ruch z portu zdalnego serwera(2180).

Należy pamiętać o zmianie wartości parametru w pliku /etc/ssh/sshd_config, który to umożliwi wystawienie portu na publicznym interfejsie.

GatewayPorts clientspecified

Aby otworzony port nasłuchiwał na wszystkich interfejsach wystarczy zamiast adresu podać *.

ssh -nNT -R *:2180:localhost:1080 user@server2

2.3. Tunelowanie do serwera za NAT

Kolejnym i dość częstym zastosowaniem tunelowania SSH jest przekierowanie portu serwera znajdującego się za NAT, na lokalny port naszego serwera. Rozważmy przypadki, gdy port, który chcemy przekierować z serwera wewnątrz NAT nasłuchuje tylko na prywatnym interfejsie oraz gdy jest on publiczny.

2.3.1. Tunelowanie portu wystawionego na prywatnym interfejsie serwera stojącego za NAT

W powyższym przykładzie, najpierw należy przedostać się do NAT używając serwera server2, następnie połączyć się z server3, aby ostatecznie zestawić połączanie zwrotne z server1 z odpowiednim przekierowaniem portów.

ssh user@server2
ssh user@server3
ssh -nNT -R 1080:localhost:3080 user@server1 

Możemy również chcieć nawiązać połączenie zwrotne na port 1180 wystawiony na publicznym interfejsie serwera server1. Aby tego dokonać musimy zmodyfikować polecenie ssh do poniższej postaci. Należy pamiętać o przestawieniu parametru GatewayPorts, co zostało opisane wcześniej.

ssh user@server2
ssh user@server3
ssh -nNT -R 192.168.1.1:1180:localhost:3080 user@server1 

Wówczas nasz tunel będzie zestawiony w następujący sposób:

2.3.1. Tunelowanie portu wystawionego na publicznym interfejsie serwera stojącego za NAT

W sytuacji, gdy port 3180 serwera server3 jest dostępny z serwera server2 sprawa znacznie się upraszcza.

W tej sytuacji wystarczy skorzystać z omawianego wcześniej wariantu -L, który przybierze postać:

ssh -nNT -L 1080:192.168.1.3:3180 user@server2 

Powyższe polecenie należy czytać następująco:

  • ssh user@server – otwórz połączenie SSH na user@server2
  • -nNT – ustaw dodatkowe opcje wyłączające/blokujące zbędne funkcje ssh, które nie są wykorzystywane podczas przekierowywania portów. Warto je stosować również ze względów bezpieczeństwa.
  • -L 1080:192.168.1.3:3180 – na maszynie, na której uruchamiam polecenie ssh otwórz port 1080 na interfejsie localhost. W momencie połączenia na ten port niech serwer, na który się loguję(server2) otworzy połączenie na 192.168.1.3 port 3080 oraz przekieruje tam ruch przychodzący i powracający.

3. SOCKS 5 Proxy

Przeglądając Internet, zwłaszcza w niesprawdzonych sieciach, nie możemy mieć pewności, że przesyłane przez nas dane nie są podsłuchiwane. W szczególności jeśli witryna używa protokołu http zamiast szyfrowania SSL(https). Jednym z rozwiązań opisanego problemu jest VPN. Nie zawsze jednak sytuacja pozwala na zestawienie właśnie takiego rodzaju połączenia.

Alternatywą może być użycie tunelu SSH do zaufanego serwera oraz Socks Proxy. Poniższe polecenie twory lokalny server SOCKS 5 na słuchujący na porcie 5000.

ssh -D 5000 -nNT user@server1 

Teraz wystarczy już tylko ustawić w przeglądarce proxy na localhost:5000, pamiętając o zaznaczeniu opcji SOCKS 5.

Jeśli chciałbyś mnie wesprzeć w tym co robię:
  • możesz udostępnić ten wpis np. na swoim twitterze lub facebooku
  • możesz również dołączyć do listy darczyńców udzielając drobnego wsparcia, które przeznaczę na dalszy rozwój bloga

4
Leave a Reply

avatar
2 Comment threads
2 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
lukasz.cieslaslawrst ack Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
rst ack
Guest
rst ack

Niestety, ale przykłady do forwardowania z opcjami -L oraz -R są błędne. Te opcje działają zupełnie inaczej niż Ci się wydaje. Po pierwsze w opcji -L klient nasłuchuje na localhost, więc nic na zewnątrz nie będzie widać. Nawet 0.0.0.0 tego nie zmieni. Podkreślam, że to klient nasłuchuje, nie serwer. Więc przykład 1.2 też jest błędny. Serwer nasłuchuje w opcji -R, ale też nie tak jak to zostało opisane. Radzę poczytaj najpierw dokumentację i sprawdzić przykłady w praktyce zanim przystąpi się do publikacji. Z tych wszystkich przykładów tylko SOCKS ma szansę zadziałać.

slaw
Guest
slaw

Same błędy w tych komendach… Choćby pierwszy przypadek – powinno być:
ssh -nNT -L 192.168.1.1:1180:localhost:1080 user@localhost
Można też zamiennie użyć ‘-R’, bez zmiany reszty komendy (ale tylko w tym przypadku), ponieważ klient i serwer to tu ta sama maszyna.

Pozostałe komendy też są do poprawy.
Analiza błędów: https://www.wykop.pl/link/4916693/#comment-64974583 (Wykop RULEZZZ! 🙂 ).

Sugeruję poprawienie artykułu, bo jakiś potencjał ma. Ale przez błędy – jest po prostu zły.

Serdecznie pozdrawiam!

Close Menu