Wróć do bloga

SSH Permission denied (publickey): prawdziwa naprawa

18 września 2026

O 02:10 deploy zmarł na linii, którą wpisałem tysiąc razy: ssh deploy@stagingPermission denied (publickey). Klucz był dobry. Oferta — nie.

TL;DR: Permission denied (publickey) znaczy, że każdy klucz zaproponowany przez klienta został odrzucony przez serwer — werdykt negocjacji, nie literówka w haśle. Diagnozuj przez ssh -vvv (które klucze zaproponowano) i log serwera journalctl -u ssh (które odrzucono i dlaczego). Potem napraw jedną z czterech przyczyn: zły użytkownik, klucza brak w authorized_keys, zbyt otwarte uprawnienia albo klucz ssh-rsa odrzucany przez OpenSSH 8.8+. ssh-copy-id zapobiega większości nawrotów.

$ ssh -T [email protected]
[email protected]: Permission denied (publickey).

Błąd to werdykt, nie podpowiedź: wszystko z oferty zostało odrzucone.

Dlaczego SSH pokazuje „Permission denied (publickey)“?

Uwierzytelnianie kluczem publicznym to negocjacja oferta–odrzucenie. Klient proponuje każdy klucz, jaki znajdzie — tożsamości z agenta, z ~/.ssh/config, domyślne nazwy plików (id_ed25519, id_rsa) i wszystko przekazane przez -i. Serwer sprawdza każdą ofertę względem ~/.ssh/authorized_keys konta docelowego. Gdy nic nie pasuje, a uwierzytelnianie hasłem jest wyłączone lub wyczerpane, klient wypisuje linię, którą każdy inżynier devops zna na pamięć.

Do debugowania ważne są dwa fakty. Po pierwsze, komunikat nie mówi, jakiego użytkownika dotknąłeś — w połowie przypadków znakomity klucz siedzi w authorized_keys złego konta. Po drugie, serwer już powiedział dlaczego: sshd loguje każdą odrzuconą ofertę. Stack trace, o który nikt nie prosił, a którego każdy potrzebuje, to -vvv.

Jak sprawdzić, który klucz SSH naprawdę oferuje?

ssh -vvv deploy@staging 2>&1 | grep -iE "offering|identity|denied|authentications"
# debug1: Offering public key: /home/you/.ssh/id_ed25519 RSA-SHA256 (explicit)
# debug1: Authentications that can continue: publickey
# deploy@staging: Permission denied (publickey).

Przeczytaj trzy linie: Offering public key (co klient zaproponował), Authentications that can continue (co serwer jeszcze przyjmie — jeśli brak password, o hasło nie zapyta nigdy) i ostateczny werdykt. Jeśli twój klucz w ogóle nie pojawia się na liście ofert, problem jest po stronie klienta: zła ścieżka -i, zapomniany IdentityFile w ~/.ssh/config albo agent (ssh-add -l), który pierwszy odpowiada przeterminowaną tożsamością.

Jakie są cztery prawdziwe przyczyny?

