<ins>
今だったら(OpenSSH 7.3以降なら) ProxyJump
オプションや、コマンドラインオプションの -J
を使うのがオススメ。
例えば、踏み台サーバーが複数あるとき(bastion1,bastion2)に、その奥のhostAに繋ぎたい時、とかでも↓みたいなコマンドで一発
ssh -J bastion1,bastion2 hostA
</ins>
以下古い記事
背景
kawazさんの「最強のSSH踏み台設定」が凄く素敵で、早速設定してみたのだけど、どうやら HostName
を設定すると上手くいかないっぽい。
DHCPとか名前解決がちゃんとしている環境だと別に HostName
は設定しなくても問題ないのだけど、IPベースだけど別名つけてsshしたい時がある。
例えば、
Host hostA
Port 10022
HostName 192.168.0.50
Host hostA+*
Port 10022
HostName 192.168.0.50
Host *+*
ProxyCommand ssh -E /dev/null -W "$(<<<"%h" cut -d+ -f1)":%p "$(<<<"%h" cut -d+ -f2-)"
# `sed` だと最長/最短マッチがわかりづらかったので `cut` に変えてます。
みたいな設定を書いて、
$ ssh hostA+fumidai.example.com
で、 fumidai.example.com
を踏み台にしつつ、その先で 192.168.0.50
に繋ぎたいみたいなケース。
この設定だと ProxyCommand
の "%h"
が 192.168.0.50+fumidai.example.com
ではなく、ただの 192.168.0.50
になってしまい踏み台の情報が欠損してちゃんと動かない。
あと、ホストの設定を書くときに、経路も含めて全部 Host
に指定しないといけないのが個人的に、ぐぬぬという感じ。
特にノートパソコンみたいに持ち運びの多いマシンだと、踏み台が必要な時と必要じゃない時とで経路が複数ありうるので、できる限り *
でサボりたい。
怠惰はプログラマのたしなみ。
ということで、ちょこっと書き換えてみた。
.ssh/config
変更後のはこんな。
Host hostA
Port 10022
HostName 192.168.0.50
Host hostA+*
Port 10022
HostName 192.168.0.50_%h
Host *+*
ProxyCommand ssh -E /dev/null -W "$(<<<"%h" cut -d+ -f1 | cut -d_ -f1)":%p "$(<<<"%h" cut -d+ -f2-)"
変更点としては、 HostName
の末尾に _%h
を加えたのと、 ProxyCommand
に | cut -d_ -f1
を加えてます。
アイデアとしては、 HostName
の設定にIPアドレスだけを書くと、 %h
が上書きされてしまうので、 Host
の +*
の部分(e.g. +fumidai.example.com
)をIPアドレスの末尾にくっつけたい。
ところが、 HostName
の定義部で使えるのは Host
全体を表す %h
だけで、かつ、シェルを解釈してくれないので、 ProxyCommand
でやっているような sed
や cut
での加工ができない。
そこで、 HostName
の定義では、適当なデリミタを挟みつつ、単に %h
を後ろに足して、その上で ProxyCommand
でホスト別名を削る、という感じです。
デリミタにはアンダースコアを使っていますが、単にホスト名に使えない文字だから使っているだけなので、+
同様、ホスト名の定義と混ざりづらければなんでもokです。
(最初は #
を使ってみてたのですが、vimのシンタックスハイライトが死ぬので _
にしてます。意味合い的には「後ろのホスト別名を読み飛ばす」という気分なので #
を使いのですが……。)
結果、
$ ssh hostA+fumidai.example.com
を実行したときには、 ProxyCommand
は
# %h=192.168.0.50_hostA+fumidai.example.com / %p=10022
ProxyCommand ssh -E /dev/null \
-W "$(<<<"192.168.0.50_hostA+fumidai.example.com" cut -d+ -f1 | cut -d_ -f1)":10022 \
"$(<<<"192.168.0.50_hostA+fumidai.example.com" cut -d+ -f2-)"
# ↓
ProxyCommand ssh -E /dev/null \
-W "$(<<<"192.168.0.50_hostA" cut -d_ -f1)":10022 "fumidai.example.com"
# ↓
ProxyCommand ssh -E /dev/null -W "192.168.0.50":10022 "fumidai.example.com"
となって、めでたく fumidai.exmaple.com
を踏み台にしつつ、 192.168.0.50
(=hostA
) に繋ぐことができるようになりました。
+
で切り分けたあとで、 _(ホスト別名)
部分を切り取るので、多段の途中だったり、経路中に何度もホスト別名が出てきてもokです。
また副産物として、経路によらず、ホスト別名ごとの設定をまとめて書くことができる様になりました。
踏み台が複数あって環境によって変えないといけない、という時でも、この一つの設定で ssh hostA+some-fumidai.example.com
でも ssh hostA+another-fumidai.example.com
でも、あるいは ssh hostA+hostA+hostA+example.com
でも、いけるようになります。
最後のは完全ネタですが、なんにせよ経路の自由度が増えるのは、なにかと便利です。
ということで、 EoQ