hgot07 Hotspot Blog

主に無線LANや認証連携などの技術についてまとめるブログです。ネコは見る専。

キャプティブポータルの仕組みと変遷

この記事を開いたということは、おそらく「キャプティブポータル (Captive Portal)」についてある程度はご存じのことと思います。無線LANを使おうとすると、ぱかっとブラウザやポップアップを開いて、利用規約を表示したりログインを要求してくる、うざったいアレです。

煩わしい手動ログイン操作を無くして、自動接続で快適な無線LANを実現したいなら、WPA2 Enterpriseなり、その拡張のPasspointなりを導入すればよいです。セキュリティも高まるし、良いことだらけです……と言いたいところですが、実は欠点もあります。少なくとも現時点では (意味深)。セキュアな公衆無線LANが普及すれば、キャプティブポータルの技術がまったく不要になるかというと、そうでもなさそうです。この話は別の機会に譲るとして、今回はキャプティブポータルの仕組みと変遷についてまとめてみます

 

macOSのCaptive Network Assistant (CNA)

macOSのCaptive Network Assistant (CNA)

 

キャプティブポータルには世代がある

「世代」などと勝手に書いていますが、独自研究によるものなので、Wikipediaならタグが付けられてしまうヤツです。

キャプティブポータルをdisる 批判するのに、「証明書の警告が出るセキュリティ問題があるからダメ」と語られることがあるのですが、これは古い方式にしか当てはまりません。知識のアップデートは重要です。

とりあえず、ザックリと3世代に分類してみました。誰かがキャプティブポータルと言った時に、どれを指しているのかを確認しないと、話が食い違う恐れがあります。

 

第1世代

まだセキュリティのない http が主流だった頃に生まれた技術です。利用者がウェブブラウザを立ち上げて、任意のウェブサイトに http でアクセスすると、接続がポータルサイトにひったくられるタイプです。

この方式は、80/tcpのアクセスをルータでポータルサイト宛に捻じ曲げることで、簡単に実現できます。ログインやクリックスルーの操作後に、フォワーディングを解除して、その端末の対外アクセスを許可するようにファイアウォールのルールを変更します。

最近のフリーWi-Fiでは新しい方式が実装されていますが、この古い方式も最終手段として広く併用されています。「ポータル画面が出ないなら、任意のサイトに http でアクセスしてみればよい」という伝説は、まだまだ有効です。

ウェブアクセスのセキュリティが問題になり、https が普及してくると、この方式では対処できなくなります。やり方を変えずに 443/tcp の宛先を書き換えたら、そう、証明書の警告画面が出ますね。利用者に、この警告画面を無視する癖が付いてしまったら、せっかく https でWWWを構築しても、十分なセキュリティが実現できなくなるでしょう。

やっていることは、中間者 (MITM) 攻撃そのものです。要するに、この方式はダメ!です。

 

第2世代

https が普及してくると、利用者はほとんど http でアクセスしなくなるので、キャプティブポータルが十分に機能しなくなりました。そこで、OSベンダは独自方式を実装しました。細かな実装は違いますが、やっていることは原理的にどれも似たようなものです

OS側に Captive Portal Detection (CPD)という仕組みが入り、OSが積極的な検出動作をします。端末がネットワークに接続されると、OSはベンダが管理している特定のウェブページにアクセスして、その応答を調べます。得られた結果に応じて、次のように処理を進めます。

  • 所定の応答が返った場合:
    インターネットにアクセスできる状態で、キャプティブポータルに遷移する必要がないと判断。
  • 所定と異なる応答が返った場合:
    キャプティブポータルがあると判断し、別ページなどからポータルのURLを取得して、ブラウザまたはミニブラウザ (アクセス制限付き)で開く。
    (この状態を作り出すために、キャプティブポータルのシステムはローカルのDNSサーバでアドレスを上書き(変更)する)
  • 応答が得られなかった場合:
    インターネットもLANもアクセスできない可能性があるので、ポータルへのアクセスも諦める。

執筆時点での各OSの実装は、以下のとおりです。

Google Android, ChromeOSの場合

http://www.gstatic.com/generate_204 にアクセスして、204 No Content が返った場合は、キャプティブポータル無しと判断する。

もし何らかのコンテンツが返ってきた場合は、ミニブラウザでそれを表示する。この状態はキャプティブステートと呼ばれる。上記のページにアクセスして、204 No Content が返るようになったら、キャプティブステートを抜ける。

