LoginSignup
160
104

More than 5 years have passed since last update.

`Include`キーワードで`ssh_config`を分割できるようになった件

Last updated at Posted at 2016-12-25

要約

  • 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の設定は基本的に先勝(先に定義されたものが優先される)なので、まずIncludeHost directiveを読み込んでからHost *で全体的な設定を行うのが良いです。

IncludeMatchHostの中にも置くことができますので記述順序には注意が必要です。例えば、下記のように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.zsh
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を使って管理できて便利です。

160
104
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
160
104