1/49
SSH - bezpieczeństwo na warstwie administracyjnej

Bezpieczny zdalny dostęp do infrastruktury

  • Prezentacja dotyczy bezpiecznego zdalnego dostępu do infrastruktury sieciowej z wykorzystaniem protokołu Secure Shell (SSH) - standardu branżowego dla administracji systemami Unix/Linux
  • Omówiona zostanie mechanika kryptograficzna stosowana w SSH: szyfrowanie symetryczne i asymetryczne, rola pary kluczy publiczny-prywatny oraz ewolucja algorytmów w kierunku nowoczesnych krzywych eliptycznych (Ed25519)
  • Szczegółowo przeanalizujemy hardening usługi (demona sshd): wyłączenie logowania hasłem, blokada roota, ograniczenie dostępu do grup oraz zmiana domyślnego portu
  • Druga połowa warsztatu poświęcona jest SSH Tunneling (przekierowanie portów lokalne, odwrotne i dynamiczne SOCKS5) oraz praktycznemu laboratorium z troubleshootingiem
SSH - bezpieczeństwo administracyjne
2/49
Cel warsztatu

Praktyczne cele warsztatu SSH

  • Zrozumienie, jak działa bezpieczeństwo na warstwie administracyjnej - czyli jak chronimy dostęp do paneli zarządzania urządzeniami sieciowymi i serwerami
  • Opanowanie koncepcji szyfrowanych portów - tunelowanie ruchu przez SSH jako mechanizm zabezpieczania komunikacji aplikacji nieposiadających własnego szyfrowania
  • Praktyczne wdrożenie uwierzytelniania kluczami publicznymi w miejsce haseł, zgodnie z najlepszymi praktykami bezpieczeństwa
  • Umiejętność audytu i hardeningu konfiguracji serwera SSH oraz diagnozowania problemów z połączeniem
Cel warsztatu
3/49
Agenda spotkania

Plan warsztatu SSH

  • Blok I (slajdy 4–12): Podstawy kryptografii SSH - jak działa szyfrowanie symetryczne i asymetryczne, rodzaje kluczy, algorytmy (RSA, ECDSA, Ed25519)
  • Blok II (slajdy 13–20): Hardening demona sshd - konfiguracja pliku sshd_config, wyłączenie haseł, blokada roota, AllowGroups, zmiana portu
  • Blok III (slajdy 21–38): SSH Tunneling - Local Forwarding (-L), Remote Forwarding (-R), Dynamic SOCKS5 (-D)
  • Blok IV (slajdy 39–49): Laboratorium praktyczne i troubleshooting - generowanie kluczy, ssh-copy-id, debugowanie, prawa dostępu, known_hosts
Agenda spotkania
4/49
Ewolucja zdalnego logowania

Historia protokołów zdalnego dostępu

  • Początki zdalnego dostępu: protokół Telnet (RFC 854, 1983) - tekstowy, nieszyfrowany, przesyłał hasła w czystym tekście
  • Problemy bezpieczeństwa Telnetu: ataki sniffingiem, przechwytywanie sesji, brak integralności transmisji
  • Następca: rlogin (BSD, 1985) - również nieszyfrowany, zaufanie oparte na adresie IP i nazwie hosta
  • Przełom: SSH-1 opracowany przez Tatu Ylönena w 1995 roku - pierwszy protokół szyfrujący całą sesję zdalną
  • Obecnie: SSH-2 (RFC 4251, 2006) - standard IETF, znacznie bezpieczniejszy, z obsługą silniejszych algorytmów i tunelowania
Ewolucja zdalnego logowania
5/49
Architektura protokołu SSH-2

Budowa i warstwy SSH-2

  • SSH-2 składa się z trzech warstw: Transport Layer, Authentication Layer i Connection Layer
  • Transport Layer: negocjacja szyfrowania symetrycznego, kompresji, integralności (MAC) - ustalany jest wspólny klucz sesji
  • Authentication Layer: uwierzytelnianie klienta - hasłem, kluczem publicznym, GSSAPI (Kerberos), keyboard-interactive
  • Connection Layer: multipleksowanie wielu kanałów w jednym połączeniu - sesja shell, tunel portów, przesyłanie plików (SFTP, SCP)
  • Klucz serwera (host key) - unikalny dla każdego serwera, zapobiega atakom Man-in-the-Middle
Architektura protokołu SSH-2
6/49
Szyfrowanie symetryczne i asymetryczne w SSH

Dwa rodzaje szyfrowania w SSH

  • Szyfrowanie symetryczne: ten sam klucz do szyfrowania i odszyfrowywania - szybkie, używane do szyfrowania całej sesji (AES-256-GCM, ChaCha20-Poly1305)
  • Problem wymiany klucza: jak bezpiecznie przekazać klucz symetryczny przez niezabezpieczoną sieć? Rozwiązanie: Diffie-Hellman (DH) lub ECDH na krzywych eliptycznych
  • Szyfrowanie asymetryczne: para kluczy publiczny/prywatny - wolniejsze, używane do uwierzytelniania i wymiany klucza sesji
  • W SSH szyfrowanie asymetryczne służy do: podpisywania cyfrowego (uwierzytelnianie klienta) i negocjacji klucza sesji (DH)
  • Po ustanowieniu sesji cała komunikacja jest szyfrowana symetrycznie - szybciej i wydajniej