実際にインターネットまで疎通しているかどうか、 http://connectivitycheck.gstatic.com/generate_204 を用いてチェックする。

Apple macOS, iOS/iPadOSの場合

http://captive.apple.com/hotspot-detect.html にアクセスして、

<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>

が返った場合は、キャプティブポータル無しと判断する。

異なるコンテンツが返った場合は、Captive Network Assistant (CNA, ミニブラウザ)でそのコンテンツを表示する。Successのコンテンツが返るようになったら、キャプティブステートから抜ける。

Microsoft Windowsの場合

Windows 10以降では、http://www.msftconnecttest.com/connecttest.txt にアクセスして、所定の文字列 "Microsoft Connect Test" が返った場合は、キャプティブポータル無しと判断する。

(Windows 8.1以前では、上記の代わりに http://www.msftncsi.com/ncsi.txt が用いられる)

異なる応答が返った場合は、http://www.msftconnecttest.com/redirect にアクセスして、そのコンテンツを規定のブラウザで表示する。

参考:

learn.microsoft.com「この動作は仕様です。」爆笑

Windowsには Network Connectivity Status Indicator (NCSI) という仕組みがあり、これが20~30秒間隔で connecttest.txt にアクセスする。所定の文字列が返った場合に、ネットワークに正しく接続されているとみなす。

 

 

第2世代の方式では、以下のような問題がありました。

  • 処理がベンダのウェブサイトに依存しているので、個別に実装する必要がある。
  • インターネットの疎通を確認する仕組みが組み合わされており、キャプティブポータルを抜けた後も、ポーリングのトラフィックがある。機内Wi-FiのようにLANに閉じたシステムでは、OSを騙す処理が必要になる。
  • キャプティブポータルのシステムで、FQDNの書き換えを行う必要があり、httpsが利用できない。
  • 実装がFQDNの書き換えに依存するため、最近普及しつつあるDNS over HTTPS (DoH)と相性が悪い。

 

第3世代

通化された安全なキャプティブポータルの仕組みを実現するために、Captive Portal APIが策定されました。

この方式では、DHCP option 114 や Router Advertisement を用いて、端末にAPIのURLが伝えられます。APIへのアクセスは https で行います。

APIは、JSON形式で次のような応答を返します。

{
  "captive": true,
  "user-portal-url": "https://portal.example.com/",
  "venue-info-url": "https://venueinfo.example.com/",
  "seconds-remaining": 326,
  "can-extend-session": true
}

user-portal-url は、ログインや利用規約の画面を出すためのページを指します。captiveがtrueの場合にアクセスされます。

venue-info-url は、サービスエリア独自の情報などを表示する、ポータルページを指します。captiveがfalseの場合でも、端末はこのURLを通知できます (端末の実装に依存)。つまり、WPA2 Enterpriseで自動接続されるような公衆無線LANであっても、利用者をポータルサイトに誘導することができます。

いずれのURLも https を使うことになっています。

 

参考:

developer.apple.com

さて、このモダンなキャプティブポータルですが、執筆時点 (2023/11/26)でOSの実装がまだ十分ではありません。まともに実用になるのはAndroid 11以降ぐらいでしょう。Appleは、iOS/iPadOS 15以降とmacOS 13 (Ventura)以降で対応したようですが、captive false時の通知機能が不十分です。Windows 10/11は非対応のようです。

 

ウェブログイン機能の実装

キャプティブポータルの主な用途である、ウェブログイン機能については、オープンソースの実装が幾つかあります。この辺でしょうか。(まだ試していない……)

 

Venue Info通知機能の実装

冒頭に書いたように、WPA2 EnterpriseやPasspointで自動接続できる無線LANシステムでは、利用者をいかにしてポータルサイトに誘導するかが、課題になっています。この場合、ウェブログインは不要で、ポータルサイトへの導線を用意すればよいということになります。

詳細は12月以降に公表するとして、とりあえず、試しに作ってみたものはこちらにあります。素材にどうぞ。

github.com

 

おしまい

 

ps
キャプティブポータルについて調べようとすると、その表面的な動作を解説するサイトばかり検索に引っかかって、機構を調べるのに苦労しました。せっかく機構を解説しているサイトが見つかっても、OSのバージョンによって動作が異なることがあり、古い情報に翻弄されました。実機で調査したものもあり、間違いがあるかもしれません。何かおかしいところがあったら教えてください。

 

参考になるその他のサイト