「Permission denied (publickey)」の解決 - SSH公開鍵認証の確認

「Permission denied (publickey)」の解決 - SSH公開鍵認証の確認

「Permission denied (publickey)」とは何を意味するのか?

結論: サーバまで到達しているが、公開鍵認証で拒否された状態。ネットワークやパスワードの問題ではなく「鍵が通っていない」ことだけを示す。

このエラーは、SSH の TCP 接続自体は成立し、サーバの sshd まで会話が届いていることを意味する。Connection timed outConnection 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 に登録され、かつ .sshauthorized_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-agent に鍵が登録されているか?

結論: agent 経由で認証している場合、鍵が agent にロードされていないと提示されない。ssh-add -l で登録済み鍵を確認する。

~/.ssh/configIdentitiesOnly を使っていない環境や、踏み台(ProxyJump)経由では、agent にロードした鍵が使われる。

$ ssh-add -l

The agent has no identities. なら鍵が未登録だ。追加する。

$ ssh-add ~/.ssh/id_ed25519

agent 転送(-A)を使う場合は、ローカルの agent に鍵があることが前提になる。

それでも直らないときのチェックリスト

結論: クライアント→サーバ→sshd 設定→ログの順に、提示・登録・権限・実効設定を1つずつ潰す。多くは権限かユーザー名違いに収束する。

  • [ ] ssh -vOffering public key が出るか
  • [ ] 秘密鍵の権限は 600~/.ssh700
  • [ ] -i で鍵を明示すると通るか
  • [ ] ログインユーザー名は正しいか
  • [ ] サーバの authorized_keys に公開鍵があるか
  • [ ] サーバの ~~/.sshauthorized_keys の所有者と権限は正しいか(StrictModes)
  • [ ] sshd -Tpubkeyauthentication yes
  • [ ] journalctl -u ssh に拒否理由が出ていないか
  • [ ] agent 利用時、ssh-add -l に鍵があるか

次に読む