ククログ

株式会社クリアコード > ククログ > おすすめ.ssh/config設定

おすすめ.ssh/config設定

はじめに

つい先日、GitHubのRSA SSHホスト鍵が突如差し替えられるという一件がありました。

詳細に関しては識者による解説に委ねますが、ちょうどタイムリーな話題だったので、SSHをより安全に利用するという観点でおすすめ設定についていくつか紹介します。

なお、クリアコードではSSH以外にもおすすめzsh設定おすすめEmacs設定という記事も公開しているので参考にしてみてください。

2023年5月11日更新:StrictHostKeyCheckingyesにする場合の安全なknown_hostsの更新方法について追記しました。

おすすめ設定について

クリアコードでは、.ssh/configのおすすめ設定を https://gitlab.com/clear-code/ssh.d にて公開しています。 これは、社内で.ssh/configの設定を見直してみようという機運が高まったことによります。

公開しているおすすめ.ssh/config設定はあくまで雛形なので、利用者ごとの事情にあわせたカスタマイズが前提です。

ディレクトリ構成

$ tree .ssh
.
├── LICENSE
├── README.md
├── conf.d ユーザーごとのカスタマイズを配置する
│   └── template.conf # 設定のサンプル
├── config
└── global.conf # 汎用的なカスタマイズ内容

基本的に、利用者ごとの事情にあわせた設定ファイル(.conf)をconf.dディレクトリ配下に配置することを想定しています。 .ssh/configからconf.d配下の.confファイルを読み込むようになっています。 特定のサイトやネットワーク環境向けの設定といったように、必要に応じてファイルを分割すると管理しやすくなってよいでしょう。

なお、SSHの.ssh/configのルールとして、最初に見つけた設定が優先される挙動になっています。 ファイルの末尾のほうに追記したもので上書きされたりはしないので、個別の設定を(汎用的な設定の)前に記述する必要があります。1 global.confよりも先にconf.d/*.confIncludeしているのはそのためです。

おすすめ設定項目

汎用的なカスタマイズ内容である、global.confに含めた項目について紹介します。 リスクやメリット・デメリットを勘案して適宜必要なものを取捨選択してみてください。

HashKnownHostsをyesにする

HashKnownHostsのSSHの既定値はyesとなっています。

ホストへの接続を受け入れると.ssh/known_hostsに記録されますが、その際の通信先をハッシュ化して通信先を秘匿化するということを意味します。

ハッシュ化されていない状態のほうが.ssh/known_hostsの内容がすぐに確認できて便利と思うかもしれません。 しかし、~/.sshディレクトリ配下がまるごと漏れた場合に、パスフレーズを設定していないSSHの鍵があれば、known_hostsとの組み合わせで 意図せずアクセスされてしまう可能性があります。

また、コマンドの履歴(.bash_history など)を探すよりも楽に攻撃対象を特定できるという意味でもリスクがあります。

もし、HashKnownHostsnoにしてしまっているのなら、変更されることをおすすめします。

2023/4/4追記: HashKnownHostsについては、開発者のDamien さんが『I'd prefer to remove hostname hashing. 』と言っている@haruyamaさんに教えて いただきました。開発者としては筋の良くないオプションであると考えているようです。代替としてObscureKnownHostnamesを導入してHashKnownHostsを非推奨にした後、最終的に削除するという案への言及があります。すぐに使えなくなるわけではありませんが、将来的に移行が必要になるかもしれないことは認識しておいたほうがよさそうです。

PasswordAuthenticationをnoにする

PasswordAuthenticationのSSHの既定値はyesとなっています。

noにすると、サーバー側がパスワード認証を有効にしていた場合でも、クライアント側で明示的にパスワード認証での接続を禁止できます。 yesだと、うっかり誤ったサーバーに接続した際にパスワードを漏洩する可能性があるため、noにすることをおすすめします。2

StrictHostKeyCheckingをyesにする

StrictHostKeyCheckingのSSHの既定値はaskとなっています。

askのままだと、(DNS改ざんなど)意図しないサーバーに接続しにいってしまった場合であっても(利用者が)fingerprintをきちんと確認せず惰性で受理してしまう危険性があります。

yesにすると、ホストキーを必ずチェックするようになり、ホストキーがknown_hostsに登録されていない場合は接続を拒否するため、安全性が高まります。

ただし、StrictHostKeyCheckingyesにする場合、事前になんらかの手段でホスト鍵のfingerprintを取得して、known_hostsに登録しておく必要があります。 例えば、いくつかのサイトではknown_hostsのエントリを明示しています。

WebサイトやWeb APIでknown_hostsのエントリが明示されていない場合でも、ssh-keyscanを使用すると、以下の要領でホスト鍵のfingerprintを取得できます。

$ ssh-keyscan gitlab.com
# gitlab.com:22 SSH-2.0-GitLab-SSHD
gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
# gitlab.com:22 SSH-2.0-GitLab-SSHD
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
# gitlab.com:22 SSH-2.0-GitLab-SSHD
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
# gitlab.com:22 SSH-2.0-GitLab-SSHD
# gitlab.com:22 SSH-2.0-GitLab-SSHD

ただし、httpsのURLでアクセスするWebサイトやWeb APIでは得られた情報の真正性がTLSの仕組みによって担保される3のに対して、ssh-keyscanではそのような検証は行われないため、StrictHostKeyCheckingaskの時と同様の危険性があります。

自分達で管理しているホストの場合には、セットアップ作業の過程などでホスト上でssh-keyscan localhostを実行して得られた情報を控えておき、関係者間で安全な方法でknown_hostsの情報を共有するようにするとよいでしょう。 そうでない場合は、異なるネットワークにいる人同士複数人でssh-keyscanを実行して結果を突き合わせるなどして、結果の真正性を確かめる必要があります。

なお、StrictHostKeyCheckingyesにすると、頻繁にVMを作成・破棄することが多いケースではホストキーの再登録の手間が頻繁に生じます。 そのような場合には、利用者ごとの.confを使って次のようにパターンを明示して、VMに使用するホストをStrictHostKeyCheckingの対象から除外するとよいでしょう。

# 信頼できる192.168.1.*の範囲(宅内LANを想定)でホストキーの変更があればユーザーに問い合わせる設定例
Host 192.168.1.*
   StrictHostKeyChecking ask

もしくは、ssh -o StrictHostKeyChecking=askで一時的にデフォルトのaskにして接続することもできます。

おわりに

今回は、おすすめ.ssh/config設定について解説をまじえて紹介しました。

おすすめ設定とはいっても、単なる雛形でしかありません。 実際の利用においては個々のユースケースにあわせてカスタマイズが必要です。

また、一度設定すればそれで終わりではありません。 定期的により安全とされる内容に見直しすることも重要です。

もし秘伝のタレ化した.ssh/configが手元にあるなら、これを機会に見直してみるのもいいかもしれません。 こんなおすすめ設定があるよ、というのがあればぜひMerge Requestを https://gitlab.com/clear-code/ssh.d に送ってください。

  1. 設定の優先順については、man ssh_configの冒頭に明記されています。

  2. あえてパスワードで接続したい場合には、特定のホストでのみ許可するように.confの設定を追加するか、十分に信頼できる接続先のホストであればssh -o PasswordAuthentication=yesで一時的に有効化して接続するなどする必要があります。

  3. WebブラウザーやWeb APIのクライアントは、httpsでの接続先のホストが本当にそのドメインの持ち主の物かどうかを証明書チェーンを使って検証した上で、ホストとの間で安全な経路で通信します。そのため、レスポンスとして得られたknown_hostsのエントリは第三者によって改竄されていない正しい物であることが保証されます。