Captive portals (apple)

You will have noticed are those rather annoying captive portals you get on hotspot / WiFi. They are frustrating in a lot of ways, and even "free" WiFi can often mean completing some details or even just pressing an "I agree to terms" button. As recently explained by arstechnica, running a WiFi does not usually mean any sort of filtering, logging, or terms and conditions are actually needed. Indeed, in some cases, having T&Cs could form a contract where one is not needed and that can result in some obligations that you don't want. It really bugs me that you can rarely use a free WiFi with a device that has no browser, like my camera, as no way to get passed the splash screen.

Much as I hate these damn things, what is quite nice is the way Apple devices pop up the splash screen when you select a WiFi, and if you don't login/accept, then it does not use that WiFi. This is Apple being a bit clever and actually the way they do it can be used sensibly.

How do they work?

The way a portal, or pay wall, or whatever you want to call them, usually works is by not providing a working Internet connection at all! They divert "web pages" to a splash screen for login/etc. How this divert works can vary, it could be block all traffic and override DNS, it could be redirect port 80. I have seen some redirect port 443 which creates a nasty security warning and really is not a good idea. Changing DNS can result in nasty caching effects.

Once you complete the process the diverts are removed and normal Internet access is possible.

What do Apple do on devices?

What apple do when you select the WiFi is make a simple HTTP GET request (not https for obvious reasons) to http://captive.apple.com/hotspot-detect.html

The response is a simple http page with Success in the title and contents. If the device sees that then it assumes it has working Internet access, and uses the WiFi.

If not, then it displays whatever page it gets instead. This works well with these typical arrangements that divert all web pages.

These "test" requests come from CaptiveNetworkSupport-325.10.1 wiser user agent, but requests to display the page and subsequent pages to complete the login are from the normal Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_3 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13G34 user agent.

Sadly sending cookies does not seem to work, so there is no real way to tell the initial test from any further test, so the server has to have some state. Normally the server will have state, knowing the user is allowed access or not (yet), and when allowed the test will go to the real captive.apple.com and be served correctly.

What if you want a simple splash page?

What I wanted to do was make a simple splash page, no terms and conditions, just saying who is providing the free WiFi. The idea is to do this for an free WiFi in a cafe. I want the WiFi to work as well as possible, with IPv6, and to work on devices without browsers if possible. But for iPhone users at least, a popup splash page would be nice.

So, first thing, divert DNS for captive.apple.com to my own server. The good news is that this can be a permanent fix in the DNS server used for this connection, it does not need to know the user is allowed or not, an we are not setting any general blocking of anything. It is a single DNS entry override with IP address. By the way, this used to be a page on http://apple.com/ which would have meant redirecting the whole apple.com domain in DNS, thankfully Apple have changed this to a specific subdomain now.

The server then needs to serve something for hotspot-detect.html to provide the splash page. However, after each page the phone re-checks hotspot-detect.html to see if now allowed or not, so I have to set some state so that the second and subsequent requests (in a short time frame) serve the expected Success page.

You don't see the MAC unless you have something local, or you can ask the remote device to use ARP or ND to find out. All you see is requesting IP address. I also have concerns that the IPv6 is a privacy address and likely to change. It may be possible to only serve an IPv4 address at DNS level to avoid that issue but that is messy.

My solution was simply to mark that IP as allowed for a short period so that only the first request to hotspot-detect.html would redirect to the splash page.

The result is the phone pops up with the splash page and is then immediately happy that it is now allowed and shows "Done" on the screen. This is exactly what I wanted.

Other devices just make use of Internet with no splash page, and there are no restrictions, which is also what I wanted.

Next step - see if Android phones do anything similar.


  1. You might be interested in something like this which I have :-
    It allows you to connect a disk and access the files via a samba connection or dedicated apple/android app.
    However one of its additional features is the ability to bridge an existing wireless connection so you can connect your phone to the devices wireless and then get the device to log into the hotel wifi and go through the portal. Anything else on the devices wifi such as your camera then has access to the hotels wifi without having to log in itself.
    The particular model I have is no longer stocked but they have lots of other variations available in the series.

  2. Android does similar, but the second request will be delayed as it's shown by a notification.
    I've not been in a position to sniff traffic though.

  3. Android, iOS and OS X all do this (OS X only does it if you're on Wifi though - for some reason they assume you'll never see a captive portal when wired).

    Additionally, iOS and OS X devices support the WISPr "standard", which allows them to cache your user name and password. I put "standard" in quotes because the standard was withdrawn when it was discovered that Apple had patented the hell out of it (which I guess is why Android doesn't support it, although HTC have included WISPr support in some of their Android devices)). Also unamusingly, the Apple implementation deviates from their own standards documents quite considerably.

  4. Google changes which host they try to connect to from one version to the next, precisely to deter people trying to be "clever" and detect their detection code.

    They make a plaintext HTTP request to one of the many Google servers, asking it for an HTTP code 204 (which is success with no content, and thus also conveniently something it knows it wouldn't likely see from a captive portal trying to draw a web page)

    If they don't get a 204, but they do get _something_ they conclude there is a captive portal and add a notification asking you to sign in to use it.

  5. For your camera could you spoof the Wireless MAC on a laptop to match the Camera, get its MAC auchorized to pass packets to the world, then fire the camera up? Or an ad-hoc hotspot on some device to give the camera wifi.

  6. you could use the captive portal in the Unifi AP and set up a separate SSID for "devices".

    1. The captive portal would block access until set up, which is not what we want. It also seems to break IPv6 even when authorised I believe.


Comments are moderated purely to filter out obvious spam, but it means they may not show immediately.

ISO8601 is wasted

Why did we even bother? Why create ISO8601? A new API, new this year, as an industry standard, has JSON fields like this "nextAccessTim...