Tunelowanie SSH nie jest tak popularną usługą, jak VPN. No ale właśnie, co to ma wspólnego z VPN? Jak dostęp do zdalnej konsoli, protokół SSH, tunele i inne rzeczy mają coś wspólnego ze sobą? Co je dzieli a co łączy? Może jakieś konkretne przypadki użycia?

Trudno wskazać mi bardziej niedocenioną metodę dobierania się do pewnych usług od innej strony. I trudno mi wskazać coś, co bardziej na początku przygody z administracją systemami/aplikacjami/komputerami bardziej czesze beret i powoduje zmrużenie oczu, przy jednoczesnym rzuceniu pytania co to za czary?

Szybki szkic – co to i czym się to je?

Wyobraź sobie, że masz za pomocą SSH wjazd na maszynę, która ma uruchomioną aplikację, ale dostępną jedynie z tej maszyny, bez wystawienia jest na zewnątrz. Prościej? Serwer WWW, który ma z zewnątrz otwarte tylko SSH, ale nie WWW. Do hostowanej strony jest wjazd tylko wpisując http://localhost na tym serwerze. Mniej wyimaginowane? Zamknięte środowisko, w którym lata baza danych, do zarządzania której da się dostać tylko z serwera. No i ten serwer ma uruchomione też SSH.

Zdaję sobie sprawę, że to dość abstrakcyjny konstrukt, ale spokojnie, będzie prosto i życiowo. I z przykładami. Ale zaznaczam jednocześnie: skupiam się na lokalnym przekierowaniu portów/tunelowaniu lokalnych portów. Powód jest dość prosty: spotyka się to częściej, niż tunelowanie zdalnych portów i w życiu administratora zdecydowanie częściej się tego używa. Oczywiście źródłem tych rewelacji jest Instytut Danych z Dupy, pozwoli to jednak odkryć odrobinę rąbka tajemnicy.

Praktyka? Przygotujmy się

Przygotujmy sobie maszynę z dockerem. Utwórz katalog (u mnie: Tunelowanie) z projektem a w nim strukturę:

Tunelowanie/
│
├─ docker-compose.yml
├─ nginx/
│  ├─ default.conf
│  └─ index.html

No i teraz tak, zawartość ./nginx/default.conf:

server {
    listen 80;
    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}

Następnie ./nginx/index.html:

<h1>Hello World, jestem dostępny przez tunel SSH i localhost </h1>

I ostatecznie plik ./docker-compose.yml:

version: '3.8'

services:
  nginx:
    image: nginx:latest
    container_name: nginx_local
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - ./nginx/index.html:/usr/share/nginx/html/index.html:ro
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    restart: unless-stopped

i uruchamiamy to (docker compose up -d lub docker-compose up -d):

Z racji, że jedynym zadaniem kontenera jest zaserwować nam zawartość pliku index.html, można spokojnie użyć curl i sprawdzić, czy zostanie nam to zaserwowane.

Serwer:

curl http://localhost:8080

Czyli w skrócie: działa. Jest to osiągalne

A to, co otrzymamy, gdy to samo polecenie zostanie wykonane z poziomu innej maszyny. Oczywiście localhost został zastąpiony adresem IP serwera:

Czyli w skrócie: nie działa. Wyśmienicie.

Praktyka? Tuneluj to!

W poprzednim akapicie wykazaliśmy, że to nie zadziała, bo aplikacja ma być osiągalna jedynie z serwera. To trochę uproszczenie, ale to wystarczy. Zacznijmy w takim razie magię. Będziemy czarować panie Hermionowie i panowie Potterowie. Różdżka w dłoń i… cofam to co napisałem. Sprawy idą za daleko. Wróćmy do konsoli.

Otwórz na swoim komputerze terminal i uruchom polecenie:

ssh -L 2137:localhost:8080 [email protected]

W moim przypadku 192.168.10.51 to adres IP serwera WWW. Przyjrzyj się najpierw temu poleceniu, rozbierzmy je na atomy:

  • ssh: no bez jaj…
  • -L: „Panie SSH, robim tunel lokalny”
  • 2137:localhost:8080: „Weź port 2137 na localhoście i przekieruj go na 8080 na jakimś zdalnym, później podanym serwerze”
  • [email protected]: To jest ten później podany serwer

Reasumując: Weź port 2137 lokalnie i podepnij pod 8080 na podanym serwerze. Po lewej lokalnie, po prawej zdalnie. I tak zapomnisz, ja już zapomniałem 🙂

