🚇

AWS Client VPN が接続と切断を繰り返す場合、インターネットルートが原因かも

はじめに

「フルトンネルだと通信料が高いからスプリットトンネルにしよう!」
そう思う方は多いかもしれませんが、その際に 0.0.0.0/0 ルートの設定削除を忘れると、Windows環境でVPNの挙動がおかしくなる現象に遭遇しましたので、その内容を共有します。

結論

AWS Client VPNをスプリットトンネルで利用する際、ルートテーブルに 0.0.0.0/0 ルートが残っていると、VPNを確立するための通信までVPNを経由しようとしてしまいます。その結果、Windows端末では接続と切断が繰り返されるループに陥ります。

検証

1. フルトンネルのルート設定

まず、フルトンネルのClient VPNを設定している状況を考えます。

フルトンネルでは、以下のようなルートテーブルが端末にプッシュされます。(説明に関係のないルートは省略しています)

Destination Gateway
0.0.0.0/0 Client VPNサブネットのルーター
Client VPN Endpoint IP クライアントデバイスのデフォルトゲートウェイ
  • 1行目:全ての通信をClient VPNサブネットのルーターに転送するためのルートです。
  • 2行目:VPN接続を確立するための通信(VPNエンドポイント宛て)を、インターネット(クライアント自身のデフォルトゲートウェイ)へ向けるための例外ルートです。これにより、VPN接続のための通信がVPNトンネルを通ってしまい、接続できなくなる事態を防いでいます。

2. スプリットトンネルへの変更(問題が発生するケース)

ここで、ルートテーブルに 0.0.0.0/0 ルートを残したまま、AWS Client VPNの設定をスプリットトンネルに変更してみます。

main.tf
resource "aws_ec2_client_vpn_endpoint" "this" {
  # (略)
  split_tunnel = true # ここを追記
}

0.0.0.0/0 ルートが残ったままなので、以下のルートテーブルが端末にプッシュされます。

Destination Gateway
0.0.0.0/0 Client VPNサブネットのルーター
VPC CIDR Client VPNサブネットのルーター

3. 正常なスプリットトンネルのルート設定

比較のために、正常なスプリットトンネルのルートテーブルを見てみましょう。VPCのCIDR宛ての通信のみがVPNを通るように、ルートが1つだけプッシュされていることがわかります。

Destination Gateway
VPC CIDR Client VPNサブネットのルーター

解説

上記のルートテーブルから、推測できることは以下の通りです。

  • フルトンネルの場合:すべての通信をVPN経由にするため、VPN接続を維持するための「例外ルート(VPNエンドポイント宛ての通信はインターネット経由にする)」が自動でプッシュされます。
  • スプリットトンネルの場合:VPCへの通信など、特定の通信のみをVPN経由にするのが前提です。そのため、上記のような例外ルートはプッシュされません。

問題発生のメカニズム:スプリットトンネルの設定で 0.0.0.0/0 ルートが残っていると、スプリットトンネルの仕様により例外ルートがプッシュされません。その結果、VPNエンドポイントへの通信もVPNトンネル(0.0.0.0/0 のルート)を通ろうとしてしまい、接続と切断が無限に繰り返されてしまいます。


補足

なお、この現象は Windows端末でのみ発生し、macOSでは再現しませんでした。

参考

https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/split-tunnel-vpn.html#split-tunnel-routing

Discussion