Szyfrowanie symetryczne i asymetryczne w SSH
7/49
Protokół Diffiego-Hellmana w SSH

Bezpieczna wymiana kluczy DH

  • Diffie-Hellman (DH) - protokół wymiany kluczy pozwalający dwóm stronom uzgodnić wspólny sekret przez niezabezpieczony kanał
  • Matematyka: obie strony generują swoje pary kluczy DH, wymieniają się częściami publicznymi, a następnie obliczają wspólny klucz sesji
  • Nawet jeśli atakujący przechwyci wszystkie pakiety, nie jest w stanie odtworzyć klucza sesji (problem logarytmu dyskretnego)
  • W SSH stosuje się DH modp (z liczbami pierwszymi) oraz ECDH (na krzywych eliptycznych) - ten drugi jest szybszy i bezpieczniejszy przy krótszych kluczach
  • Dodatkowo: HMAC (Hash-based Message Authentication Code) zapewnia integralność transmisji
Protokół Diffiego-Hellmana w SSH
8/49
Para kluczy: prywatny i publiczny

Klucz prywatny i publiczny SSH

  • Klucz prywatny - tajny, przechowywany wyłącznie lokalnie na maszynie klienta, nigdy nie jest przesyłany przez sieć. Pełni rolę "dowodu osobistego" administratora
  • Klucz publiczny - jawny, dystrybuowany do serwerów, na które chcemy się logować. Nie stanowi zagrożenia, gdy trafi w niepowołane ręce
  • Mechanizm uwierzytelniania: serwer wysyła losowe wyzwanie (challenge), klient podpisuje je swoim kluczem prywatnym, serwer weryfikuje podpis kluczem publicznym
  • Klucz publiczny serwera (host key) działa odwrotnie: klient weryfikuje tożsamość serwera przy pierwszym połączeniu (known_hosts)
  • Domyślna lokalizacja: ~/.ssh/id_ed25519 (prywatny) i ~/.ssh/id_ed25519.pub (publiczny)
Para kluczy: prywatny i publiczny
9/49
Algorytmy kluczy: RSA, ECDSA, Ed25519

RSA, ECDSA, Ed25519 w SSH

  • RSA - najstarszy, oparty na faktoryzacji liczb pierwszych. Dziś wymaga kluczy 3072+ bitów dla bezpieczeństwa, co czyni go wolnym przy generowaniu i weryfikacji
  • ECDSA (Elliptic Curve Digital Signature Algorithm) - oparty na krzywych eliptycznych standardu NIST (P-256, P-384, P-521). Szybszy od RSA, ale budzi kontrowersje (parametry NIST)
  • Ed25519 - nowoczesny algorytm oparty na krzywej eliptycznej Curve25519 (Daniel J. Bernstein). Klucz ma zaledwie 256 bitów, jest bardzo szybki i bezpieczny
  • Zalety Ed25519: stały czas wykonania (odporność na ataki timingowe), mały rozmiar klucza, wysoki margines bezpieczeństwa
  • Rekomendacja: domyślnie używaj Ed25519 - ssh-keygen -t ed25519
Algorytmy kluczy: RSA, ECDSA, Ed25519
10/49
Host key - odcisk palca serwera

Weryfikacja tożsamości serwera SSH

  • Host key - para kluczy generowana automatycznie podczas pierwszej instalacji serwera SSH, przechowywana w /etc/ssh/
  • Rola: umożliwia klientowi zweryfikowanie tożsamości serwera - czy łączymy się z właściwą maszyną, a nie z atakującym MITM
  • Przy pierwszym połączeniu SSH wyświetla odcisk (fingerprint) klucza serwera i pyta o akceptację (zapis do ~/.ssh/known_hosts)
  • Pliki host key: ssh_host_ed25519_key, ssh_host_rsa_key, ssh_host_ecdsa_key - każdy typ ma osobny plik
  • Weryfikacja odcisku: ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub po stronie serwera; klient porównuje z wyświetlonym przy łączeniu
Host key - odcisk palca serwera
11/49
known_hosts i authorized_keys

Zaufane hosty i autoryzowane klucze

  • ~/.ssh/known_hosts - plik po stronie klienta, przechowuje odciski kluczy publicznych serwerów, z którymi kiedykolwiek nawiązano połączenie
  • Każdy wpis: nazwa hosta (lub IP), typ klucza i odcisk (zakodowany w Base64). Przykład: server.example.com ecdsa-sha2-nistp256 AAAAE2VjZHNh...
  • ~/.ssh/authorized_keys - plik po stronie serwera, zawiera klucze publiczne użytkowników uprawnionych do logowania bez hasła
  • Każdy wpis w authorized_keys to jedna linia: typ klucza, klucz w Base64, opcjonalny komentarz (np. nazwa użytkownika lub hosta)
  • Zabezpieczenie: authorized_keys musi mieć prawa 600, a katalog ~/.ssh 700 - inaczej SSH odmówi uwierzytelnienia
known_hosts i authorized_keys
12/49
Odejście od RSA - krzywe eliptyczne

