VPNの「魔法」を紐解く:暗号化オーバーヘッドとパケットの裏側にある真実
ネットワークエンジニアやアーキテクトであれば、「VPNを繋ぐと速度が落ちる」という事実は、もはや空気のような前提条件として受け入れているはずだ。しかし、その「落ちる」という現象の正体を、パケットレベルの挙動やCPUサイクル、そしてカーネル空間でのコンテキストスイッチまで分解して説明できるだろうか?
本稿では、個人向けVPNという文脈を入り口にしながら、暗号化がスループットとCPU負荷に与える物理的な制約、そしてそれを極限までチューニングするための「現場の知恵」を共有する。
—
1. 暗号化の代償:CPUサイクルとコンテキストスイッチ
VPNの通信は、平文のパケットをカプセル化し、さらに暗号化という「重たい」処理を課す。ここで最も無視できないのが、AES-NI(Advanced Encryption Standard New Instructions)のようなハードウェアアクセラレーションを利用できない環境での、CPU負荷の爆発だ。
パケット処理のボトルネック
VPNクライアント(OpenVPNやWireGuard)がパケットを処理する際、以下のプロセスが繰り返される。
1. 暗号化処理: 送信側のアプリケーション層から降りてきたパケットに対し、AESやChaCha20などのアルゴリズムを適用。
2. コンテキストスイッチ: ユーザー空間で動作するVPNデーモンと、カーネル空間のネットワークスタック間での頻繁なデータコピー(copy_to_user / copy_from_user)。
3. MTU問題: カプセル化によるヘッダー付与でパケットサイズが物理MTUを超過し、断片化(Fragmentation)が発生。これが再送制御やパケットロスを誘発し、TCPのRTT(Round Trip Time)を劇的に悪化させる。
2. なぜWireGuardは「速い」のか?
OpenVPNがTLSハンドシェイクという重厚なプロセスを抱え、頻繁なコンテキストスイッチを強いられるのに対し、WireGuardはLinuxカーネル内部で動作する。これにより、ユーザー空間とカーネル空間の行き来を最小限に抑え、CPUのキャッシュ効率を劇的に向上させている。
ここで重要なのは、トランスポート層での「バッファチューニング」だ。VPN経由でスループットを稼ぐためには、カーネルのネットワークパラメータを適切に追い込む必要がある。
# sysctl.conf でのチューニング例
# TCPウィンドウサイズを拡大し、高遅延環境でのスループット低下を防ぐ
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# BBR輻輳制御アルゴリズムの有効化(パケットロスに強い通信を実現)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
この設定を行うだけで、VPNトンネル内のTCPストリームは、パケットロス発生時でも再送待ちによる「詰まり」を起こしにくくなる。特にモバイル環境のような、電波状況が不安定なパブリックWi-Fiでは、bbrの恩恵は計り知れない。
3. 暗号化のオーバーヘッドを最小化する戦略
暗号化そのものを軽くすることはできないが、オーバーヘッドを「隠蔽」することは可能だ。
MTU/MSSクランプの最適化
VPN接続時、パケットの断片化を避けることはパフォーマンスの鉄則だ。ヘッダーサイズを考慮し、適切にMSS(Maximum Segment Size)をクランプする。
# iptablesを使用したMSSクランプ設定の例
# TCPパケットのヘッダーを修正し、MTU超過による断片化を強制的に抑制
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
ヘッダー圧縮の導入
OpenVPNなどでは、LZOやLZ4といった圧縮アルゴリズムが用意されている。しかし、現代の通信(すでに暗号化・圧縮済みのHTTPSトラフィックなど)に対してこれを行うのは無駄なCPU消費でしかない。もしあなたがインフラ担当者なら、「圧縮は無効化し、CPUを暗号化処理に全振りさせる」のが現代の最適解だ。
4. 結び:エンジニアが直視すべき「境界」の行方
VPNは単なる「安全なトンネル」ではない。それは、ネットワークスタックにおけるパケットのライフサイクルを強制的に書き換える「侵入者」である。
CPU負荷を抑え、スループットを極限まで引き出すためには、以下の3点を見極めることだ。
1. ハードウェアの特性: 端末がAES-NIをサポートしているか。サポートしていない場合、ChaCha20-Poly1305を採用するWireGuardが圧倒的に有利だ。
2. TCP vs UDP: VPNのトランスポートとしてTCPを選択するのは「TCP over TCP」という最悪のパフォーマンス低下(TCP Meltdown)を招く。必ずUDPベースのVPNプロトコルを選択すること。
3. カーネルの最適化: 現代のネットワークスタックは十分に高速だが、デフォルト設定は汎用的すぎる。BBR等の輻輳制御やTCPバッファの調整は、VPN利用時の必須スキルである。
セキュリティとパフォーマンスはトレードオフの関係にあると思われがちだが、プロトコルの挙動を理解し、カーネルの深部を制御できれば、その溝は埋められる。パケットが光の速度で駆け巡り、一瞬のうちに暗号化されていくその背後には、エンジニアによる緻密な計算とチューニングが存在しているのだ。
次回の記事では、この暗号化のレイテンシをさらに削るための、eBPFを用いたパケットフィルタリングの自動化について深く掘り下げていこう。
コメント