TCP Proxy (port bridge) 色々

(2005/03/12追記: proxy.c が消滅したので ucspi-proxy に変更。 コンバータの関係でフォーマットがずたずただったのを訂正。 少し説明を追加。)

サーバ管理やらデバッグやらしていると、たまにあるマシンのポートを他の マシンのポートへそのまま中継したくなることがある。 ここではいくつかの方法を紹介……というかメモしておく。

* ucspi-tcp + ucspi-proxy

ucspi-tcp と言うのは、DJB 作のコンパクトな inetd みたいなものだ。 inetd と違って 1 つのポートしか listen 出来ないが、セキュリティへのの配慮や 環境変数を使った情報の受渡しなどの機能が有る。実際に qmail や djbdns を 動かすために使われているのはこれだったりする。

能書きはいいとして、以下のようなコマンドを実行すればOK.

tcpserver -RHl0 <bindaddress> <listenport> \
tcpclient -RHl0 <targethost> <targetport> ucspi-proxy

ログが取りたい時は同じく ucspi-tcp パッケージに含まれる recordio が便利。

tcpserver -RHl0 <bindaddress> <listenport> \
tcpclient -RHl0 <targethost> <targetport> recordio ucspi-proxy

として間に挟むと全部 stderr に dump してくれる。

* netcat

netcat は元々 @stake という会社で開発されていたのだけれど、 最近 GNU netcat という名前で継続しているみたい。 telnet のかわりになったり、ポートスキャナとして使えたり 簡易 inetd になったりする汎用ソフトウェア。 @stake 在りし日は "network knife" と紹介されていたりした。

ただ、ucspi-tcp と違って UDP が扱えるというメリットがあるけれど、 listen モードにしても fork してくれないので、1回接続を処理すると終わってしまう。 ともあれブリッジの仕方。

新しいバージョンの GNU Netcat では tunnel オプションが追加されたのでお手軽に出来る。

nc -p <listenport> -L <targethost>:<targetport>

古い netcat の場合は named pipe を作れば出来る。

mknod ncloop p
nc -l -p <listenport> < ncloop | nc <targethost> <targetport> > ncloop

こちらはログ取りたいなら tee を挟むとか(ほんとか?)。

* linux netfilter (iptables)

iptables -t nat -A PREROUTING -j DNAT -p tcp -i <interface> \
--dport <port> --to <target-addr>
iptables -I FORWARD -j ACCEPT -p tcp -i <in-interface> \
-o <out-interface> --dport <port>

* linux ipmasqadm (ipchains)

ipmasqadm portfw -a -P tcp -L <bindaddress> <listenport> \
-R <targetaddres> <targetport>