Nowoczesne algorytmy kluczy

  • RSA o długości 2048 bitów jest dziś uważane za minimalnie bezpieczne - eksperci zalecają 3072 lub 4096 bitów
  • Wady dużych kluczy RSA: wolne generowanie, powolne podpisywanie, duży rozmiar przesyłanych danych (klucz publiczny to 500+ bajtów)
  • Kryptografia krzywych eliptycznych (ECC) oferuje ten sam poziom bezpieczeństwa przy znacznie mniejszych kluczach: 256-bit ECC = 3072-bit RSA
  • Ed25519 to złoty standard w SSH: najszybszy, najmniejszy, najbezpieczniejszy - klucz publiczny to tylko 32 bajty
  • OpenSSH 9.5+ domyślnie używa Ed25519 - jeśli twój system tego nie robi, zmień ręcznie: ssh-keygen -t ed25519 -a 100
Odejście od RSA - krzywe eliptyczne
13/49
Hardening SSH - dlaczego to konieczne?

Wzmacnianie bezpieczeństwa SSH

  • Domyślna konfiguracja SSH jest zbyt liberalna dla środowiska produkcyjnego - pozwala na logowanie hasłem, rootem, na domyślnym porcie
  • Automatyczne skanery (boty) nieustannie skanują Internet w poszukiwaniu otwartego portu 22 - próby logowania to tysiące dziennie
  • Najczęstsze ataki na SSH: brute-force haseł, słownikowe, ataki na domyślne konta (root), skanowanie wersji serwera
  • Hardening = minimalizacja powierzchni ataku: im mniej usług i metod uwierzytelniania jest włączonych, tym trudniej zaatakować
  • Każda zmiana w sshd_config wymaga restartu demona: sudo systemctl restart sshd
Hardening SSH - dlaczego to konieczne?
14/49
Plik sshd_config - centrum dowodzenia

Główny plik konfiguracji SSH

  • Główny plik konfiguracyjny serwera SSH: /etc/ssh/sshd_config
  • Po każdej zmianie sprawdź poprawność składni: sudo sshd -t - jeśli nie zwróci błędów, można restartować
  • Restart demona: sudo systemctl restart sshd lub sudo service ssh restart
  • Zmiany w sshd_config dotyczą wszystkich nowych połączeń - istniejące sesje nie są zamykane
  • Zawsze miej zapasowe połączenie (np. konsolę IPMI) przed restartem sshd - ryzyko zablokowania się na zewnątrz
Plik sshd_config - centrum dowodzenia
15/49
Wyłączenie logowania hasłem

Logowanie tylko kluczem w SSH

  • Dyrektywa: PasswordAuthentication no - całkowicie wyłącza możliwość logowania przez hasło
  • Po zmianie jedyną metodą uwierzytelnienia jest klucz publiczny (publickey) lub alternatywne metody (GSSAPI, certificate)
  • Zalety: eliminacja ataków brute-force na hasła, brak ryzyka wycieku haseł przez phishing, większa wygoda (logowanie bez hasła)
  • Przed wyłączeniem upewnij się, że masz skonfigurowany klucz publiczny w authorized_keys na docelowym serwerze
  • Test: po zmianie otwórz NOWE okno terminala i spróbuj się zalogować - jeśli coś pójdzie źle, masz jeszcze stare połączenie
Wyłączenie logowania hasłem
16/49
Blokada logowania na konto root

Zakaz logowania root przez SSH

  • Dyrektywa: PermitRootLogin prohibit-password - root może logować się tylko kluczem, nie hasłem
  • Alternatywa: PermitRootLogin no - całkowicie blokuje logowanie przez SSH na konto root
  • Dlaczego blokować roota? Root to znana nazwa konta, pierwszy cel ataków brute-force; logowanie rootem maskuje audyt (nie wiadomo, kto faktycznie brał dostęp)
  • Lepsza praktyka: loguj się na zwykłe konto, potem używaj sudo lub su - do eskalacji uprawnień
  • Jeśli musisz mieć root przez SSH (np. automatyzacja Ansible): użyj PermitRootLogin prohibit-password + klucz + ograniczenie w AllowGroups
Blokada logowania na konto root
17/49
Ograniczenie dostępu przez AllowGroups

Dostęp SSH tylko dla wybranych grup

  • Dyrektywa: AllowGroups ssh-users - tylko użytkownicy należący do grupy "ssh-users" mogą logować się przez SSH
  • Analogiczne: AllowUsers - lista konkretnych nazw użytkowników (np. AllowUsers admin1 admin2)
  • Działa odwrotnie: DenyGroups i DenyUsers - blokują grupy/użytkowników, reszta ma dostęp
  • Zalety: nie musisz pamiętać o wyłączaniu kont dla zwolnionych pracowników - wystarczy usunąć ich z grupy
  • Przykład: sudo groupadd ssh-users; sudo usermod -aG ssh-users john; dodaj do sshd_config: AllowGroups ssh-users
Ograniczenie dostępu przez AllowGroups
18/49
Zmiana domyślnego portu SSH

Niestandardowy port SSH dla bezpieczeństwa

  • Dyrektywa: Port 2222 - zmiana z domyślnego 22 na niestandardowy (np. 2222, 8022)
  • Cel: zredukowanie liczby automatycznych skanów i prób logowania z botów skanujących tylko port 22
  • Uwaga: zmiana portu to nie jest prawdziwe zabezpieczenie (security through obscurity) - atakujący skanują całe zakresy portów
  • Pamiętaj o firewallu: dostosuj reguły do nowego portu - np. ufw allow 2222/tcp lub firewall-cmd --add-port=2222/tcp
  • Po stronie klienta: ssh -p 2222 user@server lub w ~/.ssh/config: Port 2222
