Android Captive Portal Check: 204-HTTP-Antwort von captiveportal.kuketz.de

Jedes Mal wenn sich euer Android-Gerät mit einem WLAN verbindet, führt das System einen Captive Portal Check durch. Android will damit sicherstellen, dass euer Gerät vom Access-Point nicht nur eine IP-Adresse erhalten hat, sondern tatsächlich auch Ziele im Internet erreichen kann. Notwendig ist das bspw. zur Erkennung von Portalseiten von WLAN-Hotspots (zum Beispiel in Hotels). Android sendet zur Prüfung eine Anfrage an die Adresse »connectivitycheck.gstatic.com«. Ist die Anfrage erfolgreich bzw. wird mit dem HTTP Response-Code 204 beantwortet, besteht Zugang zum Internet. Mit dieser Anfrage übermittelt das System Informationen zur IP-Adresse des Anschlusses, dem Zeitpunkt des Internet-Zugangs und welcher Browser aktuell verwendet wird an Google.

Blockiert ihr diese Anfrage an Google via AFWall+ oder an einer anderen Stelle in eurem Netzwerk erscheint beim WLAN-Symbol in der Android-Menüleiste ein kleines Kreuz. Abhängig von der Android-Version wird auch noch eine Meldung erscheinen, dass kein Internet zu Verfügung steht. Gerade datenschutzbewusste Nutzer wollen allerdings nicht jedesmal einen »Ping« an Google versenden, wenn sie online gehen. Dafür gibt es nun eine Lösung, die auf gerooteten und nicht-gerooteten Geräten funktioniert.

Android Nougat (7.x)

Verbindet das Gerät via USB-Kabel mit eurem Rechner und aktiviert ADB für den Vorgang. Über ein Terminal am Rechner setzt ihr anschließend folgende Befehle ab:

adb shell 'settings put global captive_portal_http_url "http://captiveportal.kuketz.de"'
adb shell 'settings put global captive_portal_https_url "https://captiveportal.kuketz.de"'

Android Oreo (8.x) | Pie (9.x)

Verbindet das Gerät via USB-Kabel mit eurem Rechner und aktiviert ADB für den Vorgang. Über ein Terminal am Rechner setzt ihr anschließend folgende Befehle ab:

adb shell 'settings put global captive_portal_http_url "http://captiveportal.kuketz.de"'
adb shell 'settings put global captive_portal_https_url "https://captiveportal.kuketz.de"'
adb shell 'settings put global captive_portal_fallback_url "http://captiveportal.kuketz.de"'
adb shell 'settings put global captive_portal_other_fallback_urls "http://captiveportal.kuketz.de"'

Ob die URLs wie gewünscht angepasst wurden könnt ihr mit folgendem Befehl prüfen:

adb shell 'settings get global captive_portal_https_url'

Ausgabe:

https://captiveportal.kuketz.de

Anschließend können wir via curl (von einem Rechner aus) die URL mal abfragen:

curl -I http://captiveportal.kuketz.de

Als Antwort bekommt ihr:

HTTP/1.1 204 No Content
[...]

Genau diese Antwort erwartet euer Android-Telefon.

Alternativ zu meinem Connectivity-Check-Service könnt ihr natürlich auch selbst hosten. Via nginx geht das relativ simpel. Hier meine Konfiguration:

## SITE HANDLING HTTP ##
server {
        ## INIT ##
        listen          80;
        server_name     captiveportal.kuketz.de;
        root            /var/www/sites/captiveportal.kuketz.de;

        ## LOGS ##
        access_log off;
        error_log off;

        ## SECURITY HEADER ##
        include /etc/nginx/conf/headers.conf;
        add_header Content-Security-Policy "default-src 'none'";

        ## ENTER HERE ##
        location / {
                # Let's encrypt location
                location ^~ /.well-known/acme-challenge {
                        default_type text/plain;
                }
                location = /.well-known/acme-challenge/ {
                        return 444;
                }
                ## CAPTIVE PORTAL RESPONSE
                location / {
                        return 204;
                }
        }
}

## SITE HANDLING HTTPS ##
server {
        ## INIT ##
        listen          443 ssl;
        server_name     captiveportal.kuketz.de;
        root            /var/www/sites/captiveportal.kuketz.de;

        ## LOGS ##
        access_log off;
        error_log off;

        ## SECURITY HEADER ##
        include /etc/nginx/conf/headers-ssl.conf;
        add_header Content-Security-Policy "default-src 'none'";

        ## SSL ##
        ssl                             on;
        ssl_certificate                 /etc/ssl/certs/captiveportal.kuketz_ecdsa.pem;
        ssl_certificate_key             /etc/ssl/private/captiveportal.kuketz_ecdsa.key;
        # OCSP-Stapling
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_stapling_file /etc/ssl/certs/captiveportal.kuketz_ocspresponse.der;

        ## CAPTIVE PORTAL RESPONSE
        location / {
                return 204;
        }
}

Das Entscheidende ist eigentlich nur dieser kleine Teil:

## CAPTIVE PORTAL RESPONSE
location / {
        return 204;
}

Damit wird nginx auf Anfragen auf der Domain »captiveportal.kuketz.de« mit einem HTTP-204-Statuscode antworten. Mit Apache sollte das auch funktionieren (nicht verifiziert):

RewriteEngine On
RewriteCond %{REQUEST_URI} /
RewriteRule $ / [R=204,L]

Fazit: Ihr könnt nun also meinen Service nutzen oder den Connectiviy-Check selbst hosten. Google wird über diese Funktion jedenfalls keine Daten mehr bekommen.

Informationen zur Datenverabeitung könnt ihr den Datenschutzhinweisen entnehmen.

Hilf mit die Spendenziele zu erreichen! Mitmachen ➡