SSH tunneling i port forwarding — przewodnik praktyczny
Opublikowano: 9 kwietnia 2026 · Kategoria: VPS / Bezpieczeństwo
SSH to nie tylko narzędzie do logowania na serwer — to potężny system tunelowania, który pozwala bezpiecznie uzyskać dostęp do baz danych, ekspozować lokalne aplikacje przez publiczny serwer, tworzyć prywatne proxy SOCKS i przeskakiwać przez serwery pośrednie (bastion). Wszystko za pomocą jednej komendy.
Czym jest SSH tunnel?
SSH tunnel (port forwarding) to mechanizm przekierowania ruchu TCP przez zaszyfrowane połączenie SSH. Zamiast otwierać port w firewallu, tworzysz "prywatny kanał" przez SSH — dostępny tylko dla uwierzytelnionego użytkownika. Trzy główne rodzaje:
- Local (-L) — lokalny port → zdalny zasób. Ty korzystasz z czegoś na serwerze.
- Remote (-R) — port serwera → Twój lokalny zasób. Serwer udostępnia Twój zasób światu.
- Dynamic (-D) — lokalny proxy SOCKS5. Wszystkie żądania przez proxy wychodzą z serwera.
Local port forwarding (-L) — dostęp do bazy danych przez tunel
Najczęstszy przypadek użycia: bezpieczny dostęp do MySQL lub PostgreSQL na VPS bez otwierania portu 3306/5432 w firewallu.
# Składnia: ssh -L [lokalny_port]:[host_docelowy]:[port_docelowy] [user@serwer] # Dostęp do MySQL na VPS — tunel na localhost:3306 ssh -L 3306:localhost:3306 -N [email protected] # -N = nie uruchamiaj powłoki, tylko tunel # Teraz w nowym terminalu: mysql -h 127.0.0.1 -P 3306 -u root -p # Łączysz się z MySQL na VPS przez zaszyfrowany tunel SSH! # Dostęp do PostgreSQL ssh -L 5432:localhost:5432 -N [email protected] psql -h 127.0.0.1 -p 5432 -U postgres # Dostęp do panelu adminer na porcie 8080 VPS ssh -L 8080:localhost:8080 -N [email protected] # Otwórz http://localhost:8080 w przeglądarce # Dostęp do usługi w sieci prywatnej VPS (nie na samym serwerze) # np. Redis na 10.0.0.5:6379 dostępnym tylko z VPS ssh -L 6379:10.0.0.5:6379 -N [email protected]
Tip bezpieczeństwa: Zamiast otwierać port 3306 w firewallu (i narażać bazę na internet), zablokuj port i używaj tunelu SSH. MySQL Workbench, DBeaver i pgAdmin mają wbudowaną opcję "SSH tunnel" — automatycznie tworzą tunel przy połączeniu.
Remote port forwarding (-R) — ekspozycja lokalnej aplikacji
Remote forwarding działa odwrotnie: udostępnia Twoją lokalną aplikację przez publiczny serwer. Użyteczne gdy Twój komputer jest za NATem (router domowy bez publicznego IP) i chcesz pokazać działającą aplikację klientowi lub współpracownikom.
# Składnia: ssh -R [port_na_serwerze]:[lokalny_host]:[lokalny_port] [user@serwer] # Udostępnij lokalną aplikację na porcie 3000 przez serwer na porcie 8080 ssh -R 8080:localhost:3000 -N [email protected] # Teraz ktoś wchodząc na http://twoj-vps.pl:8080 widzi Twoją lokalną aplikację! # Aplikacja na localhost:5000 dostępna przez serwer na porcie 9090 ssh -R 9090:localhost:5000 -N [email protected] # WAŻNE: domyślnie -R binduje na 127.0.0.1 serwera (tylko loopback) # Aby zezwolić na połączenia z zewnątrz, wymagane jest w /etc/ssh/sshd_config na serwerze: # GatewayPorts yes # Po zmianie: sudo systemctl reload sshd
Dynamic SOCKS proxy (-D) — prywatny VPN przez SSH
Opcja -D tworzy dynamiczny proxy SOCKS5 na lokalnym porcie. Wszystkie połączenia
kierowane przez ten proxy wychodzą z adresu IP serwera SSH — idealne do bezpiecznego przeglądania
przez niezaufaną sieć (kawiarnia, hotel):
# Utwórz lokalny proxy SOCKS5 na porcie 1080 ssh -D 1080 -N [email protected] # W Chrome/Firefox: # Ustawienia → Proxy → SOCKS Host: 127.0.0.1, Port: 1080, SOCKS5 # Lub uruchom Chrome z argumentem: google-chrome --proxy-server="socks5://127.0.0.1:1080" # curl przez SOCKS proxy curl --socks5 127.0.0.1:1080 https://api.example.com/ # Sprawdź swoje zewnętrzne IP (powinien pokazać IP serwera, nie Twoje) curl --socks5 127.0.0.1:1080 https://api.ipify.org
ProxyJump (-J) — przeskakiwanie przez bastion host
Bastion host (jump server) to pośredni serwer przez który łączysz się z serwerami w prywatnej sieci. ProxyJump upraszcza to do jednej komendy:
# Połącz się z prywatnym serwerem (10.0.0.20) przez bastion (bastion.example.com) ssh -J [email protected] [email protected] # Wielostopniowy (przez dwa bastion hosty) ssh -J [email protected],[email protected] [email protected] # Kopiuj plik przez bastion na prywatny serwer scp -J [email protected] plik.tar.gz [email protected]:/tmp/
~/.ssh/config — skróty dla częstych tuneli
Zamiast wpisywać długie komendy, zapisz konfigurację w ~/.ssh/config:
# ~/.ssh/config
# Prosty alias dla VPS
Host myvps
HostName twoj-vps.pl
User ubuntu
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 30
ServerAliveCountMax 3
# VPS z automatycznym tunelem do MySQL
Host vps-db
HostName twoj-vps.pl
User ubuntu
IdentityFile ~/.ssh/id_rsa
LocalForward 3306 localhost:3306
LocalForward 6379 localhost:6379
# Połączenie przez bastion
Host backend-server
HostName 10.0.0.20
User ubuntu
ProxyJump [email protected]
IdentityFile ~/.ssh/id_rsa # Teraz zamiast długiej komendy: # ssh -L 3306:localhost:3306 -L 6379:localhost:6379 -N [email protected] # Wystarczy: ssh vps-db # Połączenie z backend przez bastion: ssh backend-server
autossh — trwałe tunele, które się auto-restartują
Zwykłe tunele SSH zrywają się przy chwilowej utracie sieci. autossh monitoruje połączenie
i automatycznie je restartuje:
# Instalacja
sudo apt install autossh -y
# Trwały tunel do MySQL z auto-restartem
autossh \
-M 0 \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-o "ExitOnForwardFailure yes" \
-L 3306:localhost:3306 \
-N [email protected]
# -M 0: wyłącz wbudowany monitoring autossh, używaj keepalive SSH # Utwórz usługę systemd dla autossh (startuje przy boot)
sudo tee /etc/systemd/system/ssh-tunnel-db.service <<'EOF'
[Unit]
Description=SSH Tunnel to VPS MySQL
After=network.target
[Service]
User=ubuntu
ExecStart=/usr/bin/autossh -M 0 \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-o "ExitOnForwardFailure yes" \
-L 3306:localhost:3306 \
-N [email protected]
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now ssh-tunnel-db
sudo systemctl status ssh-tunnel-db Podsumowanie — kiedy używać każdego rodzaju tunelu
| Flaga | Kierunek | Przykład użycia |
|---|---|---|
-L | Lokalny → Serwer | Dostęp do MySQL/PostgreSQL/Redis na VPS bez otwierania portu w firewallu |
-R | Serwer → Lokalny | Pokazanie lokalnej aplikacji dev klientowi przez publiczny serwer |
-D | Proxy SOCKS5 | Bezpieczne przeglądanie przez niezaufaną sieć, obejście geoblokady |
-J | ProxyJump | Dostęp do serwerów w sieci prywatnej przez bastion host |