Based on hostapd, I am building a captive portal.

  • My Linux Machine provides Wifi access.
  • iPad's and Android clients-tablets connect to this Wifi.

Generally, any client OS checks if a URL is reachable; if not: client OS states it is captive, and displays a popup browser window. The popup is used for login, presentation or else.

I'd like to display such a popup to present my machine's service, but I don't get it. I've avoided the net forward though. All connections are redirected in the machine localhost website.

Why don't I get such a popup? How to get it? How/Where should I implement it on my localhost?

Similar ideas:

When the popup happens, how is its content is defined? For instance, a restaurant captive portal asks for your secret number on your note; where is this page is stored? How does the OS know the URL to display in the popup?

To make a captive portal appear, you need to stop all internet traffic and provide a 302 redirect to the client's browser. To do this, you need to have a firewall (like iptables) redirect all traffic to a webserver (like nginx,apache,etc) where the webserver responds with a 302 redirect to the url of your login page.

I have written a lengthy article on my blog on how to do this with a Raspberry Pi. It basically boils down to the iptables block/redirect to webserver:

iptables -t nat -A wlan0_Unknown -p tcp --dport 80 -j DNAT --to-destination

and then the webserver (nginx) redirecting to the login page:

# For iOS
if ($http_user_agent ~* (CaptiveNetworkSupport) ) {
    return 302 http://hotspot.localnet/hotspot.html;

# For others
location / {
    return 302 http://hotspot.localnet/;

iOS has to be difficult in that it needs the WISP settings. hotspot.html contents are as follows:

<?xml version="1.0" encoding="UTF-8"?>
<WISPAccessGatewayParam xmlns:xsi="" xsi:noNamespaceSchemaLocation="">
<AccessLocation>Andrew Wippler is awesome</AccessLocation>
  • +1 Also complemented your answer in a new answer with some new data. Putting everything to work is a (nice?) puzzle. I have seen some captive portals in international airports and big malls that were not able to pop up the CNA window. Interestingly enough, when I was putting all the puzzle pieces together last year, I did not find this post. – Rui F Ribeiro Feb 2 at 10:32
  • We are in 2018 now. Have you worked more on this? – Rui F Ribeiro Mar 6 at 20:28

For complementing @AWippler message. I implemented a captive portal in FreeBSD, and have perfomed some tests with Windows, Mac, iOS and Android devices as clients.

Be aware that according to my tests, newer Android versions when having Chrome installed, do the captive portal detection test(s) using port 443 instead of port 80. If you only intercept port 80 for the authentication, you will start scratching your head thinking why newer Android clients are not working.

(OK, just noticed this was bumped to the front page and the answer is from 2016...Android might have started doing that shortly after)

Besides intercepting port 80, you also need to setup a SSL host, intercepting port 443 and live with the SSL certificate error. Or use an actual DNS domain valid on the Internet at large with a valid certificate.

For visitors trying also to piece together how to implement Captive Authentication see also my Q&A Captive portal using Apache and the related questions Getting WISPr tags from a FON authentication portal ; also useful for testing Disabling CNA in MacOS

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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