Whitelisting/forwarding DNS for captive portal users (SOLVED)



  • Hi, I wonder if anyone has come across this issue before? I currently run a pfSense firewall as a captive portal for our wifi network. Quite often we find that some wifi users come in with laptops that have static DNS entries in their tcp/ip configuration - although the rest of the settings are set to use DHCP. The captive portal itself is set to forward DNS for users in the network, but to use it they would have to either include their DNS settings as DHCP or set their DHCP statically to use our gateway as their DNS server. Obviously, if these users have static DNS entries they can't get the login page, as they will be redirected to it only if their DNS is working (they try to go to, say, Google and the CP redirects them to the landing page).

    My question is this: Is it possible to allow unauthenticated captive portal users access to external DNS servers prior to logging in? This would resolve the redirection problem with static DNS-set laptops. I'm thinking that maybe a firewall forwarding rule might work - for instance, forwarding all DNS traffic from inside to a specific external DNS server regardless of where the target is set in the laptop. I'm not sure that this would work, though, since it may be that users would still have to authenticate first.

    Does anyone have any ideas on how to achieve this? Any thoughts gratefully accepted.

    Thanks.



  • Hi,

    What about adding a rule that allows all UDP and TCP traffic send to port 53 ?

    Start here: function captiveportal_init_rules (/etc/inc/captiveportal.inc - line 452 (pfSEnse 2.1.4 Release))

    But: people that auto-assign there own DNS (or IP) always should experience non-network connection when they use public networks.
    Normally, its up to them to adapt their settings.
    Right now, its like they are asking for a beer using the Chinese language in a pub in London ….

    Also: as seen elsewhere: leaving port 53 open might permit some tech people to bypass the portal.



  • Hi Gertjan,

    Thanks for the response. As it happens I did find a reference to this on another post in this forum so I'm going to give that a go.

    I agree that it doesn't make a lot of sense that someone using any public wifi should expect it to work if they've set their DNS setting statically. Unfortunately, our clients don't always have to make sense - they just have to be right. Every time. As there seems to be a workaround to this issue, I'm happy to oblige, though it won't make their lives any easier at other public wifi locations.

    Best regards,

    muswellhillbilly



  • @muswellhillbilly:


    Unfortunately, our clients don't always have to make sense - they just have to be right. Every time. As there seems to be a workaround to this issue, I'm happy to oblige, though it won't make their lives any easier at other public wifi locations.

    I guess you and I have the same clients then  ;)

    I always explain to them: the day they bought their device, the access to my portal interface worked (because all devices are DHCP client enabled by default).
    Then THEY changed something (IP and/or DNS to static) and things stop working on captive portals.
    I lave it up to them to draw the conclusion …...



  • Just in case this proves useful to anyone else, after much trawling through ipfw syntax (I'm an ipTables man, myself), I finally found a workaround to allow captive portal users to use any public DNS server - not just the servers given by the internal DHCP service. The method is thus:

    Putty or ssh onto the pfSense box and navigate to the /etc/inc folder.
    Edit (I use 'vi') the captiveportal.inc file.
    Find the section starting with the following:

    "# redirect non-authenticated clients to captive portal
    add 65532 fwd 127.0.0.1, {$listenporthttp} tcp from any to any dst-port 80 in"

    Just above these lines, type in the following four entries:

    Rules to allow DNS queries to external servers from unauthenticated users. (this comment is optional)

    add 65528 allow udp from any to any 53 out
    add 65529 allow tcp from any to any 53 out
    add 65530 allow udp from any to any 53 in
    add 65531 allow tcp from any to any 53 in

    Reload the captive portal firewall rules and users should be able to query any external DNS server from that point on.

    NOTE: This was done on a pfSense 2.1.4 system. If you run an in-place update the likelihood is that you'll have to re-edit the /etc/inc/captiveportal.inc file to put these rules back in.

    PS In some circumstances, the above fix won't work, in which case the following additional solution ought to work:

    Locate the following lines in the /etc/inc/captiveportal.inc file:

    layer 2: pass ARP

    add 65301 pass layer2 mac-type arp,rarp

    Above these lines, enter the following:

    add 65299 allow udp from any to any 53 keep-state
    add 65300 allow tcp from any to any 53 keep-state

    Then save the file and run /etc/rc.captiveportal_configure. This should allow unauthenticated users to use any external DNS server prior to logging in.



  • YES!

    The above solution combined with "Port Forward for TCP/UDP 53 to 127.0.0.1" - it is now possible to force all clients using Captive Portal to use the pfSense for DNS regardless of what the clients DNS settings are.
    This resolves the issue where clients have DHCP but have re-configured their DNS servers to static.

    Perfect - thanks a lot :)



  • Hi,

    I updated pfSense to release 2.4.0 and when I edited the "captiveportal.inc" file to make the changes I found it was changed from the one in versions 2.3.x. The rules syntax are different, I have tried several times but without success.
    Did anyone have the same problem? Any suggestion is accepted, Thank you.



  • Hi,
    it seems I found the right configuration for pfSense ver. 2.4.x by adding the following lines:

    $cprules .= "# Rules to allow DNS queries to external servers from unauthenticated users\n";
    $cprules .= captiveportal_create_ipfw_rule("add", $rulenum,
    "allow udp from any to any 53 out");
    $cprules .= captiveportal_create_ipfw_rule("add", $rulenum,
    "allow tcp from any to any 53 out");
    $cprules .= captiveportal_create_ipfw_rule("add", $rulenum,
    "allow udp from any to any 53 in keep-state");
    $cprules .= captiveportal_create_ipfw_rule("add", $rulenum,
    "allow tcp from any to any 53 in keep-state");

    above the section that starts with:

    $cprules .= "# redirect non-authenticated clients to captive portal\n";
    $cprules .= captiveportal_create_ipfw_rule("add", $rulenum,
    "fwd 127.0.0.1,{$listenporthttp} tcp from any to any dst-port 80 in");

    Remember that the basic prerequisite is to enable the redirecting of all dns requests to pfsense as shown in https://doc.pfsense.org/index.php/Redirecting_all_DNS_Requests_to_pfSense