Bypassing captive portal detection on Android 10
(Yes, I know my phone is running an old version of Android. I am tempted to try GrapheneOS, on a new Pixel device, so that I am on Android 13.)
I run a WireGuard server, listening on port 53, to which my phone is connected the whole time, and my laptop connects “on-demand”.
One of the advantages of using port 53 is that, when using public Wi-Fi with a captive portal - where you have to hand over personal data to connect, usually - my laptop will sometimes bypass the login requirement, and let me use the Internet unhindered. Sometimes it works (great), sometimes it does not (acceptable; I am not expecting this to be perfect, since it depends on the Wi-Fi network’s configuration / firewalling).
Despite WireGuard on port 53, my phone, running Android 10, detects that there is a captive portal, and will not connect without me logging in. I guess that this is what most people want, but typically, I’d rather not log in. I’d prefer not to use a Wi-Fi access point which requires me to log in, than to log in.
But I am curious to see whether I could disable Android’s captive portal detection.
And I think I’ve got it working…
Apparently, there is a way of changing the captive portal detection settings from within the phone itself, but I have not managed to achieve that.
Instead, I’ve done it using the Android Debugging Bridge (adb), connecting to my phone via a USB cable.
On my laptop, I installed the Android ADB tooling with apt install adb
.
I enabled ADB debugging on my phone. It was a bit convoluted, and consisted of:
- going into “Settings”
- going into “About phone”
- tapping about 10 times on “Build number” to enable developer mode
- going to “System” (in “Settings”), “Advanced”, and then “Developer options”
- enabling “Android debugging”
On my laptop, I could then start adb with adb start-server
and then connect to the phone’s shell with adb shell
.
Within the shell, settings get global captive_portal_mode
returned null
.
I set up a Wi-Fi network with a captive portal and, by default, the phone’s Wi-Fi settings showed that that was the case, and prompted me to connect:
Changing the captive_portal_mode
setting to 0
should mean the phone ignores captive portals, so I made the change with settings put global captive_portal_mode 0
.
I attempted to connect to the test Wi-Fi network, and the phone behaved differently, as it showed the state as just “Connected”:
So that was progress, and may well be success.
It still did not connect, but that could be because my captive portal setup was doing its job properly, and preventing connections.
You may also like:
- Running the greenbone OpenVAS vulnerability scanner on a Raspberry Pi 4
- Installing SIP client Blink on Debian 11
- Fixing 'tee: command not found' on Debian 11 Bullseye
- Installing Debian 11 on a Microsoft Surface Go: secure boot, mokutil, Wi-Fi, and libinih1
- Adding music from an ssh-accessible remote server to an Android phone via Debian 11
- PinePhone: WireGuard, dns-over-https, and other thoughts
- Virtualising an existing macOS installation for VirtualBox on Debian 11
- Wi-Fi on a 2012 Mac Mini, running Debian 11
- LibreOffice Writer, deleting comments, and tracked changes
- Samsung Galaxy Tab 9.7 and postmarketOS: building a custom image
- Samsung Galaxy Tab 9.7 and postmarketOS: initial impressions
- Microsoft Surface, Debian, and two 4k monitor frustrations
- A year with password manager bitwarden
- Transfer your computers clipboard to a camera-enable mobile device via QR code
- Auto-connecting a VPN on a Wi-Fi connection from a mobile router on Debian 11