Zmiana domyślnego portu SSH
19/49
Dodatkowe dyrektywy hardeningu

Zaawansowane opcje bezpieczeństwa SSH

  • MaxAuthTries 3 - ogranicza liczbę prób uwierzytelnienia na połączenie (przeciwdziała brute-force)
  • ClientAliveInterval 300 i ClientAliveCountMax 2 - zamykanie wiszących połączeń po 10 minutach bezczynności
  • Uwaga: OpenSSH od wersji 7.5 (2017) obsługuje wyłącznie SSH-2, nie ma już potrzeby stosowania dyrektywy Protocol - została usunięta; SSH-1 jest całkowicie wyeliminowany
  • X11Forwarding no - wyłącz przekierowanie X11, jeśli nie jest potrzebne (ryzyko przechwycenia sesji graficznej)
  • PrintMotd no i PrintLastLog no - redukcja informacji wyświetlanych przed logowaniem (mniejszy przekaz informacji o systemie)
Dodatkowe dyrektywy hardeningu
20/49
Podsumowanie hardeningu - wzorcowa konfiguracja

Wzór bezpiecznej konfiguracji SSH

  • Poniżej wzorzec produkcyjny pliku /etc/ssh/sshd_config:
  • # /etc/ssh/sshd_config - wzorzec produkcyjny
    Port 51022
    PermitRootLogin no
    PasswordAuthentication no
    PubkeyAuthentication yes
    AuthenticationMethods publickey
    AllowGroups ssh-users
    MaxAuthTries 3
    MaxSessions 5
    ClientAliveInterval 300
    ClientAliveCountMax 2
    X11Forwarding no
    PrintMotd no
    LogLevel VERBOSE
    UsePAM yes
    PermitEmptyPasswords no
    LoginGraceTime 30
  • Port 51022 redukuje automatyczne skany; nowoczesny OpenSSH (7.5+) obsługuje wyłącznie SSH-2
  • PermitRootLogin no blokuje roota; PasswordAuthentication no wymusza klucze; AllowGroups ssh-users ogranicza dostęp
  • Zawsze testuj komendą sshd -t przed restartem demona
Podsumowanie hardeningu - wzorcowa konfiguracja
21/49
SSH Tunneling - koncepcja

Tunelowanie portów przez SSH

  • SSH Tunneling (przekierowanie portów) - mechanizm umożliwiający tunelowanie ruchu sieciowego przez istniejące połączenie SSH
  • Wszystkie dane przesyłane przez tunel są szyfrowane - tak jak samo połączenie SSH
  • Trzy typy tunelowania: Local Forwarding (-L), Remote Forwarding (-R) i Dynamic Forwarding (-D), SOCKS5 proxy
  • Zastosowania: dostęp do baz danych za firewallem, omijanie NAT, bezpieczne proxy, tunelowanie ruchu HTTP przez szyfrowane połączenie
  • SSH Tunneling to potężne narzędzie - pozwala "przedziurawić" firewall w kontrolowany sposób
SSH Tunneling - koncepcja
22/49
Local Forwarding - tunel lokalny

Przekierowanie lokalne w SSH

  • Składnia: ssh -L [local_bind:]local_port:remote_host:remote_port user@server
  • Przekierowuje ruch z lokalnego portu na maszynie klienta do zdalnego hosta i portu przez serwer SSH
  • Przykład: ssh -L 3306:127.0.0.1:3306 user@server - lokalny port 3306 przekierowany do MySQL na serwerze
  • Można wskazać dowolny remote_host - nie musi to być ten sam serwer SSH. Np. -L 8080:192.168.1.10:80 tuneluje do innego hosta w sieci serwera
  • Flaga -N: nie wykonuj komendy (tylko tunel), -f: działaj w tle
Local Forwarding - tunel lokalny
23/49
Local Forwarding - dostęp do MySQL

Tunel SSH do bazy MySQL

  • Scenariusz: serwer bazy MySQL (port 3306) słucha tylko na localhost, firewall blokuje wszystkie porty poza 22 (SSH)
  • Rozwiązanie: tunel lokalny przez SSH - ssh -L 13306:127.0.0.1:3306 admin@serwer-produkcyjny.pl
  • Po stronie klienta: mysql -h 127.0.0.1 -P 13306 -u root -p - łączymy się z "lokalną" bazą, ale faktycznie trafiamy na serwer
  • Zalety: nie trzeba otwierać portu 3306 w firewallu; ruch przez tunel jest w pełni szyfrowany (MySQL sam w sobie może nie mieć szyfrowania TLS)
  • Debugowanie: sudo netstat -tlnp | grep 13306 - powinien pokazać proces ssh nasłuchujący na porcie 13306
Local Forwarding - dostęp do MySQL
24/49
Local Forwarding - wiele tuneli

Wiele przekierowań lokalnych SSH

  • Można otworzyć wiele tuneli w jednym połączeniu SSH: ssh -L 8080:web:80 -L 3306:db:3306 user@bastion
  • Każda flaga -L dodaje osobny tunel - SSH nasłuchuje na każdym z lokalnych portów jednocześnie
  • Alternatywa: użyj pliku konfiguracyjnego ~/.ssh/config z dyrektywą LocalForward
  • Wzór z plikiem config:
    Host bastion
        HostName bastion.example.com
        User admin
        LocalForward 8080 web.internal:80
        LocalForward 3306 db.internal:3306
  • Połączenie: ssh bastion - tunel uruchamia się automatycznie
