5

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?

  • 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 unix.stackexchange.com/questions/446114/… - 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 6:43
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?

  • 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. – Marco Martinelli Oct 7 '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 7 '18 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.