The internals of Captive Portal - how it works



  • Hello guys!

    I am working on my thesis and my experimental thing is captive portal on pfsense. I've been studying captive portals using web, books and this forum and I also used wireshark to scan the traffic when behind captive portal. I would love for some one with detailed knowledge of captive portals to confirm on my findings and maybe add something to it. At the end of this post I have some questions that I didn't find an answer to and would appreciate if some one would help find answers to those questions.

    Prior to scanning traffic with wireshark I thought captive portal worked with DNS resolving any domain into 10.0.0.1:8002 where portal page is; but that doesn't seem to be the case. What I found is that it uses HTTP redirect messages (302 code) to redirect any HTTP GET request back to http://10.0.0.1:8002. Below is my understanding of how things run when behind the captive portal (feel free to correct me and I will edit my post).

    1. When connected to captive portal device gets its IP and other network settings via DHCP configured on the interface

    2. DNS is open and it responds to queries with actual domain server IP addresses

    3. When trying to connect to a website, the browser makes appropriate DNS query and sends an HTTP GET request to the server

    4. The request gets intercepted by default gateway which compares the server IP in the GET request to the whitelist configured in captive portal "allowed hostnames". If matched it lets the request pass. If there is no match is responds with an HTTP 302 Code (Moved Temporarily) with
    "Location: http://10.0.0.1:8002/index.php?zone=salas_ostrazica&redirurl=http%3A%2F%2F%2F\r\n" (specific to my portal)

    5. The browser makes another HTTP GET request to the url specified above and in response it receives the portal page

    6. After the authentication, MAC address of the device is added to the whitelist and is granted full access (as configured by the firewall rules on that interface)

    I tried to connect to various servers with terminal commands and it would successfully connect to web servers but issue a 302 code after making get requests. I then tried to connect to SSH and HTTPS ports on pfsense WAN side and it would not connect NOTE: firewall rules allowed the connection.

    So how is that that the SSH doesn't come through the portal since it can't be affected by HTTP redirect. Furthermore mail protocols and other applications don't work. That is the expected behaviour for captive portal but I want to understand how things work on the packet level. I am clearly missing on something so hopefully someone can fill me in.

    I can upload some wireshark reports or anything that would help to clarify what I have actually tested.



  • Hi.

    Some links to start with :
    https://forum.pfsense.org/index.php?topic=117345.msg659825#msg659825
    You should also look and try : https://www.google.fr/search?q=pfsense+captive+portal+debug&ie=utf-8&oe=utf-8&client=firefox-b&gfe_rd=cr&ei=LQr2V7yCA4Sx8wfI9IC4Cg (as always, the first link is jackpot)
    You should be friends with 'ipfw', a FreeBSD firewall.

    VERY IMPORTANT : Use the default setup : WAN = WAN, use LAN for internal 'safe' connection and a OPT1 (third) interface for your dedicated Portal setup.

    I then tried to connect to SSH and HTTPS ports on pfsense WAN side and it would not connect NOTE: firewall rules allowed the connection.

    If you're using IPv4 you need to add a NAT rule on the WAN interface. Look carefully, and you will find out that this will also add a related firewall rule. This is ancient matter and will fade out  when IPv4 gets ditched and you'll be having a clean IPv6 setup.

    By default, a Captive portal needs to be unlocked with the help of a web browser. Afterwards, SSH, FTP, POP, IMAP, NTP, SMTP, ICMP, and whatever (you chose in the GUI firewall 'OPT1' interface !), will pass through.

    Btw : you'll be needing this : https://secure.php.net/manual/fr/index.php because all pfSense is mostly using PHP - start "reading" /usr/local/captiveportal and /etc/inc/captiveportal.inc.

    You should also understand what is 'nginx' and the related setup file for the captive portal :  /var/etc/nginx-ZONE-CaptivePortal.conf



  • VERY IMPORTANT : Use the default setup : WAN = WAN, use LAN for internal 'safe' connection and a OPT1 (third) interface for your dedicated Portal setup.

    1. I guess I messed up with the configuration already. I bought this Intel motherboard with 4 Gigabit interfaces and I configured Portal (Guest_WIFI) on … well it was LAN by default. The last two interfaces is used for admin lan and are connected via bridge (see the ss of the configuration below). Can this cause problems? It works fine, but I am guessing you have other reasons for not assigning portal to default LAN interface (which I renamed to Guest_WiFi).

    2. I don't think I need a NAT rule to connect from GUEST_WIFI to the WAN address. The point I was trying to make is that as a unauthenticated client behind the captive portal (which runs on GUEST_WIFI) I was not able to connect to port 22 on WAN address but was able to connect when authenticated. The question really was what breaks the connection attempts since SSH does not use HTTP. When looking at wireshark scan I see that I get no responses back when trying to connect to WAN address on port 22. Same goes for port 443. The client keeps sending syn packets and retransmissions after tcp times out. From that I assume that the firewall simply blocks everything other than http requests until client authenticates via web browser using voucher or w/e. When however a client sends a HTTP request it gets a http redirect response to make another request to the local address with url to the captive portal.

    I wonder what rules exist when I am unauthenticated. I tried to look into firewall log files on pfsense GUI but there is very little information. I could not find any blocked traffic from the testing so I wonder what handles and blocks the traffic then if I cannot see blocks in the firewall logs.

    What is the best way to understand what and how handles the traffic behind captive portal in unautehnticated and autehnticated state. I don’t know php and freeBSD OS, so I am trying to figure out the basics through wireshark and networking knowledge that I have.

    NOTE: "pfsense" port alias is for ports 22 and 443

    ![Screen Shot 2016-10-06 at 14.00.56.jpg_thumb](/public/imported_attachments/1/Screen Shot 2016-10-06 at 14.00.56.jpg_thumb)
    ![Screen Shot 2016-10-06 at 14.00.56.jpg](/public/imported_attachments/1/Screen Shot 2016-10-06 at 14.00.56.jpg)
    ![Screen Shot 2016-10-06 at 14.00.07.jpg](/public/imported_attachments/1/Screen Shot 2016-10-06 at 14.00.07.jpg)
    ![Screen Shot 2016-10-06 at 14.04.35.jpg_thumb](/public/imported_attachments/1/Screen Shot 2016-10-06 at 14.04.35.jpg_thumb)
    ![Screen Shot 2016-10-06 at 13.26.07.jpg_thumb](/public/imported_attachments/1/Screen Shot 2016-10-06 at 13.26.07.jpg_thumb)
    ![Screen Shot 2016-10-06 at 13.21.36.jpg_thumb](/public/imported_attachments/1/Screen Shot 2016-10-06 at 13.21.36.jpg_thumb)
    ![Screen Shot 2016-10-06 at 13.26.07.jpg](/public/imported_attachments/1/Screen Shot 2016-10-06 at 13.26.07.jpg)
    ![Screen Shot 2016-10-06 at 14.00.07.jpg_thumb](/public/imported_attachments/1/Screen Shot 2016-10-06 at 14.00.07.jpg_thumb)
    ![Screen Shot 2016-10-06 at 14.04.35.jpg](/public/imported_attachments/1/Screen Shot 2016-10-06 at 14.04.35.jpg)
    ![Screen Shot 2016-10-06 at 13.21.36.jpg](/public/imported_attachments/1/Screen Shot 2016-10-06 at 13.21.36.jpg)



  • @limona21:

    1. I guess I messed up with the configuration already.

    Actually, yes.

    Do yourself a favor and start over fresh, otherwise you might hang on things that normally do not exist.

    "WAN" is WAN and your gateway to non-local networks (aka everything NOT LAN or any of the OPT interfaces)
    "LAN" is your pfSense device, use this for administration. ssh to this address.
    "Opt1 .. x" use freely as captive portal or what have you

    @limona21:

    2. I don't think I need a NAT rule to connect from GUEST_WIFI to the WAN address.

    Correct, because your config is already borked.
    "Guest_Wifi" on LAN would be your pfSense address but you killed that already.
    If you connect from outside (in a real-world scenario) you have to NAT from WAN to your pfSense LAN address.

    @limona21:

    What is the best way to understand what and how handles the traffic behind captive portal in unautehnticated and autehnticated state.

    Get to know pfSense first surely helps.

    And why is your Admin_LAN a bridge???

    Get rid of that, start with a "factory defaults" device with WAN, LAN and one OPT interface for your captive portal.
    Everything else is a good start for severe problems!



  • Yeah I will start over and fix things as you guys suggested. I surely want to have sound configuration before I dive into captiveportal.

    And why is your Admin_LAN a bridge???

    I've got 4 physical interfaces and I need one for WAN and only one for guest wifi so I figured I would bridge the other two and use them for admin lan. I am open to suggestion so please let me know what would be a better option.

    Get to know pfSense first surely helps.

    I got the pfsense 2 cookbook and I am trying to learn things from there as well as through forums, youtube and pfsense docs but it takes a long time to find exactly what you need (often I don't even what to search for to be honest). I am no pro in networking or FreeBSD so I am trying to learn things as I go. I know the basics from CCNA but that's more or less it.

    Please let me know what is the best practise to use both of the remaining interfaces and use them for a separate admin network. Also any reading regarding freebsd firewall that you think would help clear things up would also be appreciated.



  • @limona21:

    I've got 4 physical interfaces and I need one for WAN and only one for guest wifi so I figured I would bridge the other two and use them for admin lan. I am open to suggestion so please let me know what would be a better option.

    During initial init, you will assign one interface which will be the LAN, and another ne will be the WAN.
    The other two, named automatically OPT1 and OPT2, can be activated and used if you need them, later on, in the GUI.
    Like : activate one for your Captive portal setup.
    You could use the 4th as a DMZ. Or : leave it deactivated.



  • During initial init, you will assign one interface which will be the LAN, and another ne will be the WAN.
    The other two, named automatically OPT1 and OPT2, can be activated and used if you need them, later on, in the GUI.
    Like : activate one for your Captive portal setup.

    I reconfigured pfsense and did just that with 4th interface unassigned. Tomorrow I'll go and configure firewall rules and nat as you guys suggested and then go from there. I see both of you don't like the idea of bridging interfaces together. Could you explain why? I know I should use switch to extend the number of LAN ports. Just curious.



  • @limona21:

    I see both of you don't like the idea of bridging interfaces together. Could you explain why? I know I should use switch to extend the number of LAN ports.

    Bridged interfaces are not a switch. If you need more interfaces then get a $5 switch. Way better because dedicated hardware does the switching and not a software stack.

    @limona21:

    I got the pfsense 2 cookbook …

    Really, why?
    If you want to buy a book for your thesis then go with the book from the (co-)authors of this software which is "pfSense the definitive guide" by Chris Buechler and Jim Pingle.
    I heard other authors didn't get it completely right…



  • Yeah cookbook is well a cookbook and nothing more. I am glad you suggested the other book so I ended up getting Pfsense: The Definitive Guide and The Book of PF: A No-Nonsense Guide to the OpenBSD Firewall 3rd Edition. I'll be away for a while now hh ;D


Log in to reply