Konfiguracja kluczy SSH i wyłączenie uwierzytelniania hasłem to jedna z najważniejszych praktyk bezpieczeństwa na serwerach Linux, ponieważ znacząco ogranicza skuteczność ataków brute force przy zachowaniu bezpiecznego, zdalnego dostępu. Uwierzytelnianie kluczami kryptograficznymi wymaga wygenerowania pary kluczy, wdrożenia klucza publicznego na serwerach zdalnych oraz odpowiedniej konfiguracji demona SSH tak, aby odrzucał próby logowania hasłem. Ten artykuł prowadzi przez cały proces — od generowania kluczy, przez twardnienie konfiguracji serwera i poprawne uprawnienia plików, po typowe problemy i zaawansowane środki bezpieczeństwa, które administratorzy systemów Linux powinni znać, aby chronić swoją infrastrukturę.
Zrozumienie metod uwierzytelniania SSH i ich implikacji bezpieczeństwa
SSH (Secure Shell) zapewnia szyfrowaną komunikację między klientem a serwerem w sieciach potencjalnie niezaufanych. Obsługuje różne mechanizmy uwierzytelniania, z których najczęstsze to uwierzytelnianie hasłem oraz kluczem publicznym. Uwierzytelnianie hasłem wymaga wprowadzania danych przy każdym połączeniu, co naraża systemy na ataki brute force polegające na automatycznym zgadywaniu haseł. Uwierzytelnianie kluczem publicznym nie przesyła haseł w sieci i opiera się na parze kluczy: prywatnym (bezpiecznie przechowywanym u użytkownika) i publicznym (zapisanym na serwerze).
Przewaga bezpieczeństwa wynika z właściwości kryptografii klucza publicznego. W przeciwieństwie do haseł narażonych na ataki słownikowe, klucze kryptograficzne mają siłę opartą na trudnościach obliczeniowych i losowości, co czyni nieautoryzowany dostęp praktycznie niewykonalnym. Klient dowodzi posiadania klucza prywatnego bez jego wysyłania, a serwer weryfikuje to na podstawie klucza w pliku authorized_keys. Ta fundamentalna różnica sprawia, że dostęp oparty o klucze jest wielokrotnie bezpieczniejszy od haseł — szczególnie na systemach wystawionych do internetu.
Choć silne hasła nie są z natury niebezpieczne, klucze SSH oferują znacznie lepszą ochronę przed najczęstszymi wektorami ataku na usługi SSH. Dostawcy chmury (np. Google Cloud, AWS) domyślnie wyłączają logowanie hasłem, wymuszając użycie kluczy. Nowoczesne platformy, takie jak GitHub i GitLab, również rekomendują lub wymagają uwierzytelniania kluczami przy dostępie do repozytoriów.
W skrócie, najważniejsze korzyści uwierzytelniania kluczami to:
- brak przesyłania haseł w sieci,
- znacznie wyższa odporność na ataki brute force,
- łatwiejsze i bezpieczniejsze zarządzanie dostępami,
- możliwość wymuszenia silnych polityk (rotacja, ograniczenia per host),
- lepsza audytowalność oraz integracja z narzędziami DevOps.
Generowanie par kluczy SSH – algorytmy i implementacja
Pierwszym krokiem jest wygenerowanie pary kluczy narzędziem ssh-keygen (część pakietu OpenSSH). Domyślnie powstają pliki klucza prywatnego i publicznego w katalogu ~/.ssh. Aktualnie rekomendowanym algorytmem do SSH jest Ed25519 ze względu na bardzo dobry poziom bezpieczeństwa, mniejsze rozmiary kluczy i wyższą wydajność. Narzędzie obsługuje też RSA, które pozostaje szeroko wspierane.
Wybór algorytmu: RSA jest standardem od lat i wymaga co najmniej 2048 bitów (zalecane 4096 bitów), natomiast Ed25519 (kryptografia krzywych eliptycznych) zapewnia bezpieczeństwo porównywalne do wielotysięcznobitowego RSA przy znacznie mniejszych kluczach i szybszych operacjach. Klucze Ed25519 są też bardziej odporne na problemy z generatorami liczb losowych.
Dla szybkiego porównania algorytmów zobacz zestawienie:
| Algorytm | Zalecane parametry | Wydajność | Siła kryptograficzna | Kompatybilność |
|---|---|---|---|---|
| Ed25519 | domyślne | wysoka | wysoka (przy bardzo małych kluczach) | dobre wsparcie w nowoczesnych systemach |
| RSA | 4096 bitów | średnia | wysoka (przy długich kluczach) | najszersza zgodność, także ze starszymi systemami |
Aby wygenerować klucz Ed25519 zgodnie z dobrymi praktykami, użyj:
ssh-keygen -t ed25519 -C "[email protected]"
Alternatywnie, jeśli Ed25519 nie jest dostępny, RSA (z silną długością klucza):
ssh-keygen -t rsa -b 4096 -C "[email protected]"
Podczas generowania podaj lokalizację pliku i opcjonalne hasło do klucza prywatnego. Zawsze stosuj hasło do klucza prywatnego — jeśli urządzenie zostanie przejęte, zaszyfrowany klucz pozostanie bezużyteczny bez hasła. Po zakończeniu ssh-keygen pokaże odcisk palca (fingerprint) i „randomart”.
Wdrażanie kluczy publicznych na serwerach zdalnych – metody i procedury
Po wygenerowaniu pary kluczy należy zainstalować klucz publiczny na każdym serwerze docelowym. Klucz publiczny można bezpiecznie dystrybuować; tylko klucz prywatny wymaga ścisłej ochrony.
Najprościej użyć narzędzia ssh-copy-id (gdy na serwerze wciąż działa logowanie hasłem). Automatycznie dopisze ono klucz do pliku ~/.ssh/authorized_keys i nada właściwe uprawnienia:
ssh-copy-id -i ~/.ssh/id_ed25519 username@remote_host
Gdy logowanie hasłem jest już wyłączone lub masz tylko konsolę, wdrożenie wykonaj ręcznie: skopiuj zawartość pliku .pub i dopisuj ją w jednej linii do ~/.ssh/authorized_keys (jeden klucz na linię). Każdy wpis zawiera typ klucza (np. ssh-ed25519), dane klucza i ewentualny komentarz.
Przykład zawartości authorized_keys:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... entire key data ...jXvq user@workstation
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQD... entire key data ...FF488hBOk2ebpo38fHPPK1/rsOEKX9Kp9QWH user@laptop
Alternatywą dla ssh-copy-id jest bezpośrednie przesłanie klucza przez SSH i cat:
cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Powyższe polecenie tworzy katalog .ssh (jeśli go brak) i dopisuje klucz bez nadpisywania istniejących wpisów.
Zrozumienie struktury katalogów SSH i uprawnień do plików
Podsystem SSH w Linuxie wymaga ściśle określonych uprawnień do katalogu ~/.ssh i plików w nim zawartych. Funkcja StrictModes w OpenSSH weryfikuje te uprawnienia przed dopuszczeniem uwierzytelniania — zbyt liberalne ustawienia skutkują komunikatami typu „Authentication refused: bad ownership or modes for directory”.
Wymagane ustawienia uprawnień przedstawiają się następująco:
- ~/.ssh – tryb 700 (drwx——);
- ~/.ssh/id_ed25519 – klucz prywatny: tryb 600 (-rw——-);
- ~/.ssh/id_ed25519.pub – klucz publiczny: tryb 644 (często zaleca się 600);
- ~/.ssh/authorized_keys – na serwerze: tryb 600.
Pliki konfiguracyjne, takie jak config i known_hosts, również powinny mieć tryb 600. Katalog domowy użytkownika nie może być zapisywalny przez grupę/others (zwykle 755). Przykładowe komendy:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
chmod go-w ~
Jeśli mimo to pojawiają się błędy, upewnij się, że plik klucza prywatnego kończy się znakiem nowej linii.
Konfiguracja serwera SSH dla uwierzytelniania kluczem publicznym
Główny plik konfiguracyjny demona OpenSSH to /etc/ssh/sshd_config. Przed zmianami wykonaj kopię zapasową:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Aby włączyć logowanie kluczem i wyłączyć hasła, ustaw odpowiednie dyrektywy: PubkeyAuthentication yes oraz PasswordAuthentication no. Domyślna lokalizacja kluczy autoryzowanych to ~/.ssh/authorized_keys (dyrektywa AuthorizedKeysFile).
Zalecana konfiguracja, która akceptuje wyłącznie klucze:
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
Ogranicz liczbę prób uwierzytelniania dyrektywą MaxAuthTries (np. 3–4) i skróć LoginGraceTime (np. do 60 s), aby utrudnić nadużycia.
Zweryfikuj poprawność składni przed restartem usługi:
sudo sshd -T -f /etc/ssh/sshd_config
Wyłączanie uwierzytelniania hasłem – konfiguracja i wdrożenie
Przejście na wyłącznie klucze wykonuj etapami. Edytuj /etc/ssh/sshd_config i ustaw: PasswordAuthentication no oraz ChallengeResponseAuthentication no. W niektórych dystrybucjach dla pełnego zablokowania haseł konieczne może być wyłączenie PAM: UsePAM no (stosuj ostrożnie i świadomie, bo wpływa to na inne mechanizmy uwierzytelniania).
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
Zastosuj zmiany przez restart demona:
sudo systemctl restart sshd
Na starszych systemach użyj jednego z poleceń:
/etc/init.d/sshd restart
sudo service sshd restart
Nigdy nie zamykaj bieżącej sesji SSH, zanim w drugim oknie nie potwierdzisz, że logowanie kluczem działa poprawnie. W razie blokady użyj konsoli dostawcy, zresetuj hasło roota przez panel lub tymczasowo włącz hasła z poziomu konsoli.
Wyłączanie logowania root dla większego bezpieczeństwa
Ograniczenie kont mogących łączyć się przez SSH dodatkowo wzmacnia bezpieczeństwo. Dyrektywa PermitRootLogin kontroluje dostęp konta root. Rekomendowane jest całkowite wyłączenie bezpośredniego logowania roota:
PermitRootLogin no
Administratorzy powinni logować się kontem zwykłego użytkownika i używać sudo do zadań administracyjnych — zapewnia to rozliczalność poprzez logi sudo.
Ograniczanie dostępu SSH do określonych użytkowników i grup
Dyrektywy AllowUsers, AllowGroups, DenyUsers i DenyGroups umożliwiają precyzyjną kontrolę, kto może korzystać z SSH. Stosuj zasadę najmniejszych uprawnień – tylko niezbędni użytkownicy powinni mieć dostęp.
Przykład białej listy użytkowników (AllowUsers):
AllowUsers [email protected] [email protected] charlie
Przykład ograniczenia do grup (AllowGroups):
AllowGroups sshusers admin
Priorytet oceny list to kolejno: DenyUsers, AllowUsers, DenyGroups, AllowGroups. Whitelist (Allow*) jest bezpieczniejsza niż blacklist (Deny*).
Zarządzanie kluczami SSH z użyciem ssh-agent
ssh-agent przechowuje odblokowane klucze prywatne w pamięci i obsługuje żądania uwierzytelniania bez wielokrotnego wpisywania hasła do klucza. Uruchomienie w bieżącej powłoce:
eval "$(ssh-agent -s)"
Powyższe ustawia zmienne środowiskowe (m.in. SSH_AUTH_SOCK). Dodanie klucza:
ssh-add ~/.ssh/id_ed25519
Na macOS można użyć pęku kluczy:
ssh-add -K ~/.ssh/id_ed25519
Lista kluczy w agencie:
ssh-add -l
Usunięcie klucza:
ssh-add -d ~/.ssh/id_ed25519
Dla różnych hostów można przypisać różne klucze w ~/.ssh/config:
Host github.com
IdentityFile ~/.ssh/github_ed25519
AddKeysToAgent yes
UseKeychain yes
Host production.example.com
IdentityFile ~/.ssh/production_ed25519
User deploy
Port 2222
Zaawansowane środki wzmacniania bezpieczeństwa SSH
Poza podstawową konfiguracją warto zastosować dodatkowe warstwy ochrony:
- niestandardowy port – zmień domyślny Port 22 na inny (np. Port 2222), aby ograniczyć skanowanie automatyczne;
- Fail2ban – automatycznie banuje adresy z wieloma nieudanymi próbami logowania;
- LogLevel VERBOSE – podnosi szczegółowość logów i ułatwia analizę bezpieczeństwa;
- MaxAuthTries – ogranicz liczbę prób (np. do 3), by utrudnić ataki;
- 2FA dla SSH – rozważ uwierzytelnianie dwuskładnikowe (np. Google Authenticator w PAM), łącząc klucz z OTP.
Przykładowa konfiguracja fail2ban w /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 300
bantime = 3600
ignoreip = 127.0.0.1
Rozwiązywanie problemów z uwierzytelnianiem SSH
Typowy błąd „Permission denied (publickey)” diagnozuj metodycznie:
-
Sprawdź, czy działa usługa SSH:
sudo systemctl status sshdsudo systemctl start sshd -
Zweryfikuj port w konfiguracji oraz nasłuch na porcie:
grep Port /etc/ssh/sshd_configsudo ss -tlnp | grep sshd -
Potwierdź, że para kluczy się zgadza (odciski palców powinny być zgodne):
ssh-keygen -l -f ~/.ssh/id_ed25519ssh-keygen -l -f ~/.ssh/id_ed25519.pub -
Włącz szczegółowe logowanie klienta, aby zobaczyć etapy negocjacji:
ssh -v username@hostnamessh -vvv username@hostname -
Skontroluj uprawnienia katalogu domowego, ~/.ssh i plików kluczy:
ls -la ~ls -la ~/.sshls -la ~/.ssh/id_ed25519Popraw uprawnienia, jeśli to konieczne:
chmod 700 ~/.sshchmod 600 ~/.ssh/id_ed25519chmod 600 ~/.ssh/authorized_keys -
Sprawdź logi serwera podczas próby logowania:
sudo tail -f /var/log/auth.log
Rotacja kluczy SSH i zarządzanie cyklem życia
Rotuj klucze SSH co 1–2 lata, aby ograniczyć skutki ewentualnego, nieujawnionego kompromitowania. Rotacja polega na wygenerowaniu nowej pary, wdrożeniu klucza publicznego na wszystkich hostach i usunięciu starego wpisu z authorized_keys.
Pomaga konwencja nazewnicza z rokiem utworzenia:
ssh-keygen -t ed25519 -f ~/.ssh/[email protected] -C "[email protected]"
Przechowuj w agencie dwa najnowsze klucze na czas migracji:
ssh-add ~/.ssh/[email protected]
ssh-add ~/.ssh/[email protected]
Po wdrożeniu nowych kluczy usuń stare z authorized_keys, aby domknąć cykl rotacji.