PrzyczynaZnak rozpoznawczyNaprawa
Zły użytkownikKlucz działa dla root@host, zawodzi dla deploy@hostKlucz musi być w ~/.ssh/authorized_keys tamtego użytkownika
Klucz niezainstalowanyLog serwera pokazuje Failed publickey przy każdej oferciessh-copy-id user@host
Uprawnienia zbyt otwarteKlient: WARNING: UNPROTECTED PRIVATE KEY FILE — klucz pomijany, nigdy nieoferowanychmod 700 ~/.ssh; chmod 600 ~/.ssh/*
Stary klucz ssh-rsaSerwer na OpenSSH 8.8+; stary klucz RSA nigdy nieakceptowanyWygeneruj ed25519 od nowa albo zmodernizuj klucz

Przyczyna z uprawnieniami zasługuje na osobną notkę, bo OpenSSH pilnuje jej twardo: klucz prywatny czytelny dla grupy lub innych jest odrzucany przez samego klienta i po cichu wypada z oferty. Naprawa to dwa polecenia:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 ~/.ssh/authorized_keys

Przyczyna ssh-rsa potyka stare obrazy CI i Raspberry Pi: OpenSSH 8.8 (wydany 2021-10-01, openssh.com/txt/release-8.8) wyłączył domyślnie podpisy ssh-rsa — wariant oparty na SHA-1. Z release notes: “the ssh-rsa signature scheme is … disabled by default”. Klucz RSA wygenerowany w 2018 nie jest zepsuty; jego format podpisu po prostu przestał być używany. Wygenerowanie klucza ed25519 (ssh-keygen -t ed25519) to trwała odpowiedź, a konsole chmurowe dają konsolę szeregową na wypadek, gdybyś zamurował się na pół naprawy.

Jeśli sshd odmawia startu, gdy edytujesz jego konfigurację, to inne polowanie — patrz systemd service not starting.

Jak sprawdzić, dlaczego serwer odrzucił klucz?

Log serwera to uczciwy świadek. Na Ubuntu (systemd) sshd loguje werdykt każdej oferty:

journalctl -u ssh -n 50 --no-pager | grep -iE "publickey|denied|accepted"
# sshd[4421]: Failed publickey for deploy from 203.0.113.7 port 51422 ssh2: RSA SHA256:...
# sshd[4421]: Accepted publickey for deploy from 203.0.113.7 port 51422 ssh2: ED25519 SHA256:...

Failed publickey z nieoczekiwanym odciskiem znaczy, że klient zaproponował inny klucz niż myślałeś — wracaj do -vvv. Failed publickey z twoim odciskiem znaczy, że klucz jest dobry, ale niezainstalowany dla tego konta, albo że uprawnienia katalogu domowego po stronie serwera są złe (ta sama reguła 700/600 dotyczy ~/.ssh i ~/.ssh/authorized_keys serwera).

Jak poprawnie zainstalować swój klucz?

ssh-copy-id deploy@staging
# Number of key(s) added: 1
ssh -o BatchMode=yes deploy@staging 'echo ok'   # nieinteraktywny dowód

ssh-copy-id dopisuje twój klucz publiczny do authorized_keys konta docelowego z rozsądnymi uprawnieniami — istnieje, bo ręczne wklejanie do authorized_keys zawodzi regularnie: końcowy znak nowej linii albo brakujący katalog. Test z BatchMode to prawdziwy dowód: wyłącza wszystkie pytania, więc sukces znaczy, że sam klucz uniósł logowanie. Gdy klucz działa, scp i rsync dziedziczą to samo uwierzytelnienie za darmo — wybór między nimi to kwestia pasma, nie poświadczeń (rsync vs scp).

Triage w 30 sekund

ssh -vvv user@host 2>&1 | grep -i offering      # 1. które klucze zaproponowano?
journalctl -u ssh -n 50 | grep -i publickey     # 2. dlaczego odrzucono?
ls -ld ~/.ssh ~/.ssh/authorized_keys            # 3. 700 / 600?
ssh-copy-id user@host                           # 4. zainstaluj, zweryfikuj przez BatchMode

Permission denied (publickey) to wynik negocjacji, nie pytanie o hasło — serwer odrzucił każdy klucz z oferty, a jego log już wie dlaczego.

Cztery polecenia po kolei i awaria przestaje być zagadką: jedno z nich za każdym razem nazywa winowajcę. U mnie była to przeterminowana tożsamość agenta odpowiadająca przed właściwym kluczem — ssh-add -d, i deploy o 02:31 znów zzieleniał.

FAQ

Dlaczego SSH pokazuje Permission denied (publickey)?

To znaczy, że każdy klucz zaproponowany przez klienta został odrzucony przez serwer, a uwierzytelnianie hasłem lub keyboard-interactive nie było próbowane albo jest niedozwolone. To werdykt negocjacji twoich kluczy — nie literówka w haśle.

Jak naprawić SSH permission denied (publickey) na Ubuntu?

Sprawdź stronę serwera przez journalctl -u ssh -n 50, potwierdź, że twój klucz publiczny jest w ~/.ssh/authorized_keys docelowego użytkownika, i upewnij się, że uprawnienia to 700 na ~/.ssh i 600 na authorized_keys oraz kluczu prywatnym.

Dlaczego ssh -i mójklucz nadal zawodzi?

Trzy typowe powody: uprawnienia klucza prywatnego są zbyt otwarte i OpenSSH odmawia jego załadowania, serwer działa na OpenSSH 8.8+, które wyłączyło ssh-rsa (podpisy SHA-1), albo klucza nie ma w authorized_keys właściwego użytkownika.

Jak dodać swój klucz publiczny na serwer?

Uruchom ssh-copy-id user@host — doda twój klucz publiczny do ~/.ssh/authorized_keys z poprawnymi uprawnieniami. Jeśli logowanie hasłem jest już wyłączone, zrób to z konsoli, do której jeszcze masz dostęp.

— mrsaynothing

— mrsaynothing

Notatki z pogranicza AI, Linuksa i self-hostingu.

Get the next one by email

One email per post. No spam, no algorithms.

self-hosted · no third parties · one-click unsubscribe

what is this?

Gitignore nie działa? Oto prawdziwa naprawa

Podobają się teksty? Tak buduję zawodowo. zatrudnij mnie