背景
- sshでサーバーに接続したときに「そういえばconfigファイルの権限が600にしたら読み取れるって話だけど,あれはなんでなんだろ?」と疑問に
調査方法
- OpenSSHのGitHubリポジトリをcloneしてコールドリーディング
- configファイルを読み取っている場所を探してどのような判定がされているか見てみる
調査
configファイルを読みっ取っている場所特定
- configファイルは手元のPCでは
ホームディレクトリ/.ssh/config
に配置してあるので,VSCodeの検索欄でconfig
で検索 - 予想はしていましたが,結果は大量に…
-
config file
に変えたかなり減った
- しかも
check permissions on config file
!ドンピシャ!- ファイル名も
readconf.h
- ファイル名も
- ファイルを開いて見た感じ,ファイルのパーミッションチェックをするかどうかのフラグに見える
...
#define SESSION_TYPE_NONE 0
#define SESSION_TYPE_SUBSYSTEM 1
#define SESSION_TYPE_DEFAULT 2
#define SSHCONF_CHECKPERM 1 /* check permissions on config file */
#define SSHCONF_USERCONF 2 /* user provided config file not system */
#define SSHCONF_FINAL 4 /* Final pass over config, after canon. */
#define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */
...
- 実装は
readconf.c
っぽい - 先程の
SSHCONF_CHECKPERM
でファイル内検索 - 1件目
-
read_config_file_depth()
という関数の引数で使われている - パーミッションチェックのような処理はなさそう
-
for (i = 0; i < gl.gl_pathc; i++) {
debug3("%.200s line %d: Including file %s "
"depth %d%s", filename, linenum,
gl.gl_pathv[i], depth,
oactive ? "" : " (parse only)");
r = read_config_file_depth(gl.gl_pathv[i],
pw, host, original_host, options,
flags | SSHCONF_CHECKPERM | // ここ
(oactive ? 0 : SSHCONF_NEVERMATCH),
activep, want_final_pass, depth + 1);
...
- 2件目
- 先程の
read_config_file_depth()
内に存在 - パーミッションチェック処理は
(sb.st_mode & 022) != 0
の部分!ここだ!
- 先程の
if (flags & SSHCONF_CHECKPERM) { // ここ
struct stat sb;
if (fstat(fileno(f), &sb) == -1)
fatal("fstat %s: %s", filename, strerror(errno));
if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
(sb.st_mode & 022) != 0)) // パーミッションチェック
fatal("Bad owner or permissions on %s", filename);
}
...
パーミッションの判定処理で何をしているのか
- 判定処理の部分
(sb.st_mode & 022) != 0
-
sb.st_mode
は,ファイルのパーミッション情報 - ファイルのパーミッション情報と022のビット演算を行い,結果が0になればOK
- ってことは,600以外でもいけるんじゃ?
試す
ファイルパーミッション | 結果 |
---|---|
640 | OK |
604 | OK |
600 | OK |
660 | NG |
620 | NG |
602 | NG |
- 結果として,ユーザー以外に書き込みがあるとNG
SSHのconfigファイルのベストプラクティス
- 追加調査でconfigファイルについてのベストプラクティスを発見
ベスト プラクティスでは、デフォルトの権限を 664 または 600 のままにし、所有者のみが読み取りおよび書き込み権限 (rw) を持つようにすることをお勧めします。こうすることで、ファイルは権限のないユーザーによる変更から安全に保たれます。
結論
- sshのconfigファイルのパーミッションは600じゃなくてOK
- 所有者のみが読み取り・書き込みができるようにするのが望ましい
- 普段使っているツールのコードを読むとおもしろい発見があったりする