LoginSignup
28
28

More than 1 year has passed since last update.

「最強のSSH踏み台設定」でHostName使いたい

Last updated at Posted at 2015-11-18

<ins>
今だったら(OpenSSH 7.3以降なら) ProxyJump オプションや、コマンドラインオプションの -J を使うのがオススメ。

例えば、踏み台サーバーが複数あるとき(bastion1,bastion2)に、その奥のhostAに繋ぎたい時、とかでも↓みたいなコマンドで一発

ssh -J bastion1,bastion2 hostA

</ins>

以下古い記事

背景

kawazさんの「最強のSSH踏み台設定」が凄く素敵で、早速設定してみたのだけど、どうやら HostName を設定すると上手くいかないっぽい。

DHCPとか名前解決がちゃんとしている環境だと別に HostName は設定しなくても問題ないのだけど、IPベースだけど別名つけてsshしたい時がある。

例えば、

.ssh/config
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

変更後のはこんな。

.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 でやっているような sedcut での加工ができない。

そこで、 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

28
28
0

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
28
28