Self-hosting the WiFi Connectivity Check for Android

Malvin Gattinger
Thu, 08 Nov 2018 00:00:00 UT

Android is made by Google, but at least as of 2018 it is still possible to use it without Google services. Reasons to do so include privacy and independence. Of course it would be better to switch to another platform completely, but a privacy focussed free software phone or an alternative operating system for Android hardware are not there yet.

One of the “Android calling home” functions that is tricky to disable or remove, is the check for internet connectivity after joining a WiFi network.

Every Android device requests https://connectivitycheck.gstatic.com/generate_204 after connecting to a wireless network. This page hosted by google is empty and returns a 204 status code. Most captive portals use status code 200 to serve a page or 203 to redirect somewhere, hence this works as a simple check whether the device is behind a portal.

I now wanted to keep my Fairphone 2 from connecting to this server. Setting the checked URL to some nonsense would disable the check, but then Android would claim that it has no internet connection all the time, showing a dreaded exclamation mark icon.

But which server should I use instead?

As I am running multiple webservers for my own and friends’ websites, the way to go was to set up a link that generates 204 results myself.

To create the correct response I made a simple file 204.php as follows.

<?php
http_response_code(204);
exit();

Alternatively, if PHP is not available, one can also add a simple redirect to the websever configuration, in my case Apache:

<VirtualHost *:80>
    ...
    RedirectMatch 204 (.*)/204$
    ...
</VirtualHost>

Then, in a root terminal on the phone I entered the following two commands, from pat_512 in the Fairphone Forum (see links below).

settings put global captive_portal_http_url "http://198.51.100.24/204"
settings put global captive_portal_https_url "https://example.com/204.php"

In fact, this could also be used to track a device, recording on the server when it was in which wifi, or rather when it had which public IP address. Setting the URL differently on different devices could then be used to distinguish their requests.