02:10、何千回も打った一行でデプロイが死にました。ssh deploy@staging → Permission denied (publickey)。鍵は問題なかった。問題だったのは提示の仕方です。
TL;DR: Permission denied (publickey)は、クライアントが提示したすべての鍵がサーバーに拒否されたという意味 — パスワードの打ち間違いではなく、交渉の結論です。 ssh -vvv(どの鍵を提示したか)とサーバーログのjournalctl -u ssh(どの鍵が、なぜ拒否されたか)で診断します。そして4つの原因のどれかを直します。ユーザー違い、authorized_keysに鍵がない、パーミッションが緩すぎる、またはOpenSSH 8.8+に拒否されるssh-rsa鍵。ssh-copy-idが再発の大半を防ぎます。
$ ssh -T [email protected]
[email protected]: Permission denied (publickey). このエラーはヒントではなく結論です。提示されたものはすべて拒否された、ということ。
SSHはなぜ「Permission denied (publickey)」と言うのか?
公開鍵認証は「提示と拒否」の交渉です。クライアントは見つけられるすべての鍵を提示します。エージェントの識別情報、~/.ssh/config、デフォルトのファイル名(id_ed25519、id_rsa)、そして-iで渡されたものすべてです。サーバーは各提示を対象アカウントの~/.ssh/authorized_keysと照合します。どれも一致せず、パスワード認証が無効か使い果たされていれば、クライアントはすべてのdevopsエンジニアが暗記しているあの一行を出力します。
デバッグに効く事実が2つ。まず、このメッセージはどのユーザーにアクセスしたかを教えてくれない — 半数のケースは、完璧に正常な鍵が間違ったアカウントのauthorized_keysに入っているだけです。次に、サーバーはすでに理由を語っています。sshdは拒否された提示をすべてログに残します。誰も頼んでいないのに全員が必要とするスタックトレースが-vvvです。
SSHが実際に提示している鍵はどうやって確認する?
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). 読むべきは3行。Offering public key(クライアントが提示したもの)、Authentications that can continue(サーバーがまだ受け付けるもの — passwordがなければパスワード入力は永遠に来ません)、そして最終結論。自分の鍵が提示リストに一度も現れないなら、問題はクライアント側にあります。間違った-iのパス、~/.ssh/configに忘れられたIdentityFile、あるいは古い識別情報を先に返すエージェント(ssh-add -l)です。
本当の原因は4つのうちどれ?
| 原因 | 見分け方 | 直し方 |
|---|---|---|
| ユーザー違い | root@hostでは成功し、deploy@hostでは失敗する | 鍵はそのユーザーの~/.ssh/authorized_keysに入っている必要がある |
| 鍵が未設置 | サーバーログに毎回Failed publickey | ssh-copy-id user@host |
| パーミッションが緩い | クライアント: WARNING: UNPROTECTED PRIVATE KEY FILE — 鍵はスキップされ、提示すらされない | chmod 700 ~/.ssh; chmod 600 ~/.ssh/* |
古いssh-rsa鍵 | サーバーがOpenSSH 8.8+。古いRSA鍵は決して受け付けられない | ed25519で作り直すか、鍵を更新する |
パーミッションの原因は特筆に値します。OpenSSHはここを厳格に強制するからです。グループや他人が読める秘密鍵は、クライアント自身が拒否し、提示リストから静かに外れます。直し方は2コマンド:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 ~/.ssh/authorized_keys ssh-rsaの原因は古いCIイメージやRaspberry Piを陥れます。OpenSSH 8.8(2021-10-01リリース、openssh.com/txt/release-8.8)はssh-rsa署名 — SHA-1ベースの方式 — をデフォルトで無効化しました。リリースノートの言葉を借りれば、“the ssh-rsa signature scheme is … disabled by default”。2018年生まれのRSA鍵は壊れていません。署名フォーマットがもう通用しないだけです。ed25519鍵を作り直す(ssh-keygen -t ed25519)のが長期的な答えで、クラウドのコンソールにはシリアルコンソールがあるので、作業中に締め出されても復帰できます。
設定を編集中にsshd自体が起動しなくなったなら、それは別の狩りです。systemd service not startingを参照してください。
サーバーが鍵を拒否した理由はどうやって見る?
サーバー側のログが正直な証人です。Ubuntu(systemd)ではsshdが提示ごとの判定を記録します:
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は、クライアントが思っていたのと別の鍵を提示したという意味 — -vvvに戻りましょう。自分のフィンガープリント付きのFailed publickeyは、鍵は正しいがそのアカウントに未設置か、サーバー側のホームディレクトリのパーミッションが間違っているという意味です(サーバーの~/.sshと~/.ssh/authorized_keysにも同じ700/600ルールが適用されます)。
鍵を正しく設置するには?
ssh-copy-id deploy@staging
# Number of key(s) added: 1
ssh -o BatchMode=yes deploy@staging 'echo ok' # 非対話の証明 ssh-copy-idは公開鍵を対象アカウントのauthorized_keysに適切なパーミッションで追記してくれます。このコマンドが存在するのは、authorized_keysへ手動で貼り付ける方法が、末尾の改行ひとつや存在しないディレクトリひとつで、ちょうどよく失敗するからです。BatchModeチェックこそ本物の試練です。すべての入力要求を無効にするので、成功=鍵だけでログインできたという意味になります。鍵が通れば、scpもrsyncも同じ認証をただで引き継ぎます。どちらを選ぶかは帯域の問題で、認証情報の問題ではありません(rsync vs scp)。
30秒のトリアージ
ssh -vvv user@host 2>&1 | grep -i offering # 1. どの鍵が提示された?
journalctl -u ssh -n 50 | grep -i publickey # 2. なぜ拒否された?
ls -ld ~/.ssh ~/.ssh/authorized_keys # 3. 700 / 600か?
ssh-copy-id user@host # 4. 設置して、BatchModeで検証
Permission denied (publickey)はパスワードの入力要求ではなく交渉の結果です。サーバーは提示されたすべての鍵を拒否しており、ログはすでに理由を知っています。
4つのコマンドを順に実行すれば、障害は謎ではなくなります。どれかが必ず犯人を名指しします。私の場合、正しい鍵より先に答えた古いエージェントの識別情報でした。ssh-add -dして、02:31にデプロイは再び緑に戻りました。
FAQ
SSHでPermission denied (publickey)と出るのはなぜ?
クライアントが提示したすべての鍵がサーバーに拒否され、パスワードやkeyboard-interactive認証が試されていないか許可されていないという意味です。パスワードの打ち間違いではなく、提示した鍵に対する交渉の結論です。
UbuntuでSSH permission denied (publickey)を直すには?
journalctl -u ssh -n 50でサーバー側を確認し、公開鍵が対象ユーザーの~/.ssh/authorized_keysに入っているか確かめ、~/.sshは700、authorized_keysと秘密鍵は600になっているか確認してください。
ssh -i で鍵を指定しても失敗するのはなぜ?
よくある原因は3つです。秘密鍵のパーミッションが緩すぎてOpenSSHが読み込みを拒否している、サーバーがssh-rsa(SHA-1署名)を無効化したOpenSSH 8.8+で動いている、あるいは鍵が正しいユーザーのauthorized_keysにないかです。
公開鍵をサーバーに追加するには?
ssh-copy-id user@hostを実行します。公開鍵を正しい権限で~/.ssh/authorized_keysに追加してくれます。パスワードログインがすでに無効なら、アクセスできるコンソールから行ってください。
— mrsaynothing
— mrsaynothing
AI・Linux・セルフホスティングの実地メモ。
Get the next one by email
One email per post. No spam, no algorithms.
what is this?記事を楽しんでいただけましたか?私の本業はこのような構築です。 採用のご相談