Folks have been talking about using splash pages and captive portals. I figured I'd summarize past sudo mesh experiences.

Neither the wifi standard nor any commonly implemented network standards include a mechanism for logging in, paying or even clicking accept before gaining access to a network.

As a sorta hack people have implemented captive portals where you connect to a network but then don't gain access to the wider internet until you perform some action.

This is usually implemented such that when you connect you appear to be connected to the internet, but trying to access the internet doesn't work and when you attempt to access a website via HTTP you will instead get a different website showing you some sorta login or splash page. This is done by intercepting HTTP requests and always sending the splash page as a response, no matter what the HTTP request was. This hack was already very problematic for headless devices since they have no way of performing the web action required to gain access to the network.

With the widespread use of HTTPS, the splash page hack became even more problematic since the browser upon seeing a site other than the expected site will of course give an SSL warning due to the SSL certificate not matching the domain name.

Devices then began implementing captive portal detection. This is bad. It's a hack to deal with another hack. They accomplish this by requesting a web page over HTTP from a specific URL where they know what the response is supposed to be, and if they get a response other than the expected response then they know they are behind a captive portal and they can present the user with the splash page. This is implemented differently by different devices. Microsoft devices and Android devices contact a specific hostname (or set of hostnames) that are set aside for only doing captive portal detection. Apple devices are different in that they try to access a web page at apple.com. As far as I know, no linux desktop systems perform captive portal detection. Most devices will pop up the captive portal page when they detect the captive portal, but e.g. some android devices will show the connection icon in yellow instead of white and will put a notification in the notification area that can be clicked to pop up the captive portal. This can be very easy to miss and the user might just get annoyed that the internet isn't working. Also, some iDevices will only sometimes show the captive portal page. It seems like they tend to show it the first time they encounter it, but when re-connected they sometimes seemed to sit there doing nothing. This was a couple of iOS versions ago so it may have changed.

We previously implemented a fake captive portal, where the idea was that we could pop up a splash page by pretending to be a captive portal by faking out the captive portal detectors, which would cause them to display the splash page even though the internet is fully available. This solution is good because it doesn't interfere with headless devices.

However, this is really complicated. You have to know the IPs of all hostnames involved in captive portal detection, and of course Apple, Microsoft, etc. use many different IPs for the same hostname, so the IP a given client receives from a DNS server can be different from the IP another client gets. So you either need to constantly keep a fully updated list of IPs for each hostname or you need to try to ensure that all clients use a DNS server you control so you can provide fake responses to DNS queries for those hostnames. This last solution is probably the best one (and the one we used), but then you end up with the apple-specific issue that now all DNS requests for apple.com end up going to the IP you provided rather than apple.com. You can forward everything but HTTP requests to the real apple.com IP but for the HTTP requests you'll have to filter them and forward all of the requests except the captive portal requests based on URL. We had several issues with e.g. iOS updates failing due to this system being imperfectly implemented on our end.

This whole system was implemented on the exit node but it gave us quite a few issues so I ended up disabling it until we could find the time to get it back up.

You can find most of the related scripts here:

  https://github.com/sudomesh/exitnode

with a few scripts from this system also present in the firmware.

I can walk anyone interested through this system when I get back.

Apologies for the undirected info dump but I figured it might be useful.

--
marc/juul