Local Forwarding - wiele tuneli
25/49
Remote Forwarding - tunel odwrotny

Przekierowanie zdalne w SSH

  • Składnia: ssh -R [remote_bind:]remote_port:local_host:local_port user@server
  • Przekierowuje ruch z portu na serwerze do lokalnego hosta i portu na maszynie klienta
  • Innymi słowy: otwieramy port po stronie serwera, który przekierowuje ruch do naszej maszyny lokalnej
  • Zastosowanie: dostęp do maszyny za NAT-em bez potrzeby konfiguracji przekierowania portów na routerze
  • Przykład: ssh -R 2222:127.0.0.1:22 user@public-server.com - połączenie na public-server:2222 trafi do SSH na lokalnym laptopie
Remote Forwarding - tunel odwrotny
26/49
Remote Forwarding - omijanie NAT

Tunel odwrotny przez NAT

  • Scenariusz: laptop administratora w sieci domowej za NAT-em, potrzebuje zdalnego dostępu z zewnątrz do powłoki
  • Rozwiązanie: z laptopa łączymy się z publicznym serwerem pośrednim (VPS): ssh -R 2222:127.0.0.1:22 user@vps.example.com
  • Z dowolnego miejsca: ssh -p 2222 user@vps.example.com - trafiamy do shella na laptopie za NAT-em
  • Działa to, ponieważ to laptop inicjuje połączenie wychodzące (przechodzi przez NAT/firewall), a nie oczekuje na połączenie przychodzące
  • Wymagania: serwer pośredni z publicznym IP i włączoną opcją GatewayPorts lub nasłuchiwanie na localhost
Remote Forwarding - omijanie NAT
27/49
Remote Forwarding - scenariusz produkcyjny

Zdalny tunel w praktyce

  • Scenariusz: serwer wewnętrzny (192.168.1.100) bez publicznego IP, ale z dostępem do Internetu przez NAT
  • Z serwera wewnętrznego: ssh -R 8080:127.0.0.1:80 user@public-server.com - tunel dla panelu webowego
  • Teraz panel administracyjny serwera wewnętrznego jest dostępny pod public-server.com:8080
  • Można tunelować wiele usług z jednego serwera: ssh -R 8080:127.0.0.1:80 -R 2222:127.0.0.1:22 user@public
  • Automatyczne utrzymanie tunelu: użyj autossh - narzędzia, które monitoruje połączenie SSH i restartuje je w razie przerwy
Remote Forwarding - scenariusz produkcyjny
28/49
Dynamic Forwarding - SOCKS5 proxy

Proxy SOCKS5 przez SSH

  • Składnia: ssh -D [local_bind:]local_port user@server
  • Tworzy SOCKS5 proxy na lokalnym porcie - cały ruch aplikacji przez ten proxy przechodzi przez tunel SSH
  • Różnica vs -L: nie trzeba określać docelowego hosta i portu - decyzja podejmowana jest dynamicznie przez aplikację kliencką
  • Zastosowanie: bezpieczne przeglądanie Internetu (przeglądarka + SOCKS5 proxy), omijanie blokad geograficznych, maskowanie IP
  • Przykład: ssh -D 1080 user@server - proxy SOCKS5 na localhost:1080; w przeglądarce ustaw proxy SOCKS5 na 127.0.0.1:1080
Dynamic Forwarding - SOCKS5 proxy
29/49
SOCKS5 - konfiguracja przeglądarki

Przeglądarka przez tunel SOCKS5

  • Firefox: Ustawienia -> Sieć -> Proxy -> Ręczna konfiguracja -> SOCKS Host: 127.0.0.1, Port: 1080, SOCKS v5; zaznacz "Proxy DNS przez SOCKS5"
  • Chrome: uruchom z flagami: --proxy-server="socks5://127.0.0.1:1080" --host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE localhost"
  • Systemowe ustawienia proxy (Windows/macOS/Linux): ustaw zmienną środowiskową ALL_PROXY=socks5://127.0.0.1:1080
  • Weryfikacja działania: wejdź na ifconfig.me lub checkip.amazonaws.com - powinno pokazać IP serwera SSH
  • Cały ruch HTTP/HTTPS aplikacji korzystającej z proxy jest szyfrowany przez tunel SSH aż do serwera
SOCKS5 - konfiguracja przeglądarki
30/49
Porównanie typów tunelowania SSH

Lokalny, zdalny i dynamiczny w SSH

  • TypFlagaKierunekZastosowanie
    Local-LKlient -> SerwerDostęp do usług w sieci serwera przez lokalny port
    Remote-RSerwer -> KlientDostęp do klienta za NAT-em przez port na serwerze
    Dynamic-DSOCKS5 proxyRouting ruchu całej aplikacji przez serwer
  • Local (-L): otwiera port na kliencie, przekierowuje do zdalnego hosta przez serwer. Najczęstsze użycie
  • Remote (-R): otwiera port na serwerze, przekierowuje do lokalnego hosta. Do omijania NAT
  • Dynamic (-D): SOCKS5 proxy na kliencie. Elastyczne tunelowanie bez stałego celu
Porównanie typów tunelowania SSH
31/49
GatewayPorts - udostępnianie tuneli innym

