authorized_keysのパーミッション

ある日のことです。 自宅サーバーで作業をしていたとき、ふと~/.ssh/authorized_keysのパーミションを見てみると644になっていました。 これはいかんなと思いつつ調べてみると、~/.ssh/のパーミッションは755で、~/のパーミッションも755。 うろ覚えの記憶によればauthorized_keysが他人から読み取られる状態だとログインできなくなってしまうような気がしていたのですが、なぜかログインできています。 気になったので調べてみることにしました。

自宅サーバーの環境はFreeBSD 10.3+OpenSSH_7.2p2です。 この記事は自宅サーバーの動作に基づいて書かれています。1

どうやったらログインできなくなるのか

こんな状態でログインできているのならば、一体どうしたらログインできなくなるのかという疑問が湧いてきます。 まずは適当なユーザーをつくって実験をしてみることにしてみました。

# adduser
$ su hatena

パーミションを666にしてみます。この時点で他人がauthorized_keysに書き込めるようになっています。

$ chmod 666 .ssh/authorized_keys
$ exit
$ ssh -i ~/.ssh/id_rsa.xxx hatena@xxx.xxx
Permission denied (publickey).

一旦ログアウトしてリモートログインを試みるとログインできなくなりました。

$ chmod 777 .
$ chmod 777 .ssh/
$ chmod 644 .ssh/authorized_keys
$ exit
$ ssh -i ~/.ssh/id_rsa.xxx hatena@xxx.xxx
Permission denied (publickey).

また他人がauthorized_keysを削除できる状態でもログインはできません。

それでは他人が書き込めなければログインできるようになるだろうと思い、

$ chmod 700 .
$ chmod 700 .ssh/
$ chmod 666 .ssh/authorized_keys
$ exit
$ ssh -i ~/.ssh/id_rsa.xxx hatena@xxx.xxx
Permission denied (publickey).

このようにしたのですがログインできないままです。

この時点で誰もauthorized_keysに書き込めなくなっているわけですからこの挙動は不可解です。

sshd[63943]: Authentication refused: bad ownership or modes for file /usr/home/hatena/.ssh/authorized_keys

authorized_keysのパーミッションがダメというエラーログが出ていました。 これについては一番最後に触れたいと思います。

マニュアルを読む

authorized_keysについてFreeBSDのマニュアルには、

https://www.freebsd.org/cgi/man.cgi?sshd(8)

~/.ssh/authorized_keys Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user. The format of this file is described above. The content of the file is not highly sensi- tive, but 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.  In this case, sshd will not
   allow it to be used unless the StrictModes option has been set to
   ``no''.

とあります。

このファイルに他人がアクセスできず読み書きされないようにすることが推奨されているのはよいとして、注目すべきは引用部分の2段落目です。 StrictModesがnoになっていない限り、authorized_keysや上位のディレクトリが他人に書き込み可能な状態にあるときは認証に利用されることが許可されないとあります。 ここで重要なのは読み込み可能か否かについては触れていないということです。当初疑問に思っていた挙動がどうやらマニュアル通りのものらしいと理解できます。

ちなみに、FreeBSDsshdではStrictModesがデフォルトでyesになっています。

$ cat /etc/ssh/sshd_config  | grep StrictModes
#StrictModes yes

適切な設定と実装の記述

そもそも、なぜログインできるのを不思議に思ったかといえば、~/.ssh/のパーミッションは700、~/.ssh/authorized_keysのパーミッションは600ということがよく言われているからでした。これは間違いなく妥当な設定である一方、この設定を必要条件であると考えればauthorized_keysが他人から読み取られる状態だとダメという読み方もできてしまいます。これまでの実験で完全に筆者の勘違いであることが明らかになりましたが、この問題をめぐってはときにきわどい書き方がされているということも指摘しておきたいと思います。

https://wiki.centos.org/HowTos/Network/SecuringSSH#line-123

$ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/authorized_keys

The above permissions are required if StrictModes is set to yes in /etc/ssh/sshd_config (the default).

上に引用したCentOSのマニュアルには、StrictModesがyesのときにそのようなパーミッションが要求されると書かれています。 読み方によっては、authorized_keysが他人から読み込み可能だとログインできなくなると了解されかねないのではないかと考えます。 おそらく、このような表現は適切な設定と実装の記述を綯交ぜにしてしまった結果であるように思われます。

マニュアルに適切な設定が書かれていることは間違いないですが、細部に至るまで正確な表現がされているかどうかは保留して見ないといけないのかもしれません。 そして、読み手も書き手も、テクストの周辺にはつねに解釈学的な問題が生じうることを頭の隅においておくべきなのだろうと思いました。

不可解な挙動の謎

さて、ここまでで当初の疑問はすべて解決したわけですが、実験の途中に不思議な現象に遭遇していました。 事実上他人が読み書き不可であるにもかかわらず、authorized_keysのパーミッションが666のときログインできないという謎です。 どうせここまで調べてきたのでソースコードに当たってみます。エラーメッセージの文言を頼りにOpenSSHのリポジトリを検索するとそれらしい箇所が見つかりました。

https://github.com/openssh/openssh-portable/blob/2f2ffa4fbe4b671bbffa0611f15ba44cff64d58e/auth.c#L509

コードを見てみるとディレクトリの検査条件とファイルの検査条件2はORになっていますからどちらかに引っかかってしまえばアウトということになります。 したがってファイルに実際に書き込めるか否かにかかわらず、グループや他人がファイルに書けそうなパーミッションはダメということがわかります。

結論

~/.ssh/のパーミッションは700に、~/.ssh/authorized_keysのパーミッションは600にしたほうがいい。 しかしながら、authorized_keysが他人から読み込み可能であってもログインできる


  1. 他の環境でもテストしたところ、Debian 7.11+OpenSSH_6.0p1、CentOS 6.8+OpenSSH_5.3p1でも同じような挙動をしました。

  2. 参考 https://linuxjm.osdn.jp/html/LDP_man-pages/man2/stat.2.html