We're fighting phone's and other devices to stop them thinking they're in a captive portal AKA walled garden, and show the "Sign in" page, or switch to data instead of WiFi.
Android
From WifiWatchdogStateMachine.java
Android phones from Ice Cream Sandwich will try and get a response from
These are for Nougat, the code for testing connectivity is inside NetworkMonitor.java
This is in Oreo.
Oreo also lists
as a probe URL. Beware that this will require you to setup your DNS so your
server is google.com
. If users try to do a Google search,
e.g. type into their address bar, instead of getting a "Could not connect"
error, they'll have a nasty invalid certificate error because your certificate
will not be a signed Google SSL certificate.
To fake this, in nginx you'd want something like this
# =====================================================================
# = android walled garden hack =
# =====================================================================
server {
server_name
clients3.google.com
clients.l.google.com
connectivitycheck.android.com
connectivitycheck.gstatic.com
play.googleapis.com
;
listen 80;
location /generate_204 {
return 204;
}
}
iOS
Note: iOS internet detection seems to work differently. It seems to not complain if when a request to these URLs gets no response. But it will believe it is in a captive portal if a server replies. Therefore unless you pretend you're these domains you don't have to do anything, and we don't.
Here are the domains iOS devices contact
We have seen on iOS 9 devices: captive.apple.com
It has been reported that these domains are contacted as well, see Tanaza
- www.appleiphonecell.com
- apple.com
- www.itools.info
- www.ibook.info
- www.airport.us
- www.thinkdifferent.us
They may ask for /library/test/success.html
or just /
They all have wispr in their user agent string
In nginx you'd want something like this in your nginx.conf
# =====================================================================
# = ios garden hack =
# =====================================================================
server {
server_name
apple.com
captive.apple.com;
listen 80;
root /srv/apple/;
location / {
try_files /index.html /index.html;
}
}
And in /srv/apple/index.html
<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>
DNS
For this to work you need to setup DNS on your router to point the domains in
the server_name
sections of the nginx configs to your server.
We run DD-WRT on our router and the setup page looks like this. Other routers
will have their own interfaces, but the idea is the same (DD-WRT does DNS using
dnsmasq
, which is a common program to run a dns service).