Udostępnianie tuneli SSH w sieci

  • Dyrektywa serwerowa: GatewayPorts yes w sshd_config - pozwala, aby tunele były dostępne na wszystkich interfejsach
  • Domyślnie tunele (-R i -L) nasłuchują tylko na 127.0.0.1 (localhost), więc dostępne są tylko lokalnie
  • Z GatewayPorts yes możesz użyć ssh -R 0.0.0.0:2222:127.0.0.1:22 user@server, aby udostępnić tunel innym maszynom
  • Ostrożnie: udostępnianie tuneli na zewnątrz to ryzyko - każdy, kto ma dostęp do sieci serwera, może użyć tunelu
  • Alternatywa: użyj ssh -R 127.0.0.1:2222:127.0.0.1:22 + dodatkowy tunel z innego serwera (hops)
GatewayPorts - udostępnianie tuneli innym
32/49
Tunelowanie przez jump host (bastion)

Bastion SSH jako brama przesiadkowa

  • Architektura: klient -> bastion (jump host) -> serwer docelowy - bez bezpośredniego dostępu do serwera docelowego
  • Flaga -J (ProxyJump): ssh -J user@bastion user@target - SSH automatycznie tworzy tunel przez bastion
  • Stary sposób (ProxyCommand): ssh -o ProxyCommand="ssh -W %h:%p bastion" user@target
  • W pliku ~/.ssh/config:
    Host target
        ProxyJump bastion
        User admin
  • Łączenie z bazą przez bastion: ssh -J user@bastion -L 3306:127.0.0.1:3306 user@dbserver
Tunelowanie przez jump host (bastion)
33/49
SSH Agent Forwarding

Przekazywanie agenta SSH

  • ssh-agent - proces przechowujący odblokowane klucze prywatne w pamięci, aby nie wpisywać hasła (passphrase) przy każdym połączeniu
  • Agent Forwarding - pozwala na używanie lokalnego ssh-agenta podczas łączenia się z kolejnymi serwerami (skakanie po serwerach)
  • Włączanie: ssh -A user@server lub w config: ForwardAgent yes
  • Zastosowanie: łączysz się z bastionem, a z bastiona do serwera docelowego - bez przechowywania kluczy na bastionie
  • Ryzyko: administrator bastionu może użyć twojego forwardowanego agenta do logowania się na inne serwery (atak przez socket agenta)
SSH Agent Forwarding
34/49
SSH Config - zaawansowana konfiguracja klienta

Plik ~/.ssh/config

  • Plik ~/.ssh/config - centralna konfiguracja klienta SSH, definiuje aliasy, parametry połączeń i tunele
  • Przykład wpisu:
    Host prod-db
        HostName db.example.com
        User admin
        Port 51022
        IdentityFile ~/.ssh/prod_key_ed25519
        LocalForward 3306 127.0.0.1:3306
  • Po zapisaniu: ssh prod-db - łączy z bazą, otwiera tunel, używa odpowiedniego klucza
  • Wzór: Host * - konfiguracja domyślna dla wszystkich hostów (np. ForwardAgent no, ServerAliveInterval 60)
  • Możliwość warunkowego stosowania opcji przez wzorce (Host gitlab.com, Host 192.168.*)
SSH Config - zaawansowana konfiguracja klienta
35/49
SSH Certificates - zarządzanie zaufaniem

Certyfikaty SSH dla skalowalności

  • SSH Certificates - zaawansowany mechanizm uwierzytelniania, gdzie klucz publiczny jest podpisywany przez zaufany urząd certyfikacji (CA)
  • Zamiast rozpraszać klucze publiczne do authorized_keys na każdym serwerze, serwer ufa CA, a klient przedstawia certyfikat
  • Certyfikat SSH to zwykły klucz publiczny z dołączonym podpisem CA i metadanymi (ważność, nazwa użytkownika, ograniczenia)
  • Skalowalność: jeden podpis CA obsługuje wszystkie serwery; odwołanie certyfikatu = wygaśnięcie (certyfikaty mają datę ważności)
  • Konfiguracja serwera: TrustedUserCAKeys /etc/ssh/ca.pub w sshd_config
SSH Certificates - zarządzanie zaufaniem
36/49
SSH w środowisku Windows

OpenSSH na Windows

  • Windows 10/11: OpenSSH jest wbudowany (od 2018) - klient i serwer dostępne jako opcjonalne komponenty systemu
  • Instalacja serwera: Ustawienia -> Aplikacje -> Opcjonalne funkcje -> Dodaj funkcję -> "OpenSSH Server"
  • Lokalizacja plików: C:\ProgramData\ssh\sshd_config (serwer), %USERPROFILE%\.ssh\ (klient)
  • Konfiguracja serwera Windows: taka sama składnia sshd_config jak w Linux - PasswordAuthentication, PermitRootLogin (Administrator), AllowGroups
  • Uwagi: serwer OpenSSH na Windows może używać uwierzytelniania NTLM/Kerberos; domyślna powłoka to cmd.exe (można zmienić na PowerShell)
SSH w środowisku Windows
37/49
Fail2Ban i sshguard - dodatkowa ochrona

