【テクニカル・上級編】 VPN接続におけるDNSリークの発生原因と対策 – サイバーセキュリティとプライバシー保護実践ガイド

DNSリークという「穴」:VPNトンネルの裏側で漏れ出すプライバシー

カフェの片隅で、あるいは空港のラウンジで。我々エンジニアが「セキュアなVPNを張ったから安心」と高を括っているその裏で、パケットはしばしば期待を裏切る挙動を見せる。

VPNクライアントが接続を確立し、tun0 や tap0 といった仮想インタフェースが up になった瞬間、我々は全てのトラフィックが暗号化トンネルへ流れると信じている。だが、現実はそう甘くない。OSのネットワークスタックは、時に「最短距離」を求めてトンネル外のゲートウェイへ、ISPが提供するデフォルトのDNSサーバーへクエリを投げつけてしまう。これがDNSリークだ。

今回は、パケットレベルの挙動からこの脆弱性を解剖し、インフラアーキテクトとしてどう防壁を構築すべきか、その「現場の流儀」を語ろう。

—

なぜ「トンネル」の中に穴が開くのか

DNSリークの根源は、OSのDNSリゾルバの優先順位にある。Linux環境であれば /etc/resolv.conf がその象徴だ。

VPN接続時、VPNサーバーからプッシュされたDNS設定が systemd-resolved や NetworkManager によって適用される。しかし、複数のネットワークインタフェースが存在する場合、OSはクエリを投げる「最も速い」あるいは「最も優先度の高い」パスを選択する。たとえVPNが default route を奪取していても、OSが特定のドメイン解決にISPのローカルDNSを直接叩いてしまえば、VPNの暗号化レイヤーは完全にバイパスされる。

パケットキャプチャを仕掛けてみるといい。tcpdump -i any port 53 を走らせた瞬間、暗号化されたVPNパケットの中に混ざって、平文の UDP/53 パケットがISPのDNSサーバーへ向かって飛び出していく様が見えるはずだ。これは、プライバシーの漏洩であると同時に、DNSハイジャックのリスクに自ら扉を開いていることに他ならない。

—

現場で叩き込むべき「DNSリーク封じ」の処方箋

DNSリークを完全に封じ込めるには、単なるルーティングの調整では不十分だ。以下の3段構えで防御を固める必要がある。

1. systemd-resolved の厳格な制御

現代のLinuxディストリビューションでは、systemd-resolved が名前解決のハブとなっている。これをVPNのセッションに強制的に従わせる設定が必要だ。

# /etc/systemd/resolved.conf を編集
[Resolve]
# ISPのDNSを使わせない。VPN経由のDNSのみを信頼する
DNS=10.8.0.1  # VPN内のDNSサーバーを指定
DNSStubListener=yes
# LLMNRやmDNSを無効化し、クエリが外部に漏れるのを防ぐ
LLMNR=no
MulticastDNS=no

2. ルーティングテーブルの「強制収容」

iptables あるいは nftables を用い、tun0 以外のインタフェースから発生する UDP/53 を遮断する。これは強硬手段だが、最も確実だ。

# eth0(物理NIC)経由の外部DNS通信をDROPする
iptables -A OUTPUT -o eth0 -p udp --dport 53 -j DROP
iptables -A OUTPUT -o eth0 -p tcp --dport 53 -j DROP

# VPNインタフェース経由のみ許可
iptables -A OUTPUT -o tun0 -p udp --dport 53 -j ACCEPT

3. トランスポート層の最適化:DoH (DNS over HTTPS) の活用

DNSクエリそのものを HTTPS で包み込み、TLS で保護する。これにより、たとえパケットが漏れたとしても、中身をISPに覗かれることはない。dnsmasq をフロントに置き、cloudflared を使ってDoHへリレーさせる構成が、現在もっとも堅牢なアーキテクチャだ。

—

パフォーマンスとセキュリティのトレードオフ:RTTとTCPバッファ

DNSリーク対策を施すと、どうしても名前解決のホップ数が増え、RTT (Round Trip Time) が悪化する。ここで、インフラエンジニアとしての腕が試される。

TLSハンドシェイクのオーバーヘッドを削減するため、TLS 1.3 を強制し、0-RTT (Zero Round Trip Time) を活用すべきだ。また、TCPバッファのチューニングも重要だ。VPN経由の通信は、MTU調整不足によるフラグメンテーションが多発しやすい。MSS (Maximum Segment Size) を調整し、VPNヘッダー分(通常50〜60バイト)を考慮した値を設定することで、パケットロスを最小限に抑えつつ、スループットを最大化できる。

# sysctl.conf でTCPバッファを最適化
# ネットワークの遅延が大きいVPN環境では、バッファを大きめにとる
net.core.rmem_max = 26214400
net.core.wmem_max = 26214400
net.ipv4.tcp_rmem = 4096 87380 26214400
net.ipv4.tcp_wmem = 4096 65536 26214400

—

最後に:ネットワークを「信じない」というプロの姿勢

ゼロトラストの要諦は、ネットワーク境界を信用しないことにある。「VPNを張ったから安全」という幻想を捨て、OSが発するパケット一つひとつがどこへ向かっているのかを常に監視する。

DNSリークは、単なる設定ミスではない。OSという巨大なブラックボックスが、利便性を優先してセキュリティを犠牲にしようとする「本能」のようなものだ。その本能を制御し、パケットを意図したトンネルへ押し込むことこそが、我々インフラエンジニアの職人芸である。

さあ、今すぐ tcpdump を立ち上げ、君のネットワークを覗いてみてほしい。そこに「意図せぬ光」が漏れていないことを祈る。

コメント

タイトルとURLをコピーしました