SSH Config の管理を捗らせる Include と、ホストを一覧表示するワンライナー

~/.ssh/config (SSH Config) というファイルに、SSH 接続情報を記載しておける。当然、コマンドをイチイチ打つより便利なので多用しているのだが、最近そろそろ登録ホスト数が増えてきて、1ファイルに書いておくのが大変になってきた。

そこで調べてみると、どうやら Include という命令文を使うと SSH Config の内容を別ファイルに切り出せるようだ。

Include config-something.conf

Include config-other.conf

こんな感じ。config-something.confconfig-other.conf というファイルは、~/.ssh/ ディレクトリ配下、config ファイルと同階層に置いておく。

ファイル名や拡張子は自由だが、自分は ~/.ssh/ ディレクトリ配下が煩雑にならないように、config-【任意文字列】.conf という名前で統一することにした。

Host でアスタリスク * を使える

ついでに、SSH Config の Host 定義では、アスタリスク * を使った一括指定ができたりするので、コレで記述量を少なくしたりもできる。

# Foo システムの踏み台サーバ
Host foo-system-bastion
  HostName        10.120.0.1
  User            bastion
  Port            22
  IdentityFile    ~/.ssh/key-foo-system-bastion

# Foo システムの AP サーバ・開発機
Host foo-system-ap-dev
  HostName        10.120.10.1

# Foo システムの AP サーバ・ステージング機
Host foo-system-ap-staging
  HostName        10.120.20.1

# Foo システムの AP サーバ 開発機・ステージング機に共通する設定
Host foo-system-ap-*
  User            admin
  IdentityFile    ~/.ssh/key-foo-system-ap
  Port            22
  ProxyCommand    ssh foo-system-bastion -W %h:%p

本来は Host foo-system-bastion のように、HostName、User、IdentityFile などを全部書かないといけないが、foo-system-ap-devfoo-system-ap-staging の2つは、HostName しか書いていない。

じゃあユーザ名や SSH 鍵はどこで指定しているの?というと、Host foo-system-ap-* という宣言部分。ココは HostName 以外の情報を指定して、アスタリスクを使い、「foo-system-ap- で始まる Host」に対する共通の指定を記述している。

SSH Config は記述した順に優先的に値が使用されるので、こうした共通的な内容は最後の方に書いておくと、同じ項目の指定が被った時に、個別に指定した方を優先できる。

SSH Config で宣言したホスト一覧を出力する

さて、Include によるファイル分割や、アスタリスクを使った共通事項の切り出しができて、たくさんのホスト情報を管理しやすくなった。

最後に、こうして記述した SSH Config のファイル群から、ホスト名の一覧を出力するためのワンライナーを紹介する。

$ grep -rh '^Host ' "${HOME}/.ssh/" | grep -v '*' | sed 's/Host /ssh /' | sort

~/.ssh/ ディレクトリ内の全ファイルから、行頭に Host と書いてある行を grep している。

コレだけだと、先程のようにアスタリスク指定した共通部分の情報も取得されてしまうので、grep -v でアスタリスクを含む行を除外している。

こうすると Host hoge とか Host fuga といった宣言部分の行が羅列される。ココまででも良いのだが、Host 部分の文字列を ssh と変えてやれば、そのままコピペして SSH 接続するためのコマンドになるので、sed で置換し、sort してある。

~/.bashrc などでエイリアスにするならこんな感じ。

alias sshls='grep -rh '\''^Host '\'' "${HOME}/.ssh/" | grep -v '\''*'\'' | sed '\''s/Host /ssh /'\'' | sort'

以上

SSH Config には、他にも exec で実行したコマンドの戻り値に応じて Host 定義を設定できる Match 機能などがあったりする。条件分岐みたいなこともできるワケなので、今後もどんどんその機能を活用していきたい。