要約
-
ssh_config
の分割にはInclude
キーワードが使えます -
Include
キーワードは2016-08-01リリースのOpenSSH 7.3から導入されています
Include
キーワード
先日、何気なくman ssh_config
していたところInclude
という便利キーワードの存在に気づきました。Include
キーワードは、どうやら2016-08-01にリリースされたOpenSSH 7.3で導入されたようです。
Include
でできること
$ man ssh_config
...
Include
Include the specified configuration file(s). Multiple pathnames may be specified and each pathname may contain glob(3) wildcards and, for user configurations,
shell-like ``~'' references to user home directories. Files without absolute paths are assumed to be in ~/.ssh if included in a user configuration file or
/etc/ssh if included from the system configuration file. Include directive may appear inside a Match or Host block to perform conditional inclusion.
...
説明を読むと、Include
キーワードを使うことで~/.ssh/config
の設定を別ファイルに切り出すことができることがわかります。
ファイルの分割方法
Include
キーワードを使うことで
$ cat ~/.ssh/config
Host hoge
HostName hoge.example.com
User hoge
IdentityFile ~/.ssh/id.pem
Host fuga
HostName fuga
Port 2222
User abc
IdentityFile ~/.ssh/abc.pem
Host xyz
HostName xyz.example.com
Port 2222
User abc
IdentityFile ~/.ssh/abc.pem
Host *
ServerAliveInterval 300
AddKeysToAgent yes
このような~/.ssh/config
を下記のように分割することができます。
ディレクトリー構成
今回は分割したファイルを$HOME/.ssh/conf.d/
配下に置くことにします。
$ tree ~/.ssh
/Users/masa0x80/.ssh
├── ...
├── conf.d
│ ├── commons
│ │ └── abc
│ └── hosts
│ ├── hoge
│ └── misc
├── config
└── ...
~/.ssh/config
の中身
Include
を使ってHost directive
を切り出してみます。
$ cat ~/.ssh/cofig
Include conf.d/hosts/*
Host *
ServerAliveInterval 300
AddKeysToAgent yes
ssh_config
の設定は基本的に先勝(先に定義されたものが優先される)なので、まずInclude
でHost directive
を読み込んでからHost *
で全体的な設定を行うのが良いです。
Include
はMatch
やHost
の中にも置くことができますので記述順序には注意が必要です。例えば、下記のようにHost directive
の後にInclude
を記載すると、ssh foo
の時にのみconf.d/hoge
が読み込まれるために、期待通りの挙動になりません。
Host foo
HostName ...
Include conf.d/hosts/*
~/.ssh/conf.d/hosts/hoge
の中身
hoge
に関する設定を単純にファイルに切り出しただけです。
$ cat ~/.ssh/conf.d/hosts/hoge
Host hoge
HostName hoge.example.com
User hoge
IdentityFile ~/.ssh/id.pem
~/.ssh/conf.d/hosts/misc
の中身
Host directive
を複数書くこともできますし、更にInclude
することもできます。
$ cat ~/.ssh/conf.d/hosts/misc
Host fuga
HostName fuga.example.com
Include conf.d/commons/abc
Host xyz
HostName xyz.example.com
Include conf.d/commons/abc
*
や?
を使って設定を書きにくい場合は、Host directive
の中でInclude
を使用して共通設定を読み込むと便利です。今回は下記の様にも書けますが、設定が大きくなってくるとInclude
を使った方が誤爆を防ぎやすいと思います。
Host fuga
HostName fuga.example.com
Host xyz
HostName xyz.example.com
Host fuga xyz
Port 2222
User abc
IdentityFile ~/.ssh/abc.pem
~/.ssh/conf.d/commons/abc
の中身
~/.ssh/conf.d/hosts/misc
から参照される設定値です。
$ cat ~/.ssh/conf.d/commons/abc
Port 2222
User abc
IdentityFile ~/.ssh/abc.pem
fzf
との連携
zshの場合
下記のような関数を準備しておくことで^s^s
と入力することで、ssh_config
に記載されているホスト名を補完することができて便利です。
なお、読み込むファイルは~/.ssh/config
と~/.ssh/conf.d/
配下のファイルになっているので適宜修正ください。
complete-ssh-host() {
local host="$(command egrep -i '^Host\s+.+' $HOME/.ssh/config $(find $HOME/.ssh/conf.d -type f 2>/dev/null) | command egrep -v '[*?]' | awk '{print $2}' | sort | fzf)"
if [ ! -z "$host" ]; then
LBUFFER+="$host"
fi
zle reset-prompt
}
zle -N complete-ssh-host
bindkey '^s^s' complete-ssh-host
fzf
の部分をpeco
に変更することでpeco
利用に変更することもできます。
fishの場合
拙作のcomplete_ssh_host.fish
を利用すると上記のzshと同等の処理(^s^s
で補完)ができるようになります。
fisherman
を使ってインストールする場合は下記で利用できます。
fisher masa0x80/complete_ssh_host.fish
あるいは、こちらも拙作のfresco
というプラグインマネージャーを使ってインストールする場合は下記となります。
$ # Install fresco
$ curl https://raw.githubusercontent.com/masa0x80/fresco/master/install | fish
$ exec fish -l
$ # Install plugin
$ fresco masa0x80/complete_ssh_host.fish
fresco
を使うとfishのスクリプトをghq
を使って管理できて便利です。