Implementing a Captive portal using Apache

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?

Asked By: Rui F Ribeiro

||

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?

Answered By: Rui F Ribeiro
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.