Skip to content

Commit

Permalink
captive portal: redirect using code 302
Browse files Browse the repository at this point in the history
  • Loading branch information
fichtner committed Feb 8, 2017
1 parent ba90a39 commit 714bd18
Showing 1 changed file with 3 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ server.bind = "0.0.0.0"
#### bind to port
server.port = {{ cp_zone_item.zoneid|int + 8000 }}

## Redirect response code to use
url.redirect-code = 302

##
$HTTP["host"] !~ "(.*{{cp_zone_item.redirect_host_match}}.*)" {
$HTTP["host"] =~ "([^:/]+)" {
Expand Down

5 comments on commit 714bd18

@gjherbiet
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as intended. Thanks.

@fichtner
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gjherbiet thanks! regarding the 5xx code: we could consider a RFC switch for each zone, is it a valuable target?

@fichtner
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AdSchellevis are you ok with this in 17.1.2?

@AdSchellevis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fichtner the 302? looks good to me.

@gjherbiet
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fichtner Maybe a more complete approach to captive portal is necessary:

Today many OSes (macOS, iOS, Android, Windows >= 7, Blackberry) perform some type of captive portal detection when connecting to a Wi-Fi network. The process is very similar in all cases :

  1. Make an HTTP request to a well-known URL with a specific user-agent (e.g. ^CaptiveNetworkSupport for iOS)
  2. Test if the HTTP reply corresponds to what is expected (e.g. Android expects and HTTP 204 status, iOS an HTTP 200 with a given content).
  3. If not (meaning there is a captive portal), make an HTTP request to the same well-known URL but with the standard browser user-agent : this request is aimed to make the captive portal appear in a new default browser window (Windows) or a splash screen (iOS/Android) or trigger a notification (Android, based on software version).

If the display of the actual captive portal page is costly (e.g. because there are heavy API/database calls to initialize the user session), then it is better to:

  • Serve a dummy static page to captive portal detection requests (e.g. <html><body>OPNsense</body></html> with HTTP status 200, based on the specific user-agents
  • Serve the captive portal page to all other user-agents requesting a well-known URL (with the extra-refinement of not setting the redirurl variable otherwise users will be redirected to a blank/meaningless page after connection)
  • Serve the page from RFC 6585 to all other user-agents requesting another URL with HTTP status 511. As this page contains a meta http-equiv="refresh" HTML tag, only "real" browsers will end on the actual captive portal.

I have implemented such a scheme on NginX for a muni Wi-Fi where more than a million requests a day arrive, most of them being garbage that will never end with a human seeing the portal on a browser.

I have started to see how I can get along the same way with lighttpd, I may suggest a pull request soon. Again, all this complexity is only valuable when displaying the captive portal is resource intensive and/or when there are a lot of requests arriving on that page (e.g. a city, an airport, a stadium, not necessary an hotel, ...)

Another side topic is concerning WISPr authentication that is used by companies like iPass, Boingo or FON. Basically, their connection client is expecting a standard XML to send authentication credentials. This can be done either:

  • based on the user-agent, by redirecting to an XML page instead of the HTML captive portal intended for humans
  • by including the XML at the very top of the HTML captive portal code, as the WISPr standard allows this.

But, based on my experience on the public Wi-Fi business, those features are of less importance than the ability to have a "Walled Garden" (i.e. allowing access to external resources before authentication) based on destination IP (or better on FQDN). This is nowadays necessary for paid access (for instance to allow access to an online payment platform, such as PayPal). I also started to look into that, but this goes far beyond editing a lighttpd conf file...

Please sign in to comment.