Wprowadzenie: Dlaczego bezpieczeństwo SSH ma krytyczne znaczenie w 2026 roku
SSH (Secure Shell) to absolutny fundament zdalnego zarządzania serwerami Linux — napędza ponad 90% obciążeń w chmurze publicznej, obsługuje miliony operacji DevOps dziennie i jest głównym punktem wejścia dla administratorów. Ale właśnie ta wszechobecność sprawia, że SSH jest jednocześnie jednym z ulubionych celów atakujących.
Statystyki z 2025 roku mówią same za siebie. Ataki brute-force na SSH to około 89% wszystkich zachowań atakujących na punktach końcowych systemów Linux. Przeciętny serwer z otwartym portem 22 doświadcza setek prób włamań dziennie — i to bez przesady. Zautomatyzowane botnety jak P2PInfect (odpowiedzialny za ponad 80% ataków w Q4 2025), Tsunami czy nowoodkryty SSHStalker (który skompromitował ponad 7000 serwerów Linux do końca stycznia 2026), skanują Internet z przemysłową prędkością, szukając słabo zabezpieczonych instancji SSH.
A to nie wszystko. Rok 2025 przyniósł rekordowe 5530 CVE w jądrze Linuxu — wzrost o 28% w porównaniu z 4329 CVE rok wcześniej. Grupy ransomware (Qilin, Kraken, RansomHub) wykorzystały luki w jądrze do ataku na ponad 700 organizacji w 62 krajach. Każda z tych podatności mogłaby posłużyć do eskalacji uprawnień po przejęciu sesji SSH.
W tym kontekście hartowanie SSH nie jest już opcjonalne — to absolutna konieczność. Na szczęście rok 2026 przynosi też dobre wieści: OpenSSH 10.x wprowadza domyślną kryptografię postkwantową, dojrzałe wsparcie dla kluczy sprzętowych FIDO2 oraz nowe mechanizmy ostrzegawcze. W tym artykule przeprowadzimy Cię przez kompleksowy proces zabezpieczania SSH — od algorytmów kryptograficznych, przez zarządzanie kluczami i certyfikatami, po ochronę przed brute-force i audyt.
Co nowego w OpenSSH 10.x
Rok 2025 był naprawdę intensywny jeśli chodzi o rozwój OpenSSH — trzy znaczące wydania, z których każde wzmocniło bezpieczeństwo protokołu w istotny sposób.
OpenSSH 10.0 (kwiecień 2025): Era kryptografii postkwantowej
To wydanie można śmiało nazwać kamieniem milowym. Najważniejsze zmiany:
- Domyślny algorytm wymiany kluczy postkwantowy — hybrydowy algorytm
mlkem768x25519-sha256stał się domyślną metodą uzgadniania kluczy. Łączy ML-KEM (standardyzowany przez NIST mechanizm enkapsulacji kluczy odporny na ataki komputerów kwantowych) z klasycznym X25519. Mówiąc prościej — chroni zarówno przed zagrożeniami kwantowymi, jak i tradycyjnymi. - Całkowite usunięcie DSA — po dekadzie deprecjacji (DSA było domyślnie wyłączone od 2015 roku), wsparcie dla tego algorytmu zostało definitywnie usunięte. Szczerze mówiąc, najwyższa pora.
- Separacja fazy uwierzytelniania — faza uwierzytelniania użytkownika przeniesiona do oddzielnego pliku binarnego
sshd-auth, co zmniejsza powierzchnię ataku i poprawia efektywność pamięci po uwierzytelnieniu. - Zmiana preferencji szyfrów — AES-GCM jest teraz preferowane nad AES-CTR. Domyślna lista preferencji: ChaCha20/Poly1305, AES-GCM (128/256), następnie AES-CTR (128/192/256).
OpenSSH 10.1 (październik 2025): Bezpieczeństwo agenta i ostrzeżenia PQ
Ta wersja wprowadziła kilka naprawdę istotnych zmian:
- Przeniesienie gniazda agenta SSH — gniazda Unix dla
ssh-agentisshdprzeniesione z/tmpdo~/.ssh/agent. Dzięki temu procesy z dostępem do/tmpnie mogą już wykorzystać kluczy w agencie. Agent zyskał też automatyczne czyszczenie nieaktywnych gniazd. - Naprawa wstrzyknięcia poleceń w ProxyCommand — załatano krytyczną podatność umożliwiającą wstrzyknięcie poleceń powłoki przez specjalne znaki w nazwach użytkowników lub URI używanych z
ProxyCommand. - Ostrzeżenia WarnWeakCrypto — nowa opcja wyświetlająca ostrzeżenie podczas negocjowania algorytmu wymiany kluczy, który nie jest odporny na ataki kwantowe. Sterowanie przez opcję
WarnWeakCryptowssh_config. - Dyrektywa RefuseConnection — nowa opcja w konfiguracji
sshdpozwalająca odrzucać połączenia z konfigurowalnymi komunikatami. - Usunięcie kluczy XMSS — eksperymentalne wsparcie dla kluczy XMSS zostało usunięte.
OpenSSH 10.2 (październik 2025): Poprawki stabilności
Wydane zaledwie cztery dni po 10.1 — to głównie łatki naprawcze:
- Naprawiono problem z obsługą terminala przy włączonym
ControlPersist, który powodował, że sesja stawała się niezdatna do użytku. - Poprawiono pobieranie kluczy z tokenów PKCS#11 w
ssh-keygen. - Naprawiono operacje podpisywania CA, gdy klucz CA jest przechowywany w
ssh-agent.
Uwaga: Nadchodzące wydania OpenSSH zapowiadają deprecjację rekordów SSHFP opartych na SHA-1. Domyślne zachowanie
ssh-keygen -rzostanie zmienione tak, aby generować wyłącznie rekordy SSHFP z algorytmem SHA-256.
Kryptografia postkwantowa w SSH
Jedno z najpoważniejszych długoterminowych zagrożeń dla SSH to perspektywa pojawienia się kryptograficznie istotnych komputerów kwantowych. Szacunki mówią o 5 do 20 lat — wielu ekspertów spodziewa się ich w połowie lat 2030-tych.
Zagrożenie „przechwyć teraz, odszyfruj później"
Brzmi jak science fiction, ale to realne zagrożenie. Atak typu „store now, decrypt later" polega na tym, że atakujący przechwytuje i zapisuje zaszyfrowany ruch SSH w nadziei, że w przyszłości — gdy uzyska dostęp do komputera kwantowego — będzie w stanie go odszyfrować.
To oznacza, że sesje SSH bez algorytmów postkwantowych mogą być narażone na ujawnienie, nawet jeśli dziś są nie do złamania. I właśnie dlatego migracja do kryptografii postkwantowej powinna rozpocząć się już teraz, a nie dopiero po pojawieniu się komputerów kwantowych.
Dostępne algorytmy postkwantowe
OpenSSH oferuje dwa hybrydowe algorytmy wymiany kluczy odporne na ataki kwantowe:
mlkem768x25519-sha256— domyślny od OpenSSH 10.0. Łączy ML-KEM (standardyzowany przez NIST w FIPS 203) z X25519. Szybszy od poprzedniego algorytmu postkwantowego i gwarantuje bezpieczeństwo nie niższe niż sam X25519.sntrup761x25519-sha512— dostępny od OpenSSH 9.0 (kwiecień 2022). Łączy NTRU Prime z X25519. Był pierwszym domyślnym algorytmem postkwantowym w OpenSSH.
Oba działają w modelu hybrydowym — nawet jeśli komponent postkwantowy zostałby złamany, klasyczny komponent (X25519) nadal zapewnia bezpieczeństwo na poziomie tradycyjnej kryptografii. To eleganckie podejście, bo w praktyce nic nie tracisz.
Konfiguracja kryptografii postkwantowej
Aby wymusić użycie algorytmów postkwantowych na serwerze, dodaj do pliku /etc/ssh/sshd_config:
# Wymuszenie postkwantowej wymiany kluczy
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,curve25519-sha256,[email protected]
Po stronie klienta, w pliku ~/.ssh/config lub /etc/ssh/ssh_config:
# Konfiguracja klienta SSH z priorytetem PQ
Host *
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,curve25519-sha256,[email protected]
WarnWeakCrypto yes
Uwaga: Jeśli łączysz się ze starszymi serwerami, które nie obsługują algorytmów postkwantowych, możesz otrzymać ostrzeżenie
WarnWeakCrypto. To sygnał, że warto zaktualizować serwer docelowy — albo przynajmniej świadomie zaakceptować ryzyko.
Kompleksowe hartowanie sshd_config
No dobra, przechodzimy do sedna — szczegółowa konfiguracja serwera SSH implementująca najlepsze praktyki bezpieczeństwa na rok 2026. Każda sekcja jest omówiona i uzasadniona, żebyś wiedział nie tylko co wpisać, ale też dlaczego.
Klucze hosta
Klucze hosta identyfikują serwer wobec klientów. Priorytetowo traktujemy Ed25519, a RSA używamy tylko jako zapasowy z minimalną długością 4096 bitów:
# Klucze hosta — priorytet Ed25519, RSA 4096 jako fallback
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
# Wymagaj minimalnej wielkości klucza RSA 3072 bitów
RequiredRSASize 3072
Regenerację kluczy hosta warto przeprowadzać okresowo lub po reinstalacji systemu:
# Regeneracja kluczy hosta
sudo rm /etc/ssh/ssh_host_*
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
sudo ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
sudo systemctl restart sshd
Algorytmy wymiany kluczy (KexAlgorithms)
Wybieramy wyłącznie algorytmy postkwantowe i nowoczesne algorytmy oparte na krzywych eliptycznych:
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,curve25519-sha256,[email protected],diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Szyfry (Ciphers)
Ograniczamy szyfry do najsilniejszych, uwzględniając zmienione priorytety OpenSSH 10.0:
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr
ChaCha20-Poly1305 jest preferowany ze względu na odporność na ataki czasowe. AES-GCM z kolei zapewnia świetną wydajność na procesorach z akceleracją sprzętową AES-NI (a tych jest dzisiaj zdecydowana większość).
Kody uwierzytelniania wiadomości (MACs)
Używamy wyłącznie wariantów Encrypt-then-MAC (ETM), które oferują znacznie lepsze bezpieczeństwo kryptograficzne niż warianty nie-ETM:
MACs [email protected],[email protected],[email protected]
Ważne: Szyfry pracujące w trybie AEAD (ChaCha20-Poly1305 oraz AES-GCM) mają wbudowane uwierzytelnianie wiadomości i nie korzystają z oddzielnych MAC. Dyrektywa MACs ma zastosowanie jedynie dla szyfrów nie-AEAD, takich jak AES-CTR.
Algorytmy kluczy hosta (HostKeyAlgorithms)
HostKeyAlgorithms [email protected],[email protected],ssh-ed25519,[email protected],[email protected],rsa-sha2-512,rsa-sha2-256
Ustawienia uwierzytelniania
Wyłączenie uwierzytelniania hasłem to jeden z najskuteczniejszych (i najprostszych!) sposobów ochrony przed atakami brute-force:
# Wyłącz uwierzytelnianie hasłem — klucze publiczne wyłącznie
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
UsePAM no
# Włącz uwierzytelnianie kluczem publicznym
PubkeyAuthentication yes
PubkeyAcceptedAlgorithms [email protected],[email protected],ssh-ed25519,[email protected],[email protected],rsa-sha2-512,rsa-sha2-256
# Wyłącz logowanie jako root
PermitRootLogin no
# Ogranicz dostęp do określonych użytkowników i grup
AllowUsers deploy monitoring
AllowGroups ssh-users
Ograniczenia połączeń i sesji
# Maksymalna liczba prób uwierzytelnienia
MaxAuthTries 3
# Czas oczekiwania na uwierzytelnienie (w sekundach)
LoginGraceTime 30
# Wykrywanie martwych połączeń
ClientAliveInterval 300
ClientAliveCountMax 2
# Ograniczenie równoczesnych nieuwierzytelnionych połączeń
MaxStartups 10:30:60
# Maksymalna liczba sesji na połączenie
MaxSessions 3
Logowanie i audyt
# Szczegółowe logowanie, w tym odciski kluczy
LogLevel VERBOSE
# Wyłącz niepotrzebne funkcje
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
PermitTunnel no
GatewayPorts no
PermitUserEnvironment no
DisableForwarding yes
# Wyświetl baner ostrzegawczy
Banner /etc/ssh/banner
Pełny przykład sshd_config
A teraz to, na co wielu z Was pewnie czekało — kompletny, hartowany plik konfiguracyjny serwera SSH gotowy do użycia w 2026 roku:
# /etc/ssh/sshd_config — hartowana konfiguracja 2026
# Wygenerowano dla OpenSSH 10.x
# ===== Protokół i klucze hosta =====
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
# ===== Algorytmy kryptograficzne =====
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,curve25519-sha256,[email protected],diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr
MACs [email protected],[email protected],[email protected]
HostKeyAlgorithms [email protected],[email protected],ssh-ed25519,[email protected],[email protected],rsa-sha2-512,rsa-sha2-256
RequiredRSASize 3072
# ===== Uwierzytelnianie =====
PubkeyAuthentication yes
PubkeyAcceptedAlgorithms [email protected],[email protected],ssh-ed25519,[email protected],[email protected],rsa-sha2-512,rsa-sha2-256
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
UsePAM no
PermitRootLogin no
AuthenticationMethods publickey
# ===== Kontrola dostępu =====
AllowGroups ssh-users
MaxAuthTries 3
LoginGraceTime 30
MaxStartups 10:30:60
MaxSessions 3
# ===== Utrzymanie sesji =====
ClientAliveInterval 300
ClientAliveCountMax 2
# ===== Logowanie =====
LogLevel VERBOSE
SyslogFacility AUTH
# ===== Ograniczenia funkcji =====
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
PermitTunnel no
GatewayPorts no
PermitUserEnvironment no
DisableForwarding yes
PrintMotd no
# ===== Baner =====
Banner /etc/ssh/banner
# ===== SFTP =====
Subsystem sftp /usr/libexec/openssh/sftp-server -f AUTHPRIV -l INFO
Po wprowadzeniu zmian koniecznie przetestuj konfigurację przed restartem:
# Walidacja składni konfiguracji
sudo sshd -t
# Restart usługi SSH (po walidacji)
sudo systemctl restart sshd
Ostrzeżenie: Przed restartem
sshdzawsze upewnij się, że masz aktywną sesję zapasową lub dostęp do konsoli. Mówię z doświadczenia — błąd w konfiguracji może skutecznie odciąć Ci dostęp do serwera.
Zarządzanie kluczami SSH — najlepsze praktyki
Klucze kryptograficzne to fundament uwierzytelniania SSH. Ich prawidłowe generowanie, przechowywanie i rotacja mają bezpośredni wpływ na bezpieczeństwo całej infrastruktury.
Generowanie kluczy — Ed25519 jako priorytet
Ed25519 to preferowany algorytm w 2026 roku — wysokie bezpieczeństwo, małe rozmiary kluczy (256 bitów) i świetna szybkość operacji. Ciężko znaleźć powód, żeby go nie używać (chyba że musisz wspierać naprawdę stare systemy):
# Generowanie klucza Ed25519 z 100 rundami KDF
ssh-keygen -t ed25519 -a 100 -C "[email protected]"
# Opcjonalnie: RSA 4096 jako fallback dla starszych systemów
ssh-keygen -t rsa -b 4096 -a 100 -C "[email protected]"
Parametr -a 100 zwiększa liczbę rund KDF (Key Derivation Function) przy szyfrowaniu klucza prywatnego hasłem. W praktyce oznacza to, że ataki brute-force na plik klucza stają się znacznie wolniejsze — a tym samym mniej opłacalne dla atakującego.
Ochrona klucza prywatnego
Zawsze ustawiaj silne hasło na kluczu prywatnym. I zabezpiecz uprawnienia plików — to banalnie proste, a zaskakująco często pomijane:
# Ustaw restrykcyjne uprawnienia
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/authorized_keys
Polityka rotacji kluczy
Regularna rotacja kluczy SSH jest kluczowa, choć — bądźmy szczerzy — często zaniedbywana. Oto rekomendowane praktyki:
- Klucze użytkowników — rotacja co 6-12 miesięcy, lub natychmiast po podejrzeniu kompromitacji.
- Klucze hosta — rotacja po reinstalacji systemu, aktualizacji głównej wersji SSH lub podejrzeniu naruszenia.
- Klucze kont serwisowych — rotacja co 3-6 miesięcy, z wykorzystaniem zautomatyzowanych narzędzi.
- Audyt authorized_keys — regularne przeglądanie plików
authorized_keysna serwerach, usuwanie nieużywanych lub nieznanych kluczy. Zdziwilibyście się, ile „zapomnianych" kluczy można tam znaleźć po kilku latach.
Bezpieczeństwo ssh-agent
Agent SSH przechowuje odszyfrowane klucze prywatne w pamięci — co jest wygodne, ale stanowi potencjalny wektor ataku. Warto zatem stosować kilka prostych zabezpieczeń:
# Ogranicz czas życia kluczy w agencie do 4 godzin
ssh-add -t 14400 ~/.ssh/id_ed25519
# Weryfikacja załadowanych kluczy
ssh-add -l
# Usunięcie wszystkich kluczy z agenta po zakończeniu pracy
ssh-add -D
W OpenSSH 10.1 gniazdo agenta przeniesiono z /tmp do ~/.ssh/agent, co znacząco poprawia bezpieczeństwo. Jeśli korzystasz ze starszych wersji, rozważ ręczne wskazanie bezpieczniejszej lokalizacji:
# Uruchomienie agenta z niestandardową lokalizacją gniazda (starsze wersje)
mkdir -p ~/.ssh/agent
ssh-agent -a ~/.ssh/agent/agent.sock
Uwierzytelnianie oparte na certyfikatach SSH
Certyfikaty SSH to potężna (i moim zdaniem niedoceniana) alternatywa dla tradycyjnego uwierzytelniania kluczem publicznym. Zamiast dystrybuować klucze publiczne do pliku authorized_keys na każdym serwerze, serwery ufają Centrum Certyfikacji (CA), które podpisuje klucze użytkowników.
Zalety certyfikatów nad zwykłymi kluczami
- Eliminacja zarządzania authorized_keys — nie trzeba kopiować kluczy publicznych na każdy serwer. Przy większej infrastrukturze to ogromna oszczędność czasu.
- Ograniczony czas życia — certyfikaty mogą wygasać po minutach lub godzinach, radykalnie zmniejszając okno ataku.
- Kontrola tożsamości — certyfikaty zawierają „principals" (nazwy tożsamości), określające, do jakich kont ma dostęp posiadacz.
- Centralne zarządzanie — CA może natychmiast unieważnić dostęp, generując listę odwołanych kluczy (KRL).
- Audytowalność — podpisywanie certyfikatów przez CA tworzy centralny dziennik audytu.
Tworzenie Centrum Certyfikacji SSH
# Generowanie klucza CA dla użytkowników
ssh-keygen -t ed25519 -f /etc/ssh/ca/user_ca -C "SSH User CA"
# Generowanie klucza CA dla hostów
ssh-keygen -t ed25519 -f /etc/ssh/ca/host_ca -C "SSH Host CA"
# Zabezpieczenie kluczy CA
chmod 400 /etc/ssh/ca/user_ca /etc/ssh/ca/host_ca
Podpisywanie certyfikatów użytkowników
# Podpisanie klucza użytkownika z certyfikatem ważnym 8 godzin
ssh-keygen -s /etc/ssh/ca/user_ca \
-I "[email protected]" \
-n deploy,monitoring \
-V +8h \
-z 1001 \
/home/jan/.ssh/id_ed25519.pub
Wyjaśnienie parametrów:
-s— ścieżka do klucza CA (podpisujący)-I— identyfikator certyfikatu (do celów audytu)-n— lista principals (użytkowników docelowych)-V +8h— ważność certyfikatu (8 godzin)-z— numer seryjny certyfikatu
Podpisywanie certyfikatów hostów
# Podpisanie klucza hosta
ssh-keygen -s /etc/ssh/ca/host_ca \
-I "serwer-produkcyjny-01" \
-h \
-n serwer01.firma.pl,192.168.1.10 \
-V +52w \
/etc/ssh/ssh_host_ed25519_key.pub
Konfiguracja serwera do akceptowania certyfikatów
# W /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/ca/user_ca.pub
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u
# Opcjonalnie: lista odwołanych kluczy/certyfikatów
RevokedKeys /etc/ssh/ca/revoked_keys
Następnie utwórz pliki principals dla każdego użytkownika:
# Utwórz katalog principals
sudo mkdir -p /etc/ssh/auth_principals
# Dla użytkownika 'deploy':
echo "deploy" | sudo tee /etc/ssh/auth_principals/deploy
# Dla użytkownika 'monitoring':
echo "monitoring" | sudo tee /etc/ssh/auth_principals/monitoring
Konfiguracja klienta do weryfikacji certyfikatów hostów
# W ~/.ssh/known_hosts lub /etc/ssh/ssh_known_hosts
@cert-authority *.firma.pl ssh-ed25519 AAAAC3... (zawartość host_ca.pub)
Integracja z HashiCorp Vault
Jeśli zarządzasz dziesiątkami lub setkami serwerów, ręczne podpisywanie certyfikatów szybko staje się niepraktyczne. Tu z pomocą przychodzi HashiCorp Vault, który może pełnić rolę zautomatyzowanego CA SSH, generując krótkotrwałe certyfikaty na żądanie:
# Włączenie silnika sekretów SSH w Vault
vault secrets enable -path=ssh-client-signer ssh
# Konfiguracja CA
vault write ssh-client-signer/config/ca generate_signing_key=true
# Pobranie klucza publicznego CA
vault read -field=public_key ssh-client-signer/config/ca > /etc/ssh/trusted-user-ca-keys.pem
# Utworzenie roli z TTL 30 minut
vault write ssh-client-signer/roles/admin-role - <<EOF
{
"allow_user_certificates": true,
"allowed_users": "deploy,admin",
"allowed_extensions": "permit-pty,permit-port-forwarding",
"default_extensions": [{"permit-pty": ""}],
"key_type": "ca",
"default_user": "deploy",
"ttl": "30m0s",
"max_ttl": "2h"
}
EOF
# Podpisanie klucza użytkownika (z poziomu klienta)
vault write ssh-client-signer/sign/admin-role \
public_key=@$HOME/.ssh/id_ed25519.pub
Dzięki Vault certyfikaty SSH są generowane automatycznie, mają krótki czas życia i są powiązane z politykami dostępu. To naprawdę idealne rozwiązanie dla większych organizacji.
Uwierzytelnianie kluczami sprzętowymi FIDO2/U2F
Klucze sprzętowe FIDO2 (YubiKey, SoloKeys, Token2) dodają fizyczną warstwę bezpieczeństwa do uwierzytelniania SSH. Nawet jeśli atakujący uzyska pełen dostęp do komputera użytkownika, nie uwierzytelni się bez fizycznego posiadania klucza sprzętowego. To prosta zasada, ale niesamowicie skuteczna.
Typy kluczy FIDO2 w SSH
OpenSSH obsługuje dwa typy kluczy opartych na FIDO2 (przyrostek -sk oznacza „security key"):
ed25519-sk— preferowany typ, oparty na krzywej Curve25519. Wymaga YubiKey z firmware 5.2.3+. Oferuje lepsze bezpieczeństwo i wydajność niż ECDSA.ecdsa-sk— oparty na NIST P-256. Kompatybilny z większą liczbą kluczy sprzętowych FIDO2, w tym starszymi modelami.
Generowanie klucza FIDO2
# Preferowany: Ed25519-SK z kluczem rezydentnym i weryfikacją PIN
ssh-keygen -t ed25519-sk -O resident -O verify-required -C "[email protected]"
# Fallback: ECDSA-SK dla starszych kluczy sprzętowych
ssh-keygen -t ecdsa-sk -O resident -O verify-required -C "[email protected]"
# Klucz z etykietą aplikacji (gdy przechowujesz wiele kluczy SSH)
ssh-keygen -t ed25519-sk -O resident -O verify-required \
-O application=ssh:serwer-produkcyjny -C "[email protected]"
Klucze rezydentne — przenośność między maszynami
Klucz rezydentny (-O resident) jest przechowywany bezpośrednio na urządzeniu FIDO2. To oznacza, że możesz go odtworzyć na dowolnym komputerze — wystarczy podłączyć klucz:
# Odtworzenie kluczy rezydentnych z urządzenia FIDO2 na nowej maszynie
ssh-keygen -K
# Powyższe polecenie zapisze klucze do bieżącego katalogu:
# id_ed25519_sk_rk (klucz prywatny — uchwyt)
# id_ed25519_sk_rk.pub (klucz publiczny)
PIN i weryfikacja użytkownika
Opcja -O verify-required wymusza zarówno wprowadzenie kodu PIN, jak i fizyczne dotknięcie klucza sprzętowego przy każdym użyciu. To daje Ci prawdziwe dwuskładnikowe uwierzytelnianie sprzętowe:
- Coś, co masz — fizyczny klucz sprzętowy FIDO2
- Coś, co znasz — kod PIN urządzenia
Uwaga dotycząca macOS: System macOS (od wersji Sonoma / macOS 14) ma wbudowane wsparcie FIDO2 w SSH, ale jest ono niekompletne. Z doświadczenia polecam instalację OpenSSH przez Homebrew:
brew install openssh.
Najlepsze praktyki dla kluczy FIDO2
- Klucz zapasowy — zawsze rejestruj co najmniej dwa klucze sprzętowe. Jeden przechowuj w bezpiecznym miejscu jako kopię zapasową (serio, nie oszczędzaj na tym — utrata jedynego klucza FIDO2 to spory problem).
- Ustaw PIN — przed wygenerowaniem kluczy SSH ustaw PIN na urządzeniu FIDO2 za pomocą narzędzia producenta (np.
ykman fido access change-pindla YubiKey). - Etykietuj klucze — używaj opcji
-O application=ssh:nazwado rozróżniania kluczy, gdy masz ich wiele na jednym urządzeniu. - Testuj przed wyłączeniem hasła — przetestuj logowanie kluczem FIDO2 przed wyłączeniem uwierzytelniania hasłem na serwerze. To powinno być oczywiste, ale warto to podkreślić.
Ochrona przed atakami brute-force
Nawet po wyłączeniu uwierzytelniania hasłem, ataki brute-force nadal generują obciążenie serwera i zaśmiecają logi. Warto zatem wdrożyć dodatkowe warstwy ochrony — choćby dla własnego spokoju i czystości logów.
Fail2Ban — konfiguracja dla SSH
Fail2Ban monitoruje logi systemowe i automatycznie blokuje adresy IP po wykryciu powtarzających się nieudanych prób logowania. To jedno z tych narzędzi, które po prostu powinno być na każdym serwerze:
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 3
findtime = 600
bantime = 3600
banaction = nftables-multiport
ignoreip = 127.0.0.1/8 10.0.0.0/8
# Blokada na 24h po 5 próbach w ciągu godziny (recydywiści)
[sshd-aggressive]
enabled = true
port = ssh
filter = sshd[mode=aggressive]
backend = systemd
maxretry = 5
findtime = 3600
bantime = 86400
banaction = nftables-multiport
Uruchomienie i weryfikacja Fail2Ban:
# Restart Fail2Ban po zmianach konfiguracji
sudo systemctl restart fail2ban
# Sprawdzenie statusu jail-a SSH
sudo fail2ban-client status sshd
# Lista zbanowanych adresów IP
sudo fail2ban-client get sshd banip --with-time
sshguard jako alternatywa
Jeśli Fail2Ban wydaje Ci się zbyt rozbudowany, sshguard to lekka alternatywa, która nie wymaga wyrażeń regularnych do parsowania logów — automatycznie rozpoznaje format logów wielu usług:
# Instalacja na Debian/Ubuntu
sudo apt install sshguard
# Instalacja na RHEL/CentOS/Fedora
sudo dnf install sshguard
Konfiguracja sshguard z nftables:
# /etc/sshguard/sshguard.conf
BACKEND="/usr/libexec/sshguard/sshg-fw-nft-sets"
LOGREADER="LANG=C /usr/bin/journalctl -afb -p info -n1 -t sshd -o cat"
THRESHOLD=30
BLOCK_TIME=120
DETECTION_TIME=1800
BLACKLIST_FILE=120:/etc/sshguard/blacklist.db
Limitowanie połączeń z nftables
Nftables (następca iptables) pozwala ograniczyć liczbę nowych połączeń SSH bezpośrednio na poziomie zapory sieciowej. To najszybsza warstwa obrony, bo działa zanim ruch dotrze do procesu sshd:
#!/usr/sbin/nft -f
# /etc/nftables.d/ssh-ratelimit.nft
table inet ssh_filter {
set ssh_meter {
type ipv4_addr
flags dynamic,timeout
timeout 60s
}
chain input {
type filter hook input priority 0; policy accept;
# Ogranicz nowe połączenia SSH do 4 na minutę z jednego IP
tcp dport 22 ct state new \
add @ssh_meter { ip saddr limit rate 4/minute burst 6 packets } \
accept
# Odrzucaj nadmiarowe połączenia
tcp dport 22 ct state new counter drop
}
}
Dla środowisk nadal korzystających z iptables:
# Ograniczenie nowych połączeń SSH z iptables
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
Audyt i monitoring SSH
Hartowanie SSH to nie jednorazowa czynność — to ciągły proces wymagający regularnego monitoringu i audytów konfiguracji. Oto narzędzia i techniki, które powinny być w Twoim arsenale.
ssh-audit — kompleksowy audyt konfiguracji
Narzędzie ssh-audit analizuje konfigurację serwera SSH i identyfikuje słabe algorytmy, przestarzałe ustawienia i potencjalne podatności. Jeśli jeszcze go nie znasz, zdecydowanie warto zainstalować:
# Instalacja ssh-audit
pip install ssh-audit
# Audyt zdalnego serwera
ssh-audit serwer.firma.pl
# Audyt serwera na niestandardowym porcie
ssh-audit serwer.firma.pl:2222
# Audyt polityki — weryfikacja zgodności z wymaganymi standardami
ssh-audit --policy=hardened serwer.firma.pl
# Audyt konfiguracji klienta
ssh-audit --client-audit
ssh-audit wyświetla szczegółowe informacje o algorytmach wymiany kluczy, szyfrach, MAC i algorytmach kluczy hosta. Te bezpieczne oznacza na zielono, słabe na żółto, a do natychmiastowego usunięcia na czerwono. W kontekście 2026 roku zwróć szczególną uwagę na obecność algorytmów postkwantowych (mlkem768x25519-sha256 lub sntrup761x25519-sha512) w wynikach.
Analiza logów SSH
Regularna analiza logów SSH pozwala wyłapać podejrzane aktywności zanim przerodzą się w poważny incydent. Oto kilka przydatnych zapytań:
# Wyświetl nieudane próby logowania z ostatnich 24 godzin
journalctl -u sshd --since "24 hours ago" | grep "Failed"
# Wyświetl udane logowania
journalctl -u sshd --since "24 hours ago" | grep "Accepted"
# Statystyki nieudanych prób według adresu IP
journalctl -u sshd --since "7 days ago" \
| grep "Failed password" \
| awk '{print $(NF-3)}' \
| sort | uniq -c | sort -rn | head -20
# Wykryj logowania z nietypowych kluczy
journalctl -u sshd --since "24 hours ago" | grep "Accepted publickey" \
| awk '{print $9, $11, $NF}'
Integracja z systemami SIEM
Logi SSH powinny trafiać do centralnego systemu SIEM (Security Information and Event Management) w celu korelacji z innymi źródłami danych bezpieczeństwa. Konfiguracja przesyłania logów za pomocą rsyslog:
# /etc/rsyslog.d/50-ssh-siem.conf
# Przesyłanie logów SSH do serwera SIEM
if $programname == 'sshd' then {
action(type="omfwd"
target="siem.firma.pl"
port="514"
protocol="tcp"
template="RSYSLOG_SyslogProtocol23Format"
)
}
Alternatywnie, z użyciem formatu JSON (znacznie wygodniejszy do przetwarzania):
# /etc/rsyslog.d/50-ssh-json.conf
template(name="ssh-json" type="list") {
constant(value="{")
constant(value="\"timestamp\":\"") property(name="timereported" dateFormat="rfc3339")
constant(value="\",\"host\":\"") property(name="hostname")
constant(value="\",\"program\":\"") property(name="programname")
constant(value="\",\"message\":\"") property(name="msg" format="json")
constant(value="\"}\n")
}
if $programname == 'sshd' then {
action(type="omfile" file="/var/log/ssh-audit.json" template="ssh-json")
}
Audyt bezpieczeństwa z Lynis
Lynis to wszechstronne narzędzie do audytu bezpieczeństwa systemów Linux, które zawiera kompleksowe testy konfiguracji SSH:
# Instalacja Lynis
sudo apt install lynis # Debian/Ubuntu
sudo dnf install lynis # RHEL/Fedora
# Uruchomienie pełnego audytu
sudo lynis audit system
# Audyt samego SSH
sudo lynis audit system --tests-from-group "ssh"
# Wyświetlenie sugestii dotyczących SSH
sudo lynis show details SSH-7408
Lynis sprawdza między innymi:
- Czy uwierzytelnianie hasłem jest wyłączone
- Czy logowanie root jest zablokowane
- Czy używane są silne algorytmy kryptograficzne
- Czy ustawiono odpowiednie limity czasowe i liczby prób
- Czy uprawnienia plików konfiguracyjnych SSH są prawidłowe
- Czy włączono szczegółowe logowanie
Automatyzacja audytu — skrypt cyklicznego sprawdzania
Warto zautomatyzować regularne audyty SSH. Poniższy skrypt możesz uruchamiać przez crona — nic skomplikowanego, ale daje spokój ducha:
#!/bin/bash
# /usr/local/bin/ssh-security-check.sh
# Cykliczny audyt bezpieczeństwa SSH
REPORT="/var/log/ssh-security-audit-$(date +%Y%m%d).log"
ADMIN_EMAIL="[email protected]"
echo "=== Audyt bezpieczeństwa SSH — $(date) ===" > "$REPORT"
# Sprawdzenie wersji OpenSSH
echo -e "\n--- Wersja OpenSSH ---" >> "$REPORT"
sshd -V 2>&1 >> "$REPORT"
# Sprawdzenie konfiguracji
echo -e "\n--- Walidacja sshd_config ---" >> "$REPORT"
sshd -t 2>&1 >> "$REPORT"
# Sprawdzenie uprawnień plików
echo -e "\n--- Uprawnienia plików SSH ---" >> "$REPORT"
ls -la /etc/ssh/ssh_host_*_key 2>&1 >> "$REPORT"
stat -c "%a %U %G %n" /etc/ssh/sshd_config >> "$REPORT"
# Sprawdzenie aktywnych sesji
echo -e "\n--- Aktywne sesje SSH ---" >> "$REPORT"
who | grep pts >> "$REPORT"
# Sprawdzenie nieudanych prób logowania (ostatnie 24h)
echo -e "\n--- Nieudane próby logowania (24h) ---" >> "$REPORT"
journalctl -u sshd --since "24 hours ago" 2>/dev/null \
| grep -c "Failed" >> "$REPORT"
# Wysyłka raportu
mail -s "Raport audytu SSH — $(hostname)" "$ADMIN_EMAIL" < "$REPORT"
# Dodanie do crontab — uruchamianie codziennie o 6:00
echo "0 6 * * * /usr/local/bin/ssh-security-check.sh" | sudo crontab -
Podsumowanie i lista kontrolna bezpieczeństwa SSH
Hartowanie SSH w 2026 roku wymaga podejścia wielowarstwowego — nowoczesna kryptografia, rygorystyczna kontrola dostępu, sprzętowe uwierzytelnianie i ciągły monitoring. Poniżej znajdziesz kompletną listę kontrolną, którą warto przejść punkt po punkcie w swojej infrastrukturze.
Lista kontrolna hartowania SSH na 2026 rok
- Kryptografia postkwantowa
- Zaktualizuj OpenSSH do wersji 10.x
- Upewnij się, że
mlkem768x25519-sha256jest na liście KexAlgorithms - Włącz
WarnWeakCrypto yespo stronie klienta - Zweryfikuj algorytmy postkwantowe za pomocą
ssh-audit
- Klucze hosta i szyfry
- Używaj Ed25519 jako głównego klucza hosta
- Ustaw
RequiredRSASize 3072(minimum) - Ogranicz szyfry do ChaCha20-Poly1305 i AES-GCM/AES-CTR
- Używaj wyłącznie wariantów MAC typu ETM
- Usuń klucze hosta DSA i ECDSA (opcjonalnie)
- Uwierzytelnianie
- Wyłącz
PasswordAuthentication - Wyłącz
ChallengeResponseAuthentication - Ustaw
PermitRootLogin no - Skonfiguruj
AllowUserslubAllowGroups - Rozważ wdrożenie certyfikatów SSH z krótkim TTL
- Rozważ wdrożenie kluczy FIDO2 (
ed25519-sk)
- Wyłącz
- Klucze użytkowników
- Generuj klucze Ed25519 z
-a 100 - Zawsze ustawiaj silne hasło na kluczu prywatnym
- Wdróż politykę rotacji kluczy (6-12 miesięcy)
- Regularnie audytuj pliki
authorized_keys - Ogranicz czas życia kluczy w
ssh-agent
- Generuj klucze Ed25519 z
- Ograniczenia połączeń
- Ustaw
MaxAuthTries 3 - Ustaw
LoginGraceTime 30 - Skonfiguruj
ClientAliveIntervaliClientAliveCountMax - Ustaw odpowiednie wartości
MaxStartups
- Ustaw
- Ochrona przed brute-force
- Wdróż Fail2Ban lub sshguard
- Skonfiguruj limitowanie połączeń w nftables/iptables
- Rozważ przeniesienie SSH na niestandardowy port (dodatkowa, nie główna, warstwa ochrony)
- Logowanie i audyt
- Ustaw
LogLevel VERBOSE - Skonfiguruj przesyłanie logów SSH do SIEM
- Uruchamiaj
ssh-auditpo każdej zmianie konfiguracji - Wykonuj regularne audyty z Lynis
- Zautomatyzuj raporty bezpieczeństwa
- Ustaw
- Ograniczanie funkcji
- Wyłącz
X11Forwarding(jeśli niepotrzebne) - Wyłącz
AllowTcpForwarding(jeśli niepotrzebne) - Wyłącz
AllowAgentForwarding(jeśli niepotrzebne) - Wyłącz
PermitTunnel - Ustaw
PermitUserEnvironment no
- Wyłącz
Bezpieczeństwo SSH w 2026 roku to nieustanna ewolucja. Zagrożenia takie jak ataki postkwantowe typu „przechwyć teraz, odszyfruj później", wyrafinowane botnety i rosnąca liczba podatności w jądrze Linuxu wymagają od nas proaktywnego podejścia. Wdrożenie opisanych w tym artykule praktyk — od kryptografii postkwantowej, przez certyfikaty SSH i klucze FIDO2, po zaawansowany monitoring — zapewni solidną ochronę Twojej infrastruktury. Ale pamiętaj: najlepsza konfiguracja jest bezwartościowa, jeśli nie jest regularnie audytowana i aktualizowana. Hartowanie SSH to ciągły proces, nie jednorazowe zadanie.