Hartowanie SSH w 2026: OpenSSH 10, kryptografia postkwantowa i klucze FIDO2

Praktyczny przewodnik po hartowaniu SSH w 2026 roku. Poznaj nowości w OpenSSH 10.x, konfigurację kryptografii postkwantowej (mlkem768x25519-sha256), uwierzytelnianie certyfikatami SSH i kluczami FIDO2, ochronę przed brute-force oraz audyt bezpieczeństwa.

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-sha256 stał 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-agent i sshd przeniesione z /tmp do ~/.ssh/agent. Dzięki temu procesy z dostępem do /tmp nie 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ę WarnWeakCrypto w ssh_config.
  • Dyrektywa RefuseConnection — nowa opcja w konfiguracji sshd pozwalają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 -r zostanie 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 sshd zawsze 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_keys na 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-pin dla YubiKey).
  • Etykietuj klucze — używaj opcji -O application=ssh:nazwa do 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

  1. Kryptografia postkwantowa
    • Zaktualizuj OpenSSH do wersji 10.x
    • Upewnij się, że mlkem768x25519-sha256 jest na liście KexAlgorithms
    • Włącz WarnWeakCrypto yes po stronie klienta
    • Zweryfikuj algorytmy postkwantowe za pomocą ssh-audit
  2. 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)
  3. Uwierzytelnianie
    • Wyłącz PasswordAuthentication
    • Wyłącz ChallengeResponseAuthentication
    • Ustaw PermitRootLogin no
    • Skonfiguruj AllowUsers lub AllowGroups
    • Rozważ wdrożenie certyfikatów SSH z krótkim TTL
    • Rozważ wdrożenie kluczy FIDO2 (ed25519-sk)
  4. 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
  5. Ograniczenia połączeń
    • Ustaw MaxAuthTries 3
    • Ustaw LoginGraceTime 30
    • Skonfiguruj ClientAliveInterval i ClientAliveCountMax
    • Ustaw odpowiednie wartości MaxStartups
  6. 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)
  7. Logowanie i audyt
    • Ustaw LogLevel VERBOSE
    • Skonfiguruj przesyłanie logów SSH do SIEM
    • Uruchamiaj ssh-audit po każdej zmianie konfiguracji
    • Wykonuj regularne audyty z Lynis
    • Zautomatyzuj raporty bezpieczeństwa
  8. 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

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.

O Autorze Editorial Team

Our team of expert writers and editors.