オープンなネットワークでは、アクセスポイントはパケットをそのままインターネットへ渡しません。上流のポリシーポイントが、端末がまだ認可されているかを確認し、認可されるまではほとんどすべてが破棄されます。VPNクライアントはその沈黙を「死んだサーバー」と読み取ります。めったにそうとは言いません:WireGuardは虚空へハンドシェイクを再試行し、OpenVPNは接続タイムアウトを報告し、IKEv2は応答しないリモートサーバーについてのエラー809として返ってきます。

ポータルが実際に制御しているもの

キャプティブポータルは、ポリシー決定点とリダイレクターというふたつのものが接ぎ木されたものです。端末が関連付けを行いDHCPリースを取得すると、ネットワークはあなたを認可前の状態に置きます。

その状態はファイアウォールのルールセットです。通常はDNSを許可し、短いポータルホスト一覧へのHTTPまたはHTTPSを許可し、それ以外はすべて破棄します。許可された一覧は「囲われた庭」であり、VPNのエンドポイントはほとんど含まれません。

この破棄はどれも礼儀正しいものではありません。VPNサーバー宛てのパケットは拒否ではなく破棄されるため、クライアントはICMP unreachableもTCP resetも受け取らず、応答がないだけです。ベンダーによっては、リダイレクターがポート80にサインインページへのリダイレクトで応答する一方、ポート443は破棄または傍受されます。リダイレクトは平文のHTTP応答を運ぶので簡単に見分けられ、443の傍受にはブラウザーが信頼を拒否する証明書が必要です。

認可そのものは通常、端末のMACアドレスに紐づき、ときにはリースされたIPに紐づき、タイマー付きのセッションテーブルに存在します。サインインするとエントリーが作られます。あなたの通信を通すファイアウォールルールは、そのエントリーが存在する間だけ存在するため、あなたの側で何も変わらないのに問題全体が後から再発します。

VPNのハンドシェイクが始まる前に死ぬ理由

プロトコルごとにトランスポートが異なり、認可前のファイアウォールはそれぞれを違う形で壊します。WindowsとiOSのIKEv2はUDP 500とUDP 4500を使い、これらのポートでの破棄は809として現れるか、段階を別々に報告するクライアントでは名前解決風の失敗として現れます。UDP 1194のOpenVPNはタイムアウトが切れるまで接続中の状態に留まります。TCP 443のOpenVPNは興味深いケースで、ポータルがTCPハンドシェイクを完了してからリダイレクトページで応答することがあるため、タイムアウトではなくTLSエラーが見えます。

WireGuardはこの仕組みを最も明確に示します。設計上UDPのみでTCPの代替がなく、未知のUDPを破棄するファイアウォールはトランスポートを完全に取り除きます。クライアントは間隔を広げながらハンドシェイク開始を送り続け、決して完了しないハンドシェイクを報告します。そのメッセージにはWi-Fiの記述もなく、ブラウザーを開くべきという示唆もありません。

プラットフォームはVPNより先に状態を察知しようとします。Windowsは既知のURLを取得してサインイン通知を出すか判断し、Androidは204 No Contentを返すべきエンドポイントを要求し、Appleの端末は小さなキャプティブネットワークのウィンドウを開きます。これらのプローブが機能するのは、ポータルが期待された本文ではなくリダイレクトで応答するからです。同じ挙動が、トンネルが死んでいるのにポータルが完全に健全に見える理由を説明します:プローブとトンネルは別のルールで判定されているのです。

セッションの失効が実際にリセットするもの

施設はVPNアカウントとは無関係な理由、つまりアイドルタイムアウト、セッションの最大長、新しいDHCPリース、あるいは別のアクセスポイントへの再関連付けでセッションを失効させます。タイマーが発火するとセッションテーブルのエントリーが消え、認可前のルールセットがチェックイン時とまったく同じ状態に戻ります。

確立済みのトンネルは、健全に見えるだけの時間生き残ることがよくあります。キープアライブは送られ続け、クライアントがそれに気づくかは応答のない通信の扱い方次第なので、経路が消えた後もしばらくステータスライトは緑のままかもしれません。やがてトンネルが落ち、再接続のたびに同じブロックされたポートで失敗します。

その時点で、クライアントのエラーは、注意深く読めば、どの段階にいるかを教えてくれます:

SymptomWhat it meansNext check
Handshake times out with no replyPre-authorization drop on UDPLoad any HTTP page and see whether the portal appears
Immediate TLS error on 443The portal answered your TCP connectionAuthorize, then retry the same profile
Authentication rejectedYour credentials reached the serverThe network is fine, so treat this as an account problem
Connects, then drops repeatedlySession or lease churnWatch the portal timer and the lease time

