TCP通信は一般的にコネクションが張られるので、通信の仕組みが理解しやすいのですが
UDPについては一方通行で再送無しの印象が強く、どのようにパケットのやり取りをしているのか理解していない人も多いのではないでしょうか?
復習もかねてUDPパケットの代表サービスであるDNSのパケットキャプチャをしてみました。
レジュメ
結論、UDP通信は送信されたソースポートにパケットを返す
結論から言ってしまうと、例えばDNSというサービスのUDP通信を考えると、
- DNSサービスなので、DNSサーバーに宛先ポート53に向けてUDPパケットを飛ばします
- DNSサーバーはDNSクライアントの送信元ポートに対しUDPパケットを返信します
UDPで返信が必要な通信は上記のようになっています。
※ UDP通信の場合は、返信パケットがない通信(通信プログラムの作りに依存します)も存在します(例えば、Syslogとか)。
実際にDNS通信のUDPパケットキャプチャした結果
実際に以下のDNSのやり取りを発生させパケットキャプチャしてみました。
以下のように、DNSクライアントから、8.8.8.8(GoogleのDNSサーバー)に対しnslookupで名前解決をしてみました。
その結果のDNSクライアント側でのUDPパケットキャプチャが以下です。
DNSクライアント(192.168.25.x:60127)から、DNSサーバー(8.8.8.8:53)にUDP通信させたところ、
DNSサーバー(8.8.8.8:53)から、DNSクライアント(192.168.25.x:60127)にUDP返信が来ていることがわかります。
DNSクライアントで送信に使用したポートで、DNSサーバーからの返信をそのまま待っているというわけです。
TCPではなくUDPなので、パケットが返ってくる保証はないので、プログラム的にタイムアウト値を設ける必要がありますね。(windowsのnslookupの場合、タイムアウト値がデフォルトで2秒)
ファイヤウォールの設定ではこのUDPの戻り通信を考慮する必要はあるのか?
ほとんどのファイヤウォールではこのUDPの戻り通信の制御を意識して設定する必要はありません。
それは「ステートフルインスペクション」という機能で実装されているからです。
(少なくとも「FortiGate」では検証確認を取りましたので、UDPの戻りも「ステートフルインスペクション」で実現できます。)
ステートプルインスペクションとは、簡単いうと「戻り通信についても動的に許可する機能」のことです。
ステートプルインスペクションは、TCP通信だけにとどまらず、UDP通信につても有効です。
逆に言うと、このステートフルインスペクションを無効にすると、ファイヤフォールの設定・設計が超大変です(例えば、AWSのNACLとか)。