«前の日記(2014-12-24) 最新 次の日記(2015-01-26)» 編集

meta's blog - The Power To Serve

筆者について

FreeBSDを通じてOSSにささかな貢献を。

OSS活動をご支援いただける方を募集しています


2015-01-16 socat を使って IPv6 非対応のデーモンに IPv6 で接続する

socat を使って IPv6 非対応のデーモンに IPv6 で接続する

ちょっとした小技のメモ。

現在ではソフトウェアの IPv6 対応も進み、IPv4 と IPv6 の両方で LISTEN できるようになっているソフトウェアが多くなっています。ただ、依然 IPv4 でしか LISTEN できないソフトウェアも少なくありません。xrdp などがその1例です。

そこで、socat を使って IPv4 でしか LISTEN しないデーモンにも IPv6 で接続できるようにしてみました。 それぞれのループバックアドレスをポートフォワーディングでつなぐというからくりで、以下のコマンドで ::#3389 から 127.0.0.1:3389 に転送します。

$ socat TCP6-LISTEN:3389,fork TCP4:127.0.0.1:3389

ただしコレだと、IPv6 で接続するには socat を常に CLI から起動していないといけなくて、この程度のためにデーモンの起動スクリプトを書くのも大変なので、inetd を使って socat を起動することにします。

ここから先は FreeBSD での例です。他の OS の場合も似たような感じで適当に。

/etc/inetd.conf に以下の行を追加。細かいオプションなどはハンドブックから。inetd 経由で使う場合は、inetd から標準入出力経由で IPv4 の TCP ポートにつなぐので socat に指定するオプションが少し違います。

rdp     stream  tcp6    nowait  nobody  /usr/local/bin/socat    socat stdin tcp4:127.0.0.1:3389
rdp
サービス名・ポート番号 (/etc/services に書かれている名前で指定)
stream
ソケットタイプ TCP の場合は stream
protocol
IPv6 TCP のみ LISTEN するので tcp6 と指定
nowait
stream ソケットを使うので nowait
nobody
socat を実行するユーザ名
/usr/local/bin/socat
socat へのフルパス

/etc/rc.conf に inetd_enable="YES" と追加して inetd サービスを起動。

# service inetd start

あとは netstat などで tcp6 の目当てのポートを LISTEN していることと、接続できることを確認しておしまい。

こんな感じにデータが流れていって、IPv6 で来たパケットが IPv4 のポートに中継されていきます。

--[IPv6]--[inetd]--[socat]--[標準入出力]--[IPv4]--[daemon]