6

I have been trying to build a captive portal in Apache that I plan to be Apple CNA aware.

I found several relevant posts in StackOverflow, including Captive portal popups... and How to create WiFi popup login page.

I defined the relevant Apache configuration as:

RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^CaptiveNetworkSupport(.*)$ [NC]
RewriteRule ^(.*)$ http://192.168.2.1/captive/portal.html [L,R=302]

# android
RedirectMatch 302 /generate_204 http://192.168.2.1/captive/portal.html

# windows
RedirectMatch 302 /ncsi.txt http://192.168.2.1/captive/portal.html

It is not working quite right, as the CNA browser enters a redirect loop.

I also tried putting all my relevant pages into a /captive directory, and defining the rule

RewriteRule !^captive($|/) http://192.168.2.1/captive/portal.html [L,R=302]

But had similar loop problems. What to do?

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
  • Hello; I am now struggling with a similar problem; I am using create_ap to start network, which in turn deals with hostapd and dnsmasq. I wonder what the simplest solution would be for my use case https://unix.stackexchange.com/questions/446114/can-i-get-dnsmasq-to-drop-any-address-queries-it-does-not-know - it would be great to hear what you say. I thought what is left for me is to tweak iptables and apache. Thanks – r0berts May 31 '18 at 06:43

1 Answers1

5

Upon investigating and doing some tests, it is evident the Apple CNA is a web browser of its own; evidently if an exception is not properly made, all subsequent requests will have yet again the same user agent. So it will start the procedure/portal redirection from scratch, thus the redirect loops.

So in the rule for Apple, we won't redirect anymore if the destination host is the captive portal server.

# apple
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^CaptiveNetworkSupport(.*)$ [NC]
RewriteCond %{HTTP_HOST} !^192.168.2.1$
RewriteRule ^(.*)$ http://192.168.2.1/captive/portal.html [L,R=302]

# android
RedirectMatch 302 /generate_204 http://192.168.2.1/captive/portal.html

# windows
RedirectMatch 302 /ncsi.txt http://192.168.2.1/captive/portal.html

We also add a generic catch-all rule here, that if none of the previous conditions happen, or we are dealing with a OS which we do not have a rule for, it will redirect to the portal if not already there (e.g. not visiting the captive directory).

RewriteEngine on
RewriteCond %{REQUEST_URI} !^/captive/ [NC]
RewriteRule ^(.*)$ http://192.168.2.1/captive/portal.html [L]

Obviously, I would stress out that with this configuration, all the captive portal specific files have to live below the /captive directory.

See also Captive portal detection, popup implementation?

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
  • 1
    I'd like to add that it's also useful to redirect any 404 to the captive portal with ErrorDocument 404 /captive/portal.html. – pinco Oct 07 '18 at 15:39
  • @MarcoMartinelli Thanks for the comment! We encounter a few tibdbits about the theme here and there, hence also having published those questions in the past. – Rui F Ribeiro Oct 07 '18 at 15:50