一行のメッセージと、誤読されている部分
sh
$ sftp alice@files.example.com
alice@files.example.com: Permission denied (publickey).このメッセージは OpenSSH クライアントの一箇所で作られていて、その書式文字列を見るのが一番早いです。
text
fatal("%s@%s: Permission denied (%s).",
authctxt->server_user, authctxt->host, authlist);最後のフィールドは authlist、つまりサーバーがまだ受け付ける認証方式の一覧です。失敗した方式の名前ではありません。したがって Permission denied (publickey) の意味は「手持ちを全部試した、サーバーは公開鍵認証しか提供していない、そして自分の鍵は受け付けられなかった」。(publickey,password) と出ていればパスワードに落ちられますが、そう出ていないなら探しても無駄です。
| 見えること | 原因 | 対処 |
|---|---|---|
即失敗し、-v に "Offering public key" が出ない | クライアントが鍵を見つけていない / 送っていない | -i、IdentitiesOnly yes |
-v では鍵を出しているのに拒否される | authorized_keys に無い、またはユーザー違い | 対象アカウントのファイルを確認 |
| あるユーザーは通り、別のユーザーは通らない | ~、~/.ssh、authorized_keys の権限 | ディレクトリ 700、ファイル 600 |
-v に "no mutual signature algorithm" | OpenSSH 8.8 以降 ssh-rsa が既定で無効 | 鍵種を変える、ホスト単位で再有効化 |
| サーバーのログに "invalid format" | 鍵ファイルが違う(.ppk、公開鍵を秘密鍵として指定) | OpenSSH 形式へ変換 |
| Windows で管理者アカウントだけ失敗 | administrators_authorized_keys を使っていない | そのファイルを作り ACL を直す |
| スクリプトや踏み台経由でだけ失敗 | エージェントがない / 転送されていない | ssh-add、ForwardAgent は意識して使う |
1. まず verbose ログを読む
以下はすべて、クライアント自身のハンドシェイクの記録を見るまでは当て推量です。
sh
ssh -v alice@files.example.com
sftp -v alice@files.example.com答えを運ぶ行は三つで、いずれも OpenSSH のソースにあるリテラル文字列です。Authentications that can continue: publickey はサーバーの方式一覧。Offering public key: /Users/alice/.ssh/id_ed25519 は、その鍵を実際に送ったという意味で、この行が無ければ原因は完全にクライアント側です。そして no mutual signature algorithm が手順 4 のアルゴリズム不一致です。
サーバー側では sshd_config の LogLevel を上げます。値は QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, DEBUG3 で既定は INFO。鍵のフィンガープリントを記録するには VERBOSE で十分です。マニュアルは DEBUG レベルでのログ記録は「violates the privacy of users and is not recommended」と警告しています。
2. 両端の権限を直す
サーバー側で最も多く、最も見えにくい原因です。正しい鍵でも、書き込み可能なディレクトリに置かれていれば黙って無視されます。sshd のマニュアルは明確で、~/.ssh は「the recommended permissions are read/write/execute for the user, and not accessible by others」、~/.ssh/authorized_keys は「the recommended permissions are read/write for the user, and not accessible by others」。理由も続きます。「If this file, the ~/.ssh directory, or the user's home directory are writable by other users, then the file could be modified or replaced by unauthorized users」、その場合「sshd will not allow it to be used unless the StrictModes option has been set to 'no'」。StrictModes の既定は yes です。
sh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod go-w ~
ls -ld ~ ~/.ssh ~/.ssh/authorized_keysクライアント側も同じで、他人から読める秘密鍵は ssh 自身が拒否します(chmod 600 ~/.ssh/id_ed25519)。
3. ファイル・書式・ユーザー名を確認する
authorized_keys は 1 行 1 鍵で、マニュアルはフィールドを「options, keytype, base64-encoded key, comment」と説明しています(options は省略可)。コピー&ペーストやブラウザのダウンロードで入った改行は base64 を割って、その行を黙って無効にします。
sh
ssh-keygen -lf ~/.ssh/id_ed25519.pub
tail -c 100 ~/.ssh/authorized_keys | cat -A | tail -2同じ系統であと二つ。鍵はログインするアカウントの authorized_keys に入っていなければならず、だから alice 用の鍵で sftp root@host は失敗します。そして sshd_config の AuthorizedKeysFile は別の場所を指せます——「may include wildcards」でトークンも使えるので、堅めのホストはホームではなく /etc/ssh/keys/%u を読んでいるかもしれません。
4. 古い RSA 鍵を止めたアルゴリズム変更
長年動いていた鍵が突然止まったなら、まずこれです。OpenSSH 8.8 のリリースノートはこう書いています。「This release disables RSA signatures using the SHA-1 hash algorithm by default. This change has been made as the SHA-1 hash algorithm is cryptographically broken.」無効になったのは ssh-rsa という署名アルゴリズムで、RSA 鍵そのものではありません。
ssh_config の PubkeyAcceptedAlgorithms の現在の既定一覧には rsa-sha2-512 と rsa-sha2-256 が入り、ssh-rsa は入っていません。手元の設定は自分で確認できます。
sh
ssh -Q PubkeyAcceptedAlgorithmsリリースノートが挙げている応急処置は、宛先ホスト単位での再有効化です。同ノートはこれを「only as a stopgap measure until legacy implementations can be upgraded or reconfigured with another key type (such as ECDSA or Ed25519)」と位置づけています。
text
Host old-host
HostkeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa+ は既定集合への追加、- は削除、^ は先頭への配置です。より良い対処は新しい鍵:ssh-keygen -t ed25519。
5. エージェント、パスフレーズ、鍵が多すぎる問題
秘密鍵にパスフレーズがあり、何も尋ねてこない環境(cron、CI、GUI アプリ)では、クライアントは鍵を開けられません。一度エージェントに載せます。
sh
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l逆の失敗もあります。MaxAuthTries の既定は 6 なので、エージェントが十数個の鍵を差し出すとクライアントが正解に届く前に切られます。対処は IdentitiesOnly——「only use the configured authentication identity and certificate files … even if ssh-agent or a PKCS11Provider or SecurityKeyProvider offers more identities」という指定です。
sh
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 alice@files.example.com踏み台にはエージェント転送よりも ProxyJump を。転送するならホスト単位で、全体設定では絶対にやらないこと。
6. Windows サーバーには鍵ファイルが二つある
これは午後を溶かす類の罠で、しかも一般的な手順が「まさに検証で使うアカウント」で間違っています。マイクロソフトの文書は明確です。管理者ユーザーの公開鍵は C:\ProgramData\ssh\ の administrators_authorized_keys に置き、「This file only applies to administrator accounts. You must use it instead of the user-specific file within the user's profile location.」ACL は管理者と SYSTEM のみに絞ります。
powershell
icacls.exe "$env:ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"同じページの注記も二つ。Windows OpenSSH は AuthorizedKeysCommand と AuthorizedKeysCommandUser に非対応で、鍵認証はローカルアカウントと Active Directory アカウントで使えますが、Microsoft Entra ID のアカウントでは使えません。
鍵が通ったあとの話
認証が直れば、残るのはその接続で何をするかです。AnyStorage(v0.2.24;macOS 11 以降 / Windows 10 以降 / Ubuntu 20.04 以降)は鍵認証の SFTP ホストを、S3 互換エンドポイントや WebDAV と同じ一つのウィンドウで扱え、無料プランの接続数は 2 つ。ファイル一覧ではなくドライブとして欲しいときは、内蔵のローカル WebDAV サーバー(http://127.0.0.1:3211)経由でマウントします。FUSE も WinFsp も macFUSE も要らない、つまり今解いた鍵の問題の上に sshfs の debug を積まずに済みます。
(publickey) は「鍵が間違っている」という意味ですか?
「サーバーは公開鍵認証しか受け付けず、こちらが出したもので満足しなかった」という意味です。これには「何も出していない」も含まれるので、ssh -v と "Offering public key" 行が最初の確認になります。
ssh は通るのに sftp が落ちます
認証は同じで、サービスが違います。鍵で ssh は通り sftp が後段で落ちるなら、sshd_config の Subsystem 行(sftp-server か internal-sftp)と、sshd が権限と所有者を無条件に検査する ChrootDirectory を見てください。
古い RSA 鍵はもう使えませんか?
十分な長さの本物の RSA 鍵なら使えます。現代の rsa-sha2-256 / rsa-sha2-512 署名アルゴリズムは同じ鍵を使います。既定で無効になったのは SHA-1 の ssh-rsa 署名だけです。
.ppk ファイルはそのまま使えますか?
そのままでは使えません。PuTTY の形式は独自なので、PuTTYgen の Conversions メニューで OpenSSH 秘密鍵として書き出すか、ssh-keygen で新しい鍵を作ってください。
次に読む
- 通った SFTP をドライブにする:SFTP をネットワークドライブとしてマウント
- デスクトップクライアントの比較:FTP / SFTP クライアント
- もう一つの道のマウントエラー:rclone mount の FUSE エラー