Jak łatwo zauważyć, strona jest osiągalna już na naszym komputerze, pod adresem http://localhost:2137

Czy też odnosicie wrażenie, że twórców składni trochę niebo spadło na głowę? Spójrz, wcześniej lokalny port był z lewej, teraz z prawej, głupie te kąkutery…

Dlaczego ten adres? Bo taki wskazaliśmy w poprzednim poleceniu. A właśnie, co w konsoli słychać? Otóż niewiele i odpowiednio przewijając ekran można nie zauważyć tego, że ma się tunel SSH posadzony na swoim kąkuterze.

Aby przestać tunelować, po prostu zamknij to. Wpisz exit w konsoli i tunelowanie zniknie. Serio. Na prawdę. No…

Jak to wygląda ciut głębiej?

Skoro to jest jakiś rodzaj sklejenia portu lokalnego do zdalnego, można o chyba jakoś podejrzeć, prawda? Prawda?

No prawda, ludzkość wymyśliła dawno temu narzędzia do tego. Użyjemy ss. Na naszym komputerze, z podniesionym tunelem, wpisz w konsoli:

ss -tlnp | grep 2137

Co to nam da? A to, o proszę:

Poprosiliśmy o listę połączeń TCP (flaga -t), bez rozwiązywania nazw hostów (-n), z wygadaniem się co to za proces (PID procesu, -p), no i samo słuchańsko (-l jak listening). No i mamy.

Dlaczego nie VPN i jaka to różnica?

Serwer SSH jest prawdopodobnie zainstalowany defaultowo na serwerze, do którego chcesz się dobrać. Nie musisz instalować żadnego dodatkowego oprogramowania, co na nie swoich serwerach nie jest takie oczywiste. Nie spowodujesz alertu bezpieczeństwa, bo używasz SSH. Nie otwierasz kolejnych portów, nie dłubiesz w firewallu, nie robisz niczego niezgodnego z prawem ustanowionym przez bezpieczeniki.

Jednocześnie masz kontrolę nad tym, co ma zostać przepchnięte tunelem. Skupiasz się na jednym porcie i na jednej usłudze. Unikasz sytuacji, gdy przez tunel poleci zbyt dużo.

VPN służy częściej do przepychania całego ruchu tunelem. Tunelowanie SSH ogranicza się do jednego, mocno kontrolowanego, łatwego do uruchomienia i zastopowania, portu. Nie wymaga także dodatkowych konfiguracji, przynajmniej w domyślnych instalacjach zarówno serwera, jak i klienta SSH.

Upraszcza także administrację (można sobie przepchnąć port do zarządzania bazą danych albo panel administracyjny administratora przez WWW, debugowanie, nie wymaga rzeźby w firewallu, zmian w zabezpieczeniach.

Nie nadaje się jednak do przeglądania internetu w kategorii daily. Znaczy się, nie ma przepisu który by tego zabraniał. Możliwość szybkiego, przypadkowego zamknięcia sesji, specyfika protokołu SSH, która jest upierdliwa w takich zastosowaniach skutecznie to uwala. Poza tym VPN jest do tego po prostu wygodniejszy: pchasz wszystko przez tunel, bez wskazywania konkretnych portów. Tunelowanie SSH to świetne narzędzie, ale dla administratorów. Odpowiadając na pytanie postawione w tytule: to moc, ale bardzo wyspecjalizowana. Łatwo też dojść do wniosku, że przy nieodpowiedniej konfiguracji i braku ostrożności, taki tunel może okazać się dość niebezpieczny, co jest prawdą. Skompromitowane klucze SSH, brak kontroli logów, nieograniczone dostępy – to jedynie wierzchołek góry lodowej potencjalnych problemów. Warto tunelowanie ssh rozważać w kategorii 20 minut na tymczasowy tunel, wykonanie zadania, posprzątanie po sobie. Trwałe użytkowanie lepiej przenieść na VPN, który w 99% (źródło: Instytut Danych z Dupy) zapewni wyższe bezpieczeństwo, lepszą kontrolę nad sesjami i użytkownikami.

Źródła


1 komentarz

Podsłuchiwanie pakietów – tcpdump, Wireshark i inne niuchadła – Baremetal.work · 03/12/2025 o 21:54

[…] potrzebę stosowania GUI. Nie będzie nam potrzebne, szczególnie, że przecież już wiadomo, że istnieje coś takiego jak curl […]

Skomentuj Podsłuchiwanie pakietów – tcpdump, Wireshark i inne niuchadła – Baremetal.work Anuluj pisanie odpowiedzi

Symbol zastępczy awatara

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *