Mesh/Firmware/Splash page
The splash page will be automatically displayed by devices that support captive portal detection. The splash page will not actually be a captive portal, it will only specifically block captive portal detection probes.
Types of detection
Android
Expects HTTP 204 response from http://clients3.google.com/generate_204
or
expects zero-length response body from http://www.google.com/blank.html
or something else.
Captive portal detection method appears to have changed in 4.2.2.
The code that uses the HTTP 204 method is here. This is the master branch, which I assume is latest stable or latest development, so I'm not sure what this "faster captive portal detection" in 4.2.2 is supposed to mean.
Mac OS and iOS
We don't know the complete set of checks. We know that it does an HTTP GET of http://www.apple.com/library/test/success.html and checks if the result is/contains "Success". The result from firefox is:
<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>
This may not be the whole story though, though this seems to indicate that it is.
Windows
The captive portal detection is called NCSI (Network Connectivity Status Indicator). It works like so:
- A DNS lookup of www.msftncsi.com followed by a GET request to the resulting IP with URL http://www.msftncsi.com/ncsi.txt. This file is expected to contain only the text "Microsoft NCSI" (no quotes).
- A DNS lookup of dns.msftncsi.com. If the DNS lookup does not result in the IP 131.107.255.255, the internet connection is assumed to be non-functioning.
So: To get a splash page displayed, the initial request to http://www.msftncsi.com/ncsi.txt should not return the expected text (unknown if blocking the connection outright is good enough), but the DNS
More info here.
Solutions
The filtering should happen at the exit nodes (the servers from which traffic flows between the mesh and the internet). This means that we are not limited by the processing power of the routers.
Proxy
A proxy such as Polipo or Squid could be used.
iptables layer 7
Layer 7 filtering allows the use of regular expression matching of the beginning of the packet data.
ip-based optimization
One of the problems with a proxy and with layer 7 filtering is that it's slow. It would be nice if we could filter only the traffic going to the servers used for captive portal detection (using proxy or layer 7). Unfortunately these servers have not one, but a range of IP addresses (at least for www.apple.com), but a DNS request from an exit node and any user on the mesh going through that same exit node should get the same response. Thus, we should be able to have a script that:
- Periodically looks up the IP for the different servers
- Adds the result as an entry in /etc/hosts
- Updates iptables rules to direct traffic to those IP addresses through the proxy or layer 7 rules.
It may be that we could run an actual caching DNS server, but that DNS server would need a hook to be called every time certain entries change.