今まで、 ~/.ssh/config は必要になった時に雑な追記を繰り返していた。 消したい時も、git 等で管理していないので念の為コメント化するだけに留めてしまい更に汚くなった。 最近メインマシンを新しくしたので設定を移行する際に、せっかくなので真面目に管理するようにした。 その管理方法について紹介する。

ファイルを分割する

まずは、一つのファイルで管理していると肥大化してしまうのでファイルを分割することにした。 そのために ~/.ssh/config には以下の1行だけを書くことにした。 この Include によって ~/.ssh/config.d 内にあるすべてのファイルが設定ファイルとして読み込まれるようになる。

Include ~/.ssh/config.d/*

1ホスト1ファイルにまで分割する必要は無いと思ったので、大まかにドメインごとにした。 具体的には以下のようなファイル構成になる。

config.d
├── 49-sub.example.ac.jp
├── 50-example.ac.jp
├── 50-github.com
└── 50-takono.io

*.example.ac.jp ではユーザー名を設定しつつ、 *.sub.example.ac.jp では別のユーザー名を設定したいといった場合に、優先順位が重要になる。 数字を先頭に入れないとサブドメイン名によっては優先順位が逆になり適切に反映されなくなってしまうため、先頭に 50- のように数字を入れている。

git を使う

バージョン管理を行うために git を使うことにした。 ~/.ssh でそのまま git init してしまうことも可能だが、(.gitignore は書いたりするとしても)何らかの事故で秘密鍵を push してしまうと怖い。 なので別ディレクトリで git リポジトリを作り、その中に config.d 等を配置した。 そして ~/.ssh/config.d 等には git リポジトリ内へのシンボリックリンクを作成するようにした。

known_hosts も含める

また known_hosts についても git で管理するようにした。 こうすることで複数の環境で共有することができ、何度もフィンガープリントの確認をしなくて済む。 しかし ~/.ssh/known_hosts をそのまま git で管理すると、使わなくなったホストが溜まっていきそうかつ、コンフリクトも起きやすそうなので設定と同じように分割するようにした。

そのために以下のような known_hosts.d を作成し、各ホストの設定で UserKnownHostsFile を書いた。 known_hosts では順番は関係ないので config.d のような先頭に数字をつけることはしない。

設定を書いていないホストについては引き続き ~/.ssh/known_hosts に追記されていくが、一度しか使わないホスト等なので特に git で管理はしない。

known_hosts.d
├── sub.example.ac.jp
├── example.ac.jp
├── github.com
└── takono.io

まとめ

~/.ssh 内の config や known_hosts について、ファイルを分割し git で管理するようにした。 これにより config が読みやすくなり、 git で復元ができるので安心して削除もできるようになった。 また所属する組織から抜ける時などには対応する config と known_hosts のファイルを消すだけで良いため、不要な項目が残りにくくなった。