Sunday, January 13, 2013

L2 over SSH


このところ ssh tunnel ネタが多いが、実は ssh を使って port forwarding だけではなく、L3トンネルや L2トンネルを作れるのはそんなに知られていないように思う。実際、自分も Software Design 2012/10月号の、川本(@togakushi)さんの記事「SSH力をつけよう!」を読むまで知らなかった。

余談だが、この記事は本当にすばらしい。chef 特集につられて買った号だったのだが、編集部の気合いを感じた一冊だった。


まず、L3トンネルのやり方から。
port forwarding とは違い、今度はオプションに -L ではなく -w を使う。
例えば

  $ ssh -w 0:0   root@remote_host

とすれば、ローカルとリモートの双方に tun0 という tunnel device (tun) が作成され、
-w の指定値は、

  $ ssh -w any:any   root@remote_host

のように、any:any とすれば、tun1 とか tun2 とか、ローカルリモートそれぞれで tunnel device 番号の空きの若いものから自動的に採番してくれる。

こうして作成した tunX にそれぞれ適切に IP address を割り当てれば IP レベル(L3 レベル)で通信できるようになる。


ところで、この仮想化の時代、L3トンネルが張れるなら、L2 トンネルも張れないのか?と思うのが、人情だと思う。Software Design の記事では、スペースの関係か触れられていないのだが、実は、以下のように ssh のオプション指定によって、tunnnel device (tunX)だけでなく、Encapsulation が Ethernet に見えるような L2 tunnel、つまり tap も作成できる。

  $ ssh -w any:any  -o Tunnel=ethernet  root@remote_host

tap を作成する場合もやはり -w は必要で、指定値は tun の時と同じように使われる。
つまり、tap1 なり tap9 なりと(空いていれば)好きな番号の tap device を作れる。
(1/17追記)
なお、/etc/ssh/sshd_config や /etc/ssh/ssh_config に TunnelPermit や Tunnel 等の指定値が明示的に記述されていると強制的に tun になってしまうことがあるので注意のこと。


さて、実はここからが本題である。
下図のようにHOST1 と HOST2 があるとして、この2台の間は、proxy なり、NATなり、(多段)port forwarding なりの何らかの手段で ssh 接続可能だとする。(多段)port forwarding については前にも書いたので参考まで。

図の赤い線で結んだssh 接続の間には proxy があっても NATがあってもよい。とにかく、HOST1とHOST2の間でssh接続し、上で説明したオプションを指定して tap を接続してしまうことによって、仮想的に1枚のL2面を作れたことになる。(通信品質についてはいわずもがななので、そこはつっこまないように)

さらに図のように、作成した tap をbridge で VMの仮想NICに接続してしまえば、踏み台の向こうの環境で動いているVMに対して、L2レベルで接続できるので、例えば HOST2 から HOST1 上のVMに対してDHCPでアドレスを払いだす…等といったことも可能である。
(HOST2の構成が図とはちょっと違うのだが)実際やってみたら、問題なく動くし、やろうと思えば3ノード以上でフルメッシュ構成にするのも可能である。(ループが発生しないように若干注意が必要だが...)
世の中では、VXLAN だの STT だの NVGRE といった L2 over L3 技術や、SPB やら TRILL (やそれらの拡張)といった L2 over L2 技術で百花繚乱状態だが、こういう poor man's solution もあるよということで(笑)

No comments:

Post a Comment