境界防御の幻想とWebRTCの「穴」:VPNを透過するIP暴露のメカニズムを解剖する
ネットワークエンジニアの端くれとして、VPNを接続した瞬間に「これで私の素性は守られた」と安堵するユーザーを見ると、つい苦笑いが漏れてしまう。なぜなら、パケットの挙動を追えば、VPNトンネルが確立されていても、ブラウザという名の「特権的な穴」からローカルの正体がダダ漏れになっている事実は珍しくないからだ。
今回は、現代のブラウザにおけるリアルタイム通信技術、WebRTC(Web Real-Time Communication)が引き起こすIPアドレス漏洩問題に焦点を当てる。これは単なる設定ミスではなく、設計思想の衝突が引き起こす「仕様上の脆弱性」だ。
—
1. WebRTCが突き破る境界線
WebRTCは、プラグインなしでブラウザ間でのP2P通信を実現するために生み出された。ビデオ会議やWeb電話を爆速で開始するために、通信経路を確立するプロセスで ICE (Interactive Connectivity Establishment) フレームワークを駆使する。
ここで問題になるのが、STUN (Session Traversal Utilities for NAT) プロトコルだ。クライアントはNATの内側から外側のグローバルIPを知るために STUN サーバーへ問い合わせを行うが、ブラウザはこの過程で、ホストが持つ全てのネットワークインターフェース(VPNの仮想NIC含む)を列挙し、候補(Candidate)として相手に送信してしまう。
結果として、VPN経由のパケットを待つはずの通信相手に対し、ブラウザは「私のローカルIPはこれだ」と、VPNをバイパスした生のインターフェース情報をわざわざ通知してしまうのである。これが「WebRTCリーク」の正体だ。
—
2. パケットレベルで紐解く「リーク」の挙動
WebRTCによるネゴシエーションが始まると、ブラウザは SDP (Session Description Protocol) を生成する。この SDP 内の a=candidate 属性には、以下のような情報が詰め込まれる。
a=candidate:1 1 UDP 2122260223 192.168.1.15 5000 typ host
# 192.168.1.15 はVPNを通さないローカルIPアドレス。これが相手に渡る。
本来、TLS でハンドシェイクを最適化し、RTT(Round Trip Time)を削り込むための工夫が、セキュリティの観点では「余計な情報」として機能してしまう。さらに厄介なのは、この通信が TCP や UDP の上位層で、ブラウザのランタイムによって独自に制御されている点だ。
—
3. 回避策:ブラウザレベルでの制御と「泥臭い」対策
インフラアーキテクトとして、組織内のエンドポイントを保護する場合、個々のユーザーの「VPN接続」に依存する運用はナンセンスだ。以下の対策を検討すべきである。
ブラウザの設定(ポリシーベース)
エンタープライズ環境であれば、Active Directoryのグループポリシーやブラウザのポリシー設定で、WebRTC の挙動を制限する。
- Firefox:
about:configでmedia.peerconnection.enabledをfalseにする。 - Chrome/Edge:
WebRTCIPHandlingPolicyをdisable_non_proxied_udpに設定する。
この設定により、STUN リクエストはプロキシ経由、あるいは完全に遮断され、ローカルIPの暴露を抑制できる。
Linuxカーネル/ファイアウォールでの制御
もしエンドポイントの制御が困難な場合、iptables や nftables を用いて、VPNインターフェース以外への STUN トラフィックを強制的にドロップさせるという荒技も有効だ。
# VPNインターフェース(tun0)以外からのSTUN通信(3478/udp)を拒否する例
# 完全に遮断するとWebRTCベースのサービスが死ぬため、必要に応じて許可リストを調整すること
nft add rule inet filter output oifname != "tun0" udp dport 3478 drop
—
4. ネットワークパフォーマンスとセキュリティのトレードオフ
WebRTC を完全に無効化することは、現代のコラボレーションツールを阻害することと同義だ。パフォーマンスを追求するならば、TURN (Traversal Using Relays around NAT) サーバーを自社インフラのDMZに構築し、全ての WebRTC 通信を自前のリレーサーバー経由に固定させるのがアーキテクトとしての「正解」である。
TURN を利用すれば、クライアントは直接相手のIPを知る必要がなく、TURN サーバーのグローバルIPのみを介して通信が完結する。
TURNサーバーの最適化のヒント
TURN サーバーを自前で運用する場合、以下の sysctl チューニングは必須だ。
# TCPバッファサイズの拡大(高スループット化)
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
# 接続数が多いサーバーでのポート範囲拡張
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
—
最後に:防御は「透過性」との戦いである
WebRTC のような技術は、ユーザー体験を最大化するために設計されている。しかし、その「透過性」こそがセキュリティエンジニアにとっては最大の敵となる。
VPNを接続しただけで安全を確信するのは、泥棒の目の前で金庫の暗証番号を喋っているようなものだ。プロトコルの仕様を理解し、どこで情報が漏れ、どのレイヤーで制御すべきかを見極めること。それこそが、境界防御が消え去りつつある現代のゼロトラスト環境において、我々技術者が持ちうる最強の武器である。
次回の記事では、QUIC プロトコルにおけるコネクションIDの追跡と、プライバシー保護の観点から見た次世代のハンドシェイク最適化について深掘りする予定だ。腕に覚えのある諸君は、期待していてほしい。
コメント