connectivitycheck.gstatic.com への Android の接続を誤魔化してみるテスト
Android の「インターネットは利用できません」の検出
Android に詳しい方はご存知の通り、Android は
http://connectivitycheck.gstatic.com/generate_204
に定期的に接続をしてインターネット接続できるかどうかを確認している。
ここへの接続が出来ない場合は「インターネットは利用できません」と表示される。
なお、この警告は celler 回線(3G/4G 回線)でも表示は異なるが、警告される。
なお、上の図はいずれも connectivitycheck.gstatic.com への接続を遮断して得られた動作結果であり、 実際には他のドメインへの接続はできるといった挙動を確認している。
connectivitycheck.gstatic.com の偽装と挙動
http://connectivitycheck.gstatic.com/generate_204
へ接続すると常に "204 No Content" が帰ってくる。
ここで、接続不能であったり "404 Not Found" であったりしたときに、
「インターネットは利用できません」と判定がなされる。
そこで、connectivitycheck.gstatic.com を他の IP アドレスに解決させることで 代替することを考えた。 具体的には、
- 192.168.1.2 アドレスで起動している PC 上の port 80 で HTTP server を起動させる。
http://192.168.1.2/generate_204
へのレスポンスは "204 No Content" とする。- 簡単のため "Host: connectivitycheck.gstatic.com" が要求ヘッダについていようがついていまいが、同一の動作をするものとする
- Android 機において、connectivitycheck.gstatic.com のドメイン名を 192.168.1.2 に解決させる環境を作る。
- Android 機において、WiFi アクセスポイントに接続させる。Android 機の IP アドレスは 192.168.1.1 とする。
目的を実現するために簡素な HTTP server "Fake connectivitycheck.gstatic.com" を作成した。 これを linux マシン上で駆動させた(もちろん su 権限で実行し、また firewall で port 80 を許可した)。
そして Android 機を WiFi に接続させると下記の通り、 HTTP server 側のログが吐き出された。
[2016-08-14 07:23:00] DEBUG accept: 192.168.1.1:51856 [2016-08-14 07:23:00] DEBUG WEBrick::HTTPServlet::ProcHandler is invoked. 192.168.1.1 - - [14/Aug/2016:07:23:00 EDT] "GET /generate_204 HTTP/1.1" 204 0 - -> /generate_204 Dalvik/2.1.0 (Linux; U; Android 6.0.1; Nexus 5 Build/MMB29X) [2016-08-14 07:23:00] DEBUG close: 192.168.1.1:51856 [2016-08-14 07:23:01] DEBUG accept: 192.168.1.1:56927 [2016-08-14 07:23:01] DEBUG WEBrick::HTTPServlet::ProcHandler is invoked. 192.168.1.1 - - [14/Aug/2016:07:23:01 EDT] "GET /generate_204 HTTP/1.1" 204 0 - -> /generate_204 Dalvik/2.1.0 (Linux; U; Android 6.0.1; Nexus 5 Build/MMB29X) [2016-08-14 07:23:01] DEBUG close: 192.168.1.1:56927
最初の部分しか取り出していないため時間を空けずに幾度も接続しているようにみえるが、 しばらく経ったら間隔をあけて接続するようだ。 また、重要なこととしてこれによって「インターネットは利用できません」が表示されないことを実現できた。
connectivitycheck.gstatic.com の偽装効果
connectivitycheck.gstatic.com
というGoogle のサーバへの接続処理は、
そもそも Android のコードに埋め込まれている。
よって世界中のオンラインとなっている Android 機から定期的に接続しているということだ。
それは冷静に考えると興味深いことである。
connectivitycheck.gstatic.com
の接続を
本稿で述べたようにゴニョゴニョすることでこの Google のサーバへの接続処理を止めて
かつ「インターネットは利用できません」判定も Google のサーバなしで実現することが出来た。
さらに connectivitycheck.gstatic.com
のドメイン名を 127.0.0.1 に解決させてかつ android 上でサーバを駆動させれば、
「インターネットは利用できません」判定機能が実質無効化されることを引き換えに
無線アクセスを抑えることも考えられるが、これはやっていない。
Reference
- com.android.server.connectivity.NetworkMonitor.EvaluatingState#processMessage()
- "How does WiFi in android detect if the device has to sign in or not?", Android Enthusiasts Stack Exchange
- amythical, "Bypass captive portal for Android", Notes, Jun 23 2016
その他、connectivitycheck.gstatic.com
のドメイン名解決を操作するための
/etc/hosts のフロントエンドとしてAdAwayを使用した。