以前から気になっていた、NAT ごしに UDP 通信を行う, UDP Hole Punching の実験を NetCat(ports: net/netcat) を使って行ってみました。
1. (A)ホスト側端末(Firewall なし), WAN IP アドレス: 10.0.1.2
nc -lup 1234 -v # UDP の 1234 番で LISTEN
2. (B)クライアント側端末(ルータあり), 端末の IP アドレス: 192.168.1.100, ルータの WAN IP アドレス: 10.0.5.6
nc -u -p 5678 10.0.1.2 1234 # 10.0.1.2 の UDP 1234 に接続
3. (B) で Hello を入力
4. (A) に以下のようなログが出る
connect to [10.0.1.2] from ********* [10.0.5.6] 50000
Hello
(この例では 10.0.5.6 の UDP50000ポートからの送信があった。クライアント側 NAT で送信元ポートが書きかわっている事に注意)
5. (A), (B) 両方で netcat を一度終了させる
6. (B) で, 先程送信元にしたポートに対して UDP 受信を開始する(src port, dst port の入れ換え)
nc -lup 5678 -v
7. (A) で, 先程 LISTEN していたポートから、(4) で送信元になっていた IP アドレス、ポートに対して接続を開始する
nc -u -p 1234 10.0.5.6 50000
8. (A) から Hello over NAT を送信
9. (B) で以下のようなログが表示される
connect to [192.168.1.100] from ********* [10.0.1.2] 1234
Hello over NAT
両方が NAT 内にいる場合、双方について source port が書きかわるため、(A),(B) が通信することが不可能になります。
この場合、双方の source port を記録するための非 NAT 内ホスト端末 (C) が必要です。
ただし、双方が Symmetric NAT 内にいる場合は、宛先のポート番号に対して送信元の IP アドレス、ポート番号が固定されるためこの方法を用いることができません。
参考:
– P2Pとファイアウォール
– ごろ猫ブログ
– みかログ
– IT media エンタープライズ:PART2 Skype, その通信の仕組み