「Permission denied (publickey)」の解決 - SSH公開鍵認証の確認
「Permission denied (publickey)」とは何を意味するのか?
結論: サーバまで到達しているが、公開鍵認証で拒否された状態。ネットワークやパスワードの問題ではなく「鍵が通っていない」ことだけを示す。
このエラーは、SSH の TCP 接続自体は成立し、サーバの sshd まで会話が届いていることを意味する。Connection timed out や Connection refused とは段階が違う。サーバは「publickey 方式での認証を試みたが、有効な鍵を確認できなかった」と言っている。
user@server: Permission denied (publickey).
括弧内の publickey は、サーバがその時点で許可している認証方式の一覧だ。(publickey,password) なら鍵かパスワードのどちらでも通るが、(publickey) だけならパスワード認証は無効化されており、鍵を通すしか道はない。
前提(対象環境)
- クライアント: Ubuntu / macOS(考え方は共通)
- サーバ: Ubuntu(OpenSSH server)
- サーバ側確認には別経路のログイン(コンソール等)または
sudoが必要
まず最短で何を確認すべきか?
結論:
ssh -vで「鍵が提示されているか」と「サーバがどの段階で拒否したか」を読む。これだけで原因がクライアント側かサーバ側かに二分できる。
原因は大きく分けて、クライアントが正しい鍵を提示していないか、サーバが提示された鍵を受け付けていないかのどちらかだ。最初に切り分けるべきはここで、-v の出力がその判断材料になる。
$ ssh -v user@server.example.com
注目する行:
debug1: Offering public key: /home/user/.ssh/id_ed25519 ED25519 SHA256:... debug1: Authentications that can continue: publickey debug1: No more authentication methods to try.
Offering public key が 一度も出ない → クライアントが鍵を提示していない(クライアント側の問題)。
Offering public key は出るのに拒否される → サーバが鍵を受け付けていない(サーバ側の問題)。
なぜ鍵が拒否されるのか?原因の全体像
結論: 原因はクライアント層・サーバ層・sshd 設定層の3つに分類できる。上から順に潰すと迷子になりにくい。
| 層 | 主な原因 | 確認コマンド |
|---|---|---|
| クライアント | 鍵を指定していない / agent に未登録 / ユーザー名違い | ssh -v / ssh-add -l |
| サーバ | authorized_keys に公開鍵が無い / 権限・所有者違い |
ls -la ~/.ssh |
| sshd 設定 | PubkeyAuthentication no / AuthorizedKeysFile のパス |
sudo sshd -T |
以降、この3層を順番に確認していく。
ssh -v の出力をどう読むか?
結論:
-vは試行した鍵と、サーバが返した「継続可能な認証方式」を時系列で出す。どこで会話が止まったかを読み取るのが核心。
代表的なパターンを挙げる。
鍵を1つも提示していない場合:
debug1: Authentications that can continue: publickey debug1: No more authentication methods to try.
Offering public key 行が無いまま終わっている。クライアントが使う鍵を見つけられていない。
鍵は提示したが拒否された場合:
debug1: Offering public key: /home/user/.ssh/id_rsa RSA SHA256:... debug1: Authentications that can continue: publickey
鍵を出したのにサーバが受け取らなかった。サーバ側の authorized_keys か権限を疑う。
-vv / -vvv でさらに詳細になる。鍵交換やアルゴリズムのネゴシエーションまで見えるが、認証の切り分けは -v で足りることが多い。
クライアント側: 正しい鍵を提示できているか
結論: 秘密鍵の存在・権限・指定方法を確認する。
-iで鍵を明示し、それで通るなら設定(config / agent)の問題に絞れる。
確認1: 鍵ファイルが存在するか
$ ls -la ~/.ssh
id_ed25519(秘密鍵)と id_ed25519.pub(公開鍵)のペアがあるか確認する。
確認2: 秘密鍵の権限
秘密鍵の権限が緩いと、ssh は安全のためその鍵を拒否し、Permissions 0644 for ... are too open と警告して使わない。
$ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/id_ed25519
確認3: 使う鍵を明示する
複数の鍵がある、または ~/.ssh/config が未設定だと、意図した鍵が提示されないことがある。
$ ssh -i ~/.ssh/id_ed25519 user@server.example.com
これで通るなら、鍵自体は正しい。次は恒久設定として ~/.ssh/config に書く。
Host server
HostName server.example.com
User user
IdentityFile ~/.ssh/id_ed25519
確認4: ユーザー名が合っているか
公開鍵は「どのユーザーの authorized_keys に登録されているか」が重要だ。鍵が正しくてもログインユーザーを間違えると拒否される。
$ ssh -i ~/.ssh/id_ed25519 deploy@server.example.com
サーバ側: authorized_keys と権限を確認する
結論: 公開鍵が
authorized_keysに登録され、かつ.sshとauthorized_keysの所有者・権限が正しいかを見る。権限が緩いとStrictModesが鍵を無効化する。
サーバに別経路(コンソールや既存セッション)で入れる場合、対象ユーザーの ~/.ssh を確認する。
確認1: 公開鍵が登録されているか
$ cat ~/.ssh/authorized_keys
クライアントの id_ed25519.pub の内容と一致する行があるか確認する。無ければ登録する。クライアントから一発で登録するなら:
$ ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server.example.com
手動なら、公開鍵の中身を追記する。
$ cat ~/.ssh/id_ed25519.pub | ssh user@server 'cat >> ~/.ssh/authorized_keys'
確認2: 所有者と権限(StrictModes)
sshd はデフォルトで StrictModes yes のため、ホームや .ssh の権限が緩い/所有者が違うと、鍵が正しくても認証を拒否する。これは非常にハマりやすい。
$ chown -R user:user ~/.ssh $ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/authorized_keys
ホームディレクトリ自体が group/other に書き込み可 だと拒否される点にも注意する。
$ chmod go-w ~
サーバ側ログに理由が出る。Authentication refused: bad ownership or modes for directory /home/user/.ssh のような行が出ていれば、権限・所有者が原因だと確定できる。
サーバ側ログで理由を確定するには?
結論:
journalctl -u sshでサーバの認証ログを見ると、鍵不一致・権限・ユーザー違いなど拒否の具体的理由が出る。推測を止められる。
$ sudo journalctl -u ssh -n 100 --no-pager
リアルタイムで追う場合:
$ sudo journalctl -u ssh -f
ディストリによっては /var/log/auth.log に出る。
$ sudo tail -f /var/log/auth.log
典型的な行:
Authentication refused: bad ownership or modes for directory→ 権限・所有者error: Could not open authorized keys→ パスや存在の問題Invalid user xxx→ ユーザー名違い
sshd_config の設定を疑うべきケースは?
結論: 公開鍵認証自体が無効化されている、または鍵ファイルのパスが標準と異なる場合がある。
sshd -Tで実効値を確認する。
サーバの実効設定は、設定ファイルを直接読むより sshd -T で確認するのが確実だ(Match ブロックや複数ファイルの合成結果が出る)。
$ sudo sshd -T | grep -Ei 'pubkeyauth|authorizedkeysfile'
確認ポイント:
pubkeyauthentication yesになっているか(noなら鍵認証が無効)authorizedkeysfile .ssh/authorized_keysが想定どおりか(独自パスに変更されていないか)
設定を変更した場合は反映する。
$ sudo systemctl reload ssh
SSH 設定の変更で自分を締め出さないよう、既存セッションを1つ残したまま別ターミナルで再接続テストする。reload 後すぐに新規接続が通るか確認してからセッションを閉じる。
ssh-agent に鍵が登録されているか?
結論: agent 経由で認証している場合、鍵が agent にロードされていないと提示されない。
ssh-add -lで登録済み鍵を確認する。
~/.ssh/config で IdentitiesOnly を使っていない環境や、踏み台(ProxyJump)経由では、agent にロードした鍵が使われる。
$ ssh-add -l
The agent has no identities. なら鍵が未登録だ。追加する。
$ ssh-add ~/.ssh/id_ed25519
agent 転送(-A)を使う場合は、ローカルの agent に鍵があることが前提になる。
それでも直らないときのチェックリスト
結論: クライアント→サーバ→sshd 設定→ログの順に、提示・登録・権限・実効設定を1つずつ潰す。多くは権限かユーザー名違いに収束する。
- [ ]
ssh -vでOffering public keyが出るか - [ ] 秘密鍵の権限は
600、~/.sshは700か - [ ]
-iで鍵を明示すると通るか - [ ] ログインユーザー名は正しいか
- [ ] サーバの
authorized_keysに公開鍵があるか - [ ] サーバの
~・~/.ssh・authorized_keysの所有者と権限は正しいか(StrictModes) - [ ]
sshd -Tでpubkeyauthentication yesか - [ ]
journalctl -u sshに拒否理由が出ていないか - [ ] agent 利用時、
ssh-add -lに鍵があるか