2
0

More than 1 year has passed since last update.

SSH 鯖の公開鍵認証のキーファイル設定は ~/.ssh/ から始めないほうが良い

Last updated at Posted at 2023-03-16

公開鍵認証ができない!!

先月, いつものように sshd の設定を感覚とフィーリングでやった1ところ,
締め出しを食らってしまい物理的にログインしなければならないという事件が起きました。
このときの知見を共有したいと思います。

私の環境では, チョット古いバージョンである OpenSSH_7.2p2 が動いているので, この方法じゃ解決できないかもしれません。
多分 i386 環境を使用している方はこのバージョンで動いているかと思います2

TL;DR;

/etc/ssh/sshd_configAuthorizedKeysFile 設定 を .ssh/authorized_keys にしたらログインできた。

/etc/ssh/sshd_config
# (中略)

# 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 さん

sshd_config(5) のマニュアル曰く,

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 を使って実行する。
実行結果は以下の通りである。

ssh peyang@192.168.0.37 -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 を書き換える

まず, 検証用にログインするため, パスワード認証を有効にした。そのあとに, LogLevelDEBUG にし, デバッグログを取得できるようにした。

/etc/ssh/sshd_config
# (中略)

# 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 に聞いてみたり, PerplexityGoogleで検索してみたが, 有力な情報は得られなかった。
長年の経験(笑)から、AuthorizedKeys 設定がおかしいだろうと思い, 適切なパスに変えることにした(つまりあてずっぽう)

いろいろ試したところ, ~/.ssh/authorized_keys.ssh/authorized_keys にしたところ動作した。

/etc/ssh/sshd_config
# (中略)

# 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 としてしまった.
これが今回の問題のすべての元凶だと思う。

今後は, 横着をしないでマニュアルをしっかり見ようと思った.

  1. 私は非常に怠惰なため, 繰り返しやることはマニュアルを見ないでやってしまう癖がある。

  2. ハードオフで500円で買ったマシンである。 2

2
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0