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

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

結論

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


検証

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

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

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

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

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

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

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

DestinationGateway
0.0.0.0/0Client VPNサブネットのルーター
VPC CIDRClient VPNサブネットのルーター
3. 正常なスプリットトンネルのルート設定

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

DestinationGateway
VPC CIDRClient VPNサブネットのルーター
解説

上記のルートテーブルから、推測できることは

  1. フルトンネルの場合:すべての通信をVPN経由にするため、VPN接続を維持するための「例外ルート(VPNエンドポイント宛ての通信はインターネット経由にする)」が自動でプッシュされます。
  2. スプリットトンネルの場合:VPCへの通信など、特定の通信のみをVPN経由にするのが前提です。そのため、上記のような例外ルートはプッシュされません。
  3. 問題発生スプリットトンネルの設定で 0.0.0.0/0 ルートが残っていると、2.の仕様により例外ルートがプッシュされません。その結果、VPNエンドポイントへの通信もVPNトンネル(0.0.0.0/0のルート)を通ろうとしてしまい、接続と切断が無限に繰り返されてしまいます。
補足

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

AWSのドキュメントでも、スプリットトンネルの0.0.0.0/0ルートは動作が不安定になるため、非推奨と記載があるので、変更する際はお忘れ無く!

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

以上、フルトンネルからスプリットトンネルへ移行する際の一助となれば幸いです。