ncある限りぼくはどこまででもいけるッ!

多段SSHの話。

2008-05-02追記
ncの-w secオプションで、一定時間通信がなければncが終了するようにしました。このオプションを指定しないと、sshコネクションを切った後でもncのプロセスが残留してしまいます。
2010-03-08
OpenSSH 5.4以降のnetcat mode (ssh -W host:port ...) を使えば、ncコマンドは不要かも。
2010-11-08
zshでNo such file or directoryと言われるのは、これが原因かもhttps://bugzilla.mindrot.org/show_bug.cgi?id=1494

正攻法でこたつにアクセスするには下図のようなSSHアクセスを繰り返さなければならない、といった状況があるとする。

uchi ----> otonari
           otonari ----> genkan
                         genkan ----> kotatsu
uchi$ ssh otonari
otonari$ ssh genkan
genkan$ ssh kotatsu
kotatsu$ echo yatto tsuita

もう少しイメージがわきやすいように注を加えるとこうなる。

自社NW│  他社NW    │  他社NW
      │  の踏み台  │  の内部セグメント
━━━━━━━━━━━━━━━━━━━━━━━
uchi -│-> otonari  │
      │   otonari -│-> genkan
      │            │   genkan ----> kotatsu

これを、下図のように、ダイレクトにこたつに入れるようにするには、どうするのがスマートだろうか?

uchi -((-> otonari ----> genkan -))-> kotatsu


答えはこうだ:

$ cat ~/.ssh/config
Host  kotatsu
  ProxyCommand  ssh genkan  nc -w 10 kotatsu 22
Host  genkan
  ProxyCommand  ssh otonari nc -w 10 genkan  22
Host  otonari
  User          hirakegoma
  Port          7650

これで、

uchi$ ssh kotasu howareyou
atatatakainari

のように直接こたつにアクセスすることが可能となる。

ただし、前提として、各ホストでncコマンド (netcat, The GNU Netcat) が使える必要がある。(ncコマンド以外でも、connect.cなど、同様なもので代替可能である)


ポイントは、ProxyCommandでsshコマンドの引数として指定するホスト名は、ほかのHostキーワードで定義したものが使える、という点である。(冷静に考えるとこれは当然である。なぜなら、ProxyCommandはローカルで実行されるのであるから)

今回の例ではProxyCommandを使用しているのはkotatsuとgenkanの2段だが、この仕組みを利用すれば、幾重にもProxyCommandを重ねてどこまでも遠くへゆくことが可能となる。(たとえば、kotatsuの先にある、todana、oyatsuなど)


さて、直接アクセスできることの利点を考えると、先にみたように対話的なSSHログインがコマンド1つでできる他に、

  • scpやrsync -e sshでのファイルコピーが簡潔にできるようになる。
    • 中継ホスト (otonariやgenkan) に一時コピーをする必要がない。
  • rdiffを使い、uchiとkotatsuとの間でファイルの差分の確認をするのが簡潔にできるようになる。

といったものもあげられ、局面によっては大変、有益だといえる。

まとめ

最近、寒いのでまたこたつを出そうかと思っているの。