Automatyczna blokada ataków SSH

  • Fail2Ban - narzędzie do blokowania adresów IP po wykryciu nieudanych prób logowania (analizuje logi syslog/auth.log)
  • Konfiguracja dla SSH: domyślnie banuje IP po 5 nieudanych próbach na 10 minut
  • Działanie: fail2ban monitoruje /var/log/auth.log, dopasowuje wzorce (regex), dodaje regułę do iptables/nftables/firewalld
  • sshguard - alternatywa, lżejsza, pisana w C (fail2ban w Python), podobna zasada działania
  • Ograniczenia: fail2ban nie chroni przed atakami z wielu IP (rozproszony brute-force), nie zastępuje prawidłowej konfiguracji SSH
Fail2Ban i sshguard - dodatkowa ochrona
38/49
Podsumowanie części tunelowania

Tunelowanie SSH w pigułce

  • SSH Tunneling to nieocenione narzędzie w pracy administratora sieci - pozwala bezpiecznie łączyć się z usługami bez otwierania dodatkowych portów
  • -L (Local): dostęp do bazy danych, paneli webowych, RDP za firewallem przez lokalny port
  • -R (Remote): ominięcie NAT - twój serwer za NAT-em staje się dostępny z zewnątrz
  • -D (Dynamic): SOCKS5 proxy - bezpieczne przeglądanie, maskowanie IP, ominięcie blokad geograficznych
  • Pamiętaj: tunele SSH to potężne narzędzie - używaj odpowiedzialnie i zawsze kontroluj, kto ma do nich dostęp
Podsumowanie części tunelowania
39/49
Laboratorium - generowanie pary kluczy

Lab: generowanie kluczy SSH

  • Krok 1: Otwórz terminal (Linux/macOS) lub PowerShell (Windows) na swoim komputerze klienckim
  • Krok 2: Wygeneruj parę kluczy Ed25519: ssh-keygen -t ed25519 -a 100 -C "komentarz@example.com"
  • -t ed25519: typ klucza (zalecany), -a 100: liczba rund KDF (im więcej, tym trudniej złamać passphrase), -C: komentarz (np. email)
  • Program zapyta o ścieżkę zapisu (domyślnie ~/.ssh/id_ed25519) i passphrase (hasło chroniące klucz prywatny)
  • Zawsze używaj passphrase! Jeśli klucz bez passphrase wpadnie w niepowołane ręce, atakujący natychmiast ma dostęp do wszystkich serwerów
Laboratorium - generowanie pary kluczy
40/49
Laboratorium - wysyłka klucza na serwer

Lab: kopiowanie klucza ssh-copy-id

  • Krok 3: Skopiuj klucz publiczny na serwer: ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
  • ssh-copy-id automatycznie: łączy się z serwerem (poprosi o hasło), dodaje klucz do ~/.ssh/authorized_keys, ustawia odpowiednie prawa (600)
  • Jeśli ssh-copy-id nie jest dostępny (np. starszy Windows): cat ~/.ssh/id_ed25519.pub | ssh user@server "cat >> ~/.ssh/authorized_keys"
  • Po skopiowaniu: ssh user@server - jeśli klucz działa, zalogujesz się bez hasła (lub z passphrase klucza, jeśli agent nie jest uruchomiony)
  • Weryfikacja na serwerze: sprawdź plik ~/.ssh/authorized_keys - powinien zawierać twój klucz publiczny
Laboratorium - wysyłka klucza na serwer
41/49
Laboratorium - ssh-agent i passphrase

Lab: agent SSH i hasło klucza

  • Krok 4: Uruchom ssh-agent i dodaj klucz: eval $(ssh-agent) (Linux/macOS) lub uruchom usługę "OpenSSH Authentication Agent" (Windows)
  • Dodaj klucz do agenta: ssh-add ~/.ssh/id_ed25519 - wpisz passphrase raz, potem agent pamięta aż do wylogowania
  • Od tej pory logowanie na serwery, które mają twój klucz publiczny, odbywa się bez pytania o passphrase
  • Sprawdź, które klucze są w agencie: ssh-add -l - wyświetla odciski palców załadowanych kluczy
  • Usuń klucz z agenta: ssh-add -d ~/.ssh/id_ed25519; usuń wszystkie: ssh-add -D
Laboratorium - ssh-agent i passphrase
42/49
Laboratorium - konfiguracja ~/.ssh/config

Lab: plik config klienta SSH

  • Krok 5: Edytuj plik ~/.ssh/config i dodaj wpisy dla swoich serwerów
  • Przykładowa konfiguracja:
    Host serwer-prod
        HostName 192.168.1.100
        Port 51022
        User admin
        IdentityFile ~/.ssh/id_ed25519
        LocalForward 3306 127.0.0.1:3306
  • Po zapisaniu: ssh serwer-prod - SSH automatycznie użyje odpowiedniego portu, klucza i otworzy tunel
  • Korzyści: nie musisz pamiętać adresów IP, portów i parametrów - wszystko jest w pliku konfiguracyjnym
  • Zabezpieczenie: ustaw prawa 600 dla pliku config: chmod 600 ~/.ssh/config
Laboratorium - konfiguracja ~/.ssh/config
43/49
Laboratorium - debugowanie z flagą -v

Lab: debugowanie SSH (-v)

  • Krok 6: Użyj trybu verbose do debugowania połączenia: ssh -v user@server
  • Flagi verbose: -v (podstawowy), -vv (szczegółowy), -vvv (debugowanie protokołu)
  • Output verbose pokazuje: negocjację algorytmów (kex), próby uwierzytelnienia, wybór klucza, połączenie
  • Szukaj linii: "Authenticated with partial success" lub "Authentication succeeded" - to potwierdza udane logowanie
  • Jeśli widzisz "Permission denied (publickey)" - sprawdź prawa dostępu i zawartość authorized_keys na serwerze
Laboratorium - debugowanie z flagą -v
44/49
Laboratorium - tunel Local Forwarding

Lab: tunel lokalny SSH

  • Krok 7: Uruchom tunel Local Forwarding do bazy MySQL: ssh -L 13306:127.0.0.1:3306 -Nf user@server
  • Flagi: -L (local forwarding), -N (nie uruchamiaj shella), -f (działaj w tle)
  • Weryfikacja: otwórz drugi terminal i wykonaj mysql -h 127.0.0.1 -P 13306 -u root -p - powinieneś połączyć się z bazą na serwerze
  • Sprawdź działanie tunelu: netstat -ano | findstr 13306 (Windows) lub sudo netstat -tlnp | grep 13306 (Linux)
  • Zakończenie tunelu: znajdź PID procesu SSH (ps aux | grep ssh) i zakończ: kill PID lub pkill -f "ssh -L"
Laboratorium - tunel Local Forwarding
45/49
Troubleshooting - prawa dostępu do plików

Problemy z uprawnieniami ~/.ssh

  • Najczęstszy błąd: Permissions 0644 for 'id_ed25519' are too open - klucz prywatny ma zbyt otwarte prawa
  • Rozwiązanie: chmod 600 ~/.ssh/id_ed25519 - tylko właściciel może czytać i zapisywać klucz prywatny
  • Dla authorized_keys na serwerze: chmod 600 ~/.ssh/authorized_keys i chmod 700 ~/.ssh
  • Dla klucza publicznego: chmod 644 ~/.ssh/id_ed25519.pub - może być czytelny dla wszystkich
  • Zasada: klucz prywatny = 600, klucz publiczny = 644, authorized_keys = 600, .ssh = 700, config = 600
Troubleshooting - prawa dostępu do plików
46/49
Troubleshooting - known_hosts i MITM

Konflikt known_hosts i atak MITM

  • Problem: WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! - klucz serwera się zmienił
  • Przyczyny: reinstalacja systemu, podmiana serwera, atak MITM, regeneracja kluczy hosta
  • Rozwiązanie (jeśli zmiana była legalna): ssh-keygen -R nazwa-serwera - usuwa stary wpis z known_hosts
  • Alternatywnie: ręczne usunięcie linii z ~/.ssh/known_hosts odpowiadającej za stary klucz
  • Zapobieganie MITM: zawsze weryfikuj odcisk klucza serwera bezpiecznym kanałem (np. telefonicznie, przez komunikator szyfrowany)
Troubleshooting - known_hosts i MITM
47/49
Troubleshooting - inne typowe problemy

Inne częste problemy z SSH

  • Błąd: ssh: connect to host port 22: Connection refused - serwer nie nasłuchuje na tym porcie
  • Sprawdź: czy serwer SSH jest uruchomiony (systemctl status sshd), czy firewall nie blokuje portu, czy to właściwy port
  • Błąd: ssh: Could not resolve hostname - problem z DNS; sprawdź /etc/resolv.conf lub użyj adresu IP
  • Błąd: Permission denied (publickey,gssapi-keyex,gssapi-with-mic) - brak dostępu kluczem
  • Debugowanie: uruchom ssh z flagą -vvv i przeanalizuj output; sprawdź logi serwera w /var/log/auth.log
Troubleshooting - inne typowe problemy
48/49
Cheat Sheet - najważniejsze komendy SSH

Ściągawka poleceń SSH

  • Generowanie kluczy: ssh-keygen -t ed25519 -a 100 -C "email@example.com"
  • Kopiowanie klucza: ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
  • Logowanie z kluczem: ssh -i ~/.ssh/id_ed25519 -p 2222 user@server
  • Tunel lokalny: ssh -L 13306:127.0.0.1:3306 -Nf user@server
  • Tunel odwrotny: ssh -R 2222:127.0.0.1:22 -Nf user@public-server.com
  • Proxy SOCKS5: ssh -D 1080 -Nf user@server
  • Skok przez bastion: ssh -J user@bastion user@target
  • Debugowanie: ssh -vvv user@server
  • Usunięcie klucza hosta: ssh-keygen -R server.example.com
  • Sprawdzenie konfiguracji: sudo sshd -t
Cheat Sheet - najważniejsze komendy SSH
49/49
Zakończenie - podsumowanie i pytania

Podsumowanie wiedzy o SSH

  • Poznaliśmy trzy filary bezpiecznego zdalnego dostępu: kryptografię (RSA, ECDSA, Ed25519), hardening (sshd_config, PasswordAuthentication no, AllowGroups) i tunelowanie (-L, -R, -D)
  • Praktyczne laboratorium pokazało: generowanie kluczy, kopiowanie na serwer, konfigurację klienta, debugowanie i uruchamianie tuneli
  • Najważniejsze zasady: używaj Ed25519, wyłącz hasła, zablokuj roota, ogranicz grupy, zmień port
  • SSH Tunneling to potężne narzędzie - używaj go odpowiedzialnie i zawsze weryfikuj autentyczność serwerów
  • Dziękuję za uwagę! Pytania i dyskusja.
Zakończenie - podsumowanie i pytania