見落としやすい点がひとつあります:セッションがMACアドレスに紐づいている場合、サインインページを再読み込みしても助からないことがあり、関連付けを切って入り直す必要があります。そうして初めて、ポータルは失効した試行ではなく新しい認可の試行を見ます。

まずサインインし、それからトンネルを上げる

うまくいく順序は、端末を認可し、経路を証明し、VPNを起動し、トンネルを証明し、それから通常のブロックを復元するというものです。最後の手順が重要なのは、ポータルに到達するために必要な一時的な状態が、まさにキルスイッチが防ぐために存在する状態だからです。

トンネル外ブロックのオプションがあるデスクトップクライアントは、ポータルページを読み込むために一時停止する必要があり、そのトンネル外の時間帯は機密アプリを閉じておくべきです(ローカルの通信が保護なしで出ていく唯一の区間だからです)。管理された常時接続の端末は、あなたがポリシーを外すのではなく、所有者が公開した手順を使うべきです。ポータルが証明書の警告を出したら止めてください:受け入れるとセッションが施設の傍受プロキシーを通り、そのプロキシーは送信するすべてを読めます。Androidでは常時接続VPNの下のロックダウンが、トンネルが上がる前に通信を遮断し、一部のビルドはポータルのフローを除外できないため、あなたのビルドができなければ、ロックダウンを切ったままにするのではなく、施設の代替アクセスか別の端末を使ってください。Appleのオンデマンドルールは、プローブが成功するまでトンネルを拒否するように書け、それがホテルのネットワークで望む挙動です。

すでに手元にあるツールで順に検証します。トンネルの前に、ヘッダーと本文の両方が見える形でプローブを実行し、VPNのトランスポートが何か応答を受け取るかを見ます:

curl -sS -D - http://captive.apple.com/hotspot-detect.html -o -
sudo tcpdump -ni any 'udp port 500 or udp port 4500 or udp port 1194'

認可の前、通常のポータルは、Locationがサインインページを指す302か、ポータルページであるHTML本文を持つ200のどちらかを返します。どちらを得たか記録してください。サインイン前のリダイレクトは失敗ではなく、ポータルがどこへ行くべきかを教えているのです。ポータルが成功を報告したら、コマンドを繰り返し、本文が文字どおりSuccessという単語である200を期待します。その文字列がプローブを意味あるものにします。サインインする前にホストが普通に応答するなら、このネットワークに傍受ポータルはありません。キャプチャーでは、認可前の破棄は何も戻ってこない外向きのパケットであり、機能する経路は同じフローへの応答を一秒ほどで示します。接続してから、キャプチャーを繰り返します。

ポータルが「はい」と言った後もトンネルが失敗する場合

サインインの成功は許可されたトランスポートと同じではありません。多くの施設はポータルと通常の閲覧を許可しつつUDPを完全に遮断するため、WireGuardとUDPのOpenVPNは壊れ、TCP 443は動きます。TCP 443が通りUDPが通らないなら、それは設定を誤ったクライアントではなく施設のポリシーです。トランスポートを変えるか、制限を受け入れて先へ進むか、正確なエラーを保管してどの段階で止まっているかを確かめてください。

他の失敗は端末側にあります。古いMACに紐づいたままのセッション、独自のリースを持つ別のWi-Fiアダプター、ポータルの証明書例外をキャッシュしたクライアントは、いずれもきれいに再認可した後も失敗し続けることがあります。関連付けを切り、再認可し、クライアント設定に触れる前に一度だけ試してください。監視しているコンポーネントの背後のアーキテクチャーを知りたいなら、RFC 8952を読む価値があります。

ポータル自体が認可を拒むなら、問題はアカウントか端末の割り当てにあり、VPNの設定では直りません。VPNの出口国を変えても施設のローカルなアクセス状態はリセットされず、そのテーブルはあなたの端末に紐づいていて、選んだサーバーには紐づいていません。施設の運営者に尋ね、時間を与えてください(運営者が見るのはセッションテーブルだからです)。

次の旅行の前に、ゼロ番目の手順としてのポータルページ、持ち運ぶ端末ごとのブロック停止手順、そして実際に試した代替トランスポートの三つを書き留めてください。十分前に動いていたトンネルがまた止まったら、失効した認可として扱い、VPNプロファイルに触れる前にポータルを再確認してください。

関連記事