WireGuardのSplit Tunneling活用術:VPNによるネットワーク遅延を解消する

Network tutorial - IT technology blog
Network tutorial - IT technology blog

なぜFull Tunnelは生産性の「悪夢」なのか?

会社のサーバーにSSH接続するためにVPNをオンにした途端、Google Meetのビデオ会議がフリーズしてしまった…。あるいは、YouTubeの解説動画を見ようとしても、読み込みの円が回り続けるだけ.これらはデフォルトのFull Tunnel設定が引き起こす問題です。この設定では、PCからのすべてのデータが、インターネットに出る前に狭いVPNトンネルを通過することを強制されます。

私はかつて50人規模のオフィスのインフラ管理をしていました。WireGuardを導入した当初、全員にデフォルト設定を配布したところ、わずか15分で技術部門から「ネットが重すぎる」と苦情の嵐が来ました。実際、彼らがVPNを必要としていたのはデータセンターのIP帯域(10.0.0.0/24)へのアクセスだけでした。しかし、VPNはFacebookやNetflixへのトラフィックまで「飲み込んで」いたのです。その時、すぐにSplit Tunnelingに切り替える必要があると痛感しました。

Split Tunneling(スプリットトンネリング)は、データフローをスマートに分離します.重要でセキュリティが必要なものはVPNを通し、それ以外の一般的なデータはプロバイダー(ISP)の回線へ直接流します。これにより、VPNサーバーの負荷を最大80%削減し、オンライン会議やゲーム時の遅延(レイテンシ)を最小限に抑えることができます。

核心となる概念:WireGuardのAllowedIPs

Split Tunnelingの鍵はAllowedIPsというパラメータにあります。複雑なスクリプトを必要とした古いプロトコルとは異なり、WireGuardはこのIPリストを使って2つの役割を果たします。1つ目は、どのIP宛のパケットを暗号化してトンネルに送るかの決定。2つ目は、トンネルから受信したパケットの送信元アドレスが妥当かどうかのチェックです。

もしAllowedIPs = 0.0.0.0/0と設定していれば、それはFull Tunnelです。Split Tunnelに切り替えるには、必要な内部IP帯域だけを正確にリストアップするだけで済みます。

実践1:IP帯域(CIDR)によるルーティング

例えば、オフィスのサーバー192.168.10.0/24にあり、Dockerサービスが172.16.0.0/16で動作しているとします。これら2つの帯域にアクセスする時だけVPNを使用したい場合を考えます。

/etc/wireguard/wg0.confにある設定ファイルを開きます:

sudo nano /etc/wireguard/wg0.conf

[Peer]セクションを以下のように編集します:

[Interface]
PrivateKey = <YOUR_PRIVATE_KEY>
Address = 10.0.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = vpn.company.com:51820
# 内部IP帯域とVPNサーバー自体のIPのみをルーティング指定
AllowedIPs = 192.168.10.0/24, 172.16.0.0/16, 10.0.0.1/32
PersistentKeepalive = 25

簡単な解説:

  • 192.168.10.0/24: LANサーバー用。
  • 172.16.0.0/16: 内部コンテナサービス用。
  • 10.0.0.1/32: リモート管理用のVPNサーバー自体のIP。

保存後、インターフェースを再起動します:

sudo wg-quick down wg0 && sudo wg-quick up wg0

この状態でip routeコマンドを叩くと、指定したIP帯域がwg0を経由していることがわかります。一方で、デフォルトのトラフィックは依然として自宅のルーターを経由します。

実践2:ドメイン名によるルーティング

WireGuardは本来、AllowedIPsでドメインを直接サポートしていません。ドメインを入力しても、起動時に一度だけIP解決が行われるだけです。サーバーのIPが変わると接続が切れてしまいます。解決策は、PostUpスクリプトとdigコマンドを組み合わせることです。

wg0.confを以下のように更新します:

[Interface]
PrivateKey = <YOUR_PRIVATE_KEY>
Address = 10.0.0.2/24
# VPN起動時にドメインのIPを自動取得してルーティングテーブルに追加
PostUp = ip route add $(dig +short internal.corp.com | tail -n1)/32 dev wg0
PostDown = ip route del $(dig +short internal.corp.com | tail -n1)/32 dev wg0

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = vpn.company.com:51820
AllowedIPs = 10.0.0.0/24

digコマンドを使用するために、sudo apt install dnsutilsdnsutilsをインストールしておくのを忘れないでください。

DNSリーク(DNS Leak)問題を完全に解決する

IPのルーティングは正しいのに、社内サイトにアクセスできないという問題によく直面します。原因の多くは、PCが依然としてプロバイダーのDNSサーバーに問い合わせており、プロバイダー側が社内のプライベートドメインを知らないことにあります。Ubuntu 20.04以降を使用している場合、systemd-resolvedが非常に役立ちます。

[Interface]セクションに以下のスマートな設定を追加します:

DNS = 10.0.0.1, corp.com

この設定により、ドメインが.corp.comで終わる場合のみVPNサーバー(10.0.0.1)に問い合わせるよう強制されます。GoogleやFacebookなど、その他のアクセスはデフォルトのDNSを使用するため、最適な速度が維持されます。

実際の動作確認

設定が終わったら、以下の3つのステップで正しく動作しているか確認しましょう:

  1. ルーティングテーブルの確認: ip route showを実行します。内部IP帯域がdev wg0を向いていることを確認してください。
  2. パブリックIPの確認: curl ifconfig.meを実行します。結果がVPNのIPではなく、契約しているプロバイダー(ISP)のIPであることを確認します。
  3. 内部へのPingテスト: ping 192.168.10.1を実行します。疎通が取れれば成功です。

まとめ

Split Tunnelingをマスターすることで、WireGuardの運用は格段に洗練されます。システム全体を低速なネットワークに巻き込む代わりに、わずか5分の設定で必要なものだけを選別できます。このアプローチはサーバーリソースを節約し、快適な作業環境を維持するために不可欠です。ぜひ設定に挑戦してみてください!

Share: