SSH Config の管理を捗らせる Include と、ホストを一覧表示するワンライナー
~/.ssh/config
(SSH Config) というファイルに、SSH 接続情報を記載しておける。当然、コマンドをイチイチ打つより便利なので多用しているのだが、最近そろそろ登録ホスト数が増えてきて、1ファイルに書いておくのが大変になってきた。
そこで調べてみると、どうやら Include
という命令文を使うと SSH Config の内容を別ファイルに切り出せるようだ。
~/.ssh/config
Include config-something.conf
Include config-other.conf
こんな感じ。config-something.conf
と config-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-dev
と foo-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
機能などがあったりする。条件分岐みたいなこともできるワケなので、今後もどんどんその機能を活用していきたい。