公開鍵認証ができない!!
先月, いつものように sshd の設定を感覚とフィーリングでやった1ところ,
締め出しを食らってしまい物理的にログインしなければならないという事件が起きました。
このときの知見を共有したいと思います。
私の環境では, チョット古いバージョンである OpenSSH_7.2p2 が動いているので, この方法じゃ解決できないかもしれません。
多分 i386 環境を使用している方はこのバージョンで動いているかと思います2。
TL;DR;
/etc/ssh/sshd_config
の AuthorizedKeysFile
設定 を .ssh/authorized_keys
にしたらログインできた。
# (中略)
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#RSAAuthentication yes
PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
- AuthorizedKeysFile ~/.ssh/authorized_keys
+ AuthorizedKeysFile .ssh/authorized_keys
2023/03/18 追記 コメント by @angel_p_57 さん
AuthorizedKeysFile のファイル名中に %T が含まれている場合、その部分は接続の間 別のものに置換されます。%% は '%' 1 文字に置換されます。 %h は認証しようとしているユーザのホームディレクトリに置換され、 %u はそのユーザのユーザ名に置換されます。この後、 その絶対パスあるいはユーザのホームディレクトリからの相対パスが AuthorizedKeysFile に渡されます。デフォルトでの値は ".ssh/authorized_keys" となっています。
らしい。つまり,
- AurhorizedKeysFile は、ホームディレクトリからの相対パスで指定できる。
- ユーザにごとに設定値をカスタマイズするために,
%h
(ホームディレクトリの絶対パス)や%u
(ユーザ名) 等のプレースホルダが使える。
このことより, AuthorizedKeysFile %h/.ssh/authorized_keys
でもいいというわけだ。
前提
項目/パッケージ | バージョン | 備考 |
---|---|---|
Ubuntu | 16.04 | i386環境で試しています2。 |
OpenSSH | 7.2p2 | |
ssh | 8.9p1 | クライアントの方です。 |
当環境では, 鍵は Yubikey の PGP 機能を使って格納されており, ssh-agent の代わりに gpg=agent を使って鍵管理している。
やりたいこと
SSH で公開鍵認証を使って鯖にログインしたい。
何が起きたか
Permission denied (publickey).
と表示され、公開鍵認証ができない。また、パスワード認証を切っているため, 鯖から締め出しを食らった。
試したこと
SSH(クライアント) の詳細なログを取ってみる
ssh
コマンドでは, オプション -v
を使うと詳細なログが取れる。今回の場合は, debug3 までほしいので -vvv
を使って実行する。
実行結果は以下の通りである。
OpenSSH_for_Windows_8.9p1, LibreSSL 3.0.2
# (中略. 鍵交換や, ホストキーについてやり取りしている.)
debug1: get_agent_identities: agent returned 1 keys
debug1: Will attempt key: (カード番号) ED25519 SHA256:(キーのハッシュ) agent
# (中略. 他のアルゴリズムのキーを試そうとしている.)
debug2: pubkey_prepare: done
debug3: send packet: type 5
debug3: receive packet: type 7
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=<rsa-sha2-256,rsa-sha2-512>
debug3: receive packet: type 6
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug3: send packet: type 50
debug3: receive packet: type 51
# このあたりから認証のログだろう。
debug1: Authentications that can continue: publickey
debug3: start over, passed a different list publickey
debug3: preferred publickey,keyboard-interactive,password
debug3: authmethod_lookup publickey
debug3: remaining preferred: keyboard-interactive,password
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Offering public key: (カード番号) ED25519 SHA256:(キーのハッシュ) agent
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 51
# (中略. 他のアルゴリズムのキーを試している模様)
debug1: No more authentication methods to try.
peyang@192.168.0.37: Permission denied (publickey).
キーの読み取りエラーや, 送信エラー等は特に起きていないようである。
このログを見る限り, クライアント側には問題がないため, サーバ側の問題だと推測した。
SSH(サーバ)の詳細なログを取ってみる
下準備:サーバの sshd_config
を書き換える
まず, 検証用にログインするため, パスワード認証を有効にした。そのあとに, LogLevel
を DEBUG
にし, デバッグログを取得できるようにした。
# (中略)
# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
- #LogLevel INFO
+ Loglevel DEBUG
# (中略)
# Authentication:
# To disable tunneled clear text passwords, change to no here!
- #PasswordAuthentication yes
+ PasswordAuthentication yes
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
ChallengeResponseAuthentication no
変更が終わったら, sshd を再起動する
$ sudo systemctl restart sshd
ログを tail -f
する
SSH の認証ログ /var/log/auth.log
を垂れ流しするようにする。
そのあとに, クライアントからログインを試みる。
$ tail -f /var/log/auth.log
(中略..) sshd[12912]: debug1: session_input_channel_req: session 0 req pty-req
debug1: Allocating pty.
debug1: session_new: session 0
debug1: SELinux support disabled
debug1: session_pty_req: session 0 alloc /dev/pts/0
debug1: server_input_channel_req: channel 0 request shell reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req shell
Starting session: shell on pts/0 for peyang from 192.168.0.236 port 27577 id 0
debug1: Setting controlling tty using TIOCSCTTY.
# ここで, クライアントからログインを試みる。
Connection from 192.168.0.236 port 27833 on 192.168.0.37 port 22
debug1: Client protocol version 2.0; client software version OpenSSH_for_Windows_8.9
# (中略 preauth やキー交換が走っている。)
debug1: userauth_pubkey: test whether pkalg/pkblob are acceptable for ED25519 SHA256:(キーのハッシュ) [preauth]
debug1: temporarily_use_uid: 1000/1000 (e=0/0)
# ↓↓↓ ここテストにでます。
debug1: trying public key file /root/.ssh/authorized_keys
debug1: Could not open authorized keys '/root/.ssh/authorized_keys': Permission denied
# ↑↑↑ ここテストにでます。
debug1: restore_uid: 0/0
Failed publickey for peyang from 192.168.0.236 port 27833 ssh2: ED25519 SHA256:(キーのハッシュ)
debug1: userauth-request for user peyang service ssh-connection method publickey [preauth]
debug1: attempt 1 failures 1 [preauth]
Connection reset by 192.168.0.236 port 27833 [preauth]
debug1: do_cleanup [preauth]
debug1: monitor_read_log: child log fd closed
debug1: do_cleanup
debug1: Killing privsep child 12931
debug1: audit_event: unhandled event 12
はい。何故か, authorized_keys
の格納場所が /root/.ssh/authorized_keys
になっていることがわかる。(原因は謎)
当然, /root/.ssh
や /root/.ssh/authorized_keys
は存在しないため, 開けないのでエラーになる。
が, 当時の私はここを読み飛ばしてたため, 解決から遠回りをすることになった。
ログを軽く読み飛ばしてはいけない(戒め)
権限を見直してみる(結局関係なかった)
以前, authorized_keys
や ~/.ssh/
が他グループに所属していたり, 他のユーザが書き込みできると認証ができない旨の記事を見た。
関係ないとは思ったが, 一応確認してみる。
peyang@Peyantu:~/.ssh$ ll
total 4
-rw------- 1 peyang peyang 186 Feb 14 00:12 authorized_keys
peyang@Peyantu:~/.ssh$ cd ../
peyang@Peyantu:~$ls -la
toltal (128)
# (中略)
drwx------ 2 peyang peyang 4096 Feb 14 00:16 .ssh
適切な権限は, .ssh/authorized_keys
が 600, .ssh
が 700 のため, 健全な権限である。
サーバ側の AuthorizedKeys
のパスを変更してみる
ここで当時の私は, 上記の ssh が /root/.ssh
のキーを参照している問題に気づく。
一通り ChatGPT に聞いてみたり, Perplexity や Googleで検索してみたが, 有力な情報は得られなかった。
長年の経験(笑)から、AuthorizedKeys
設定がおかしいだろうと思い, 適切なパスに変えることにした(つまりあてずっぽう)
いろいろ試したところ, ~/.ssh/authorized_keys
を .ssh/authorized_keys
にしたところ動作した。
# (中略)
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#RSAAuthentication yes
PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
- AuthorizedKeysFile ~/.ssh/authorized_keys
+ AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
おわりに
今回の直接的な原因としては, AuthorizedKeysFile
設定がおかしかったことが挙げられる.
だが, そもそもこれが起きた理由は, 全くもってマニュアルを見なかった私にある。
sshd_config
をみると, AuthorizedKeysFile
設定の下の項目である IgnoreUserKnownHosts
のコメントに, ~/.ssh/known_hosts
と書かれてある。
私は, ~/
をつけることが慣習かと思い, 今回の問題となった設定も ~/.ssh/authorized_keys
としてしまった.
これが今回の問題のすべての元凶だと思う。
今後は, 横着をしないでマニュアルをしっかり見ようと思った.