Captive portal - what am i missing
-
@michmoor said in Captive portal - what am i missing:
portal.xxx.com is a IP Alias i made - 192.168.50.211
Ok, why not ....
But 'normally', a captive portal is assigned to a NIC dedicated for the portal, setup like 192168.x.1/24 where 192.168.x.1 is the pfSense captive portal IPv4. The 192.168.x.2 to 250 is part of the DHCP portal pool (I've reserved several IPs for my AP's outside of this range : 251,252,253,254)
An gateway in the middle of a IPv4 range is ... strange - for me.You have setup this one ? :
Services > DNS Resolver > General Settings
under Host Overrides :From now on, when the URL https://portal.xxxxxxxx.net is used, "portal.xxxxxxxx.net" will get resolved locally, by the resolver, and points to 192.168.2.1 and from there on, on port 8003, the TLS portal web server will answer, as the https version should be listening to 8003.
The http should listen on 8002.Never assume ^^ : fact check :
[23.09.1-RELEASE][root@pfSense.xxxxxxl.net]/root: sockstat -4L | grep '800' root nginx 26853 5 tcp4 *:8003 *:* root nginx 26551 5 tcp4 *:8003 *:* root nginx 26322 5 tcp4 *:8003 *:* root nginx 26050 5 tcp4 *:8003 *:* root nginx 25832 5 tcp4 *:8003 *:* root nginx 25596 5 tcp4 *:8003 *:* root nginx 25587 5 tcp4 *:8003 *:* root nginx 25522 5 tcp4 *:8002 *:* root nginx 25274 5 tcp4 *:8002 *:* root nginx 24968 5 tcp4 *:8002 *:* root nginx 24825 5 tcp4 *:8002 *:* root nginx 24663 5 tcp4 *:8002 *:* root nginx 24610 5 tcp4 *:8002 *:* root nginx 24381 5 tcp4 *:8002 *:* ? ? ? ? tcp4 192.168.2.1:8002 192.168.2.215:36840 ? ? ? ? tcp4 192.168.2.1:8002 192.168.2.215:43290
which means that nginx, the one used for the captive portal and not the pfSense GUI, has 7 instances for http (8002) and 7 for https (8003)
@michmoor said in Captive portal - what am i missing:
"Your connection is not private"
Is that the message show below the SSID name of the wifi network ?
That's might be alarming for the portal user.
Captive portals networks are normally not WPA2 - or something else - protected, but 'open' wifi networks.The login page will be https (TLS) protected - so no one can sniff your user and password, and as soon as you are logged in, all traffic, these days, is TLS - nobody gets his mails over non TLS connections anymore, neither will they using http (port 80) sites as these don't exists anymore.
One thing will be fowing over the Wifi in clear : the DNS traffic.You could of course activate WPA2 (or something like that) on your Wifi network. In that case you have to publish your WPA2 SSID password and the captive portal credentials.
So, in short : the "Your connection is not private" is probably a scary thing for the "don't no nothing about anything use", and they might decide not to use the network.
On the other side, the one that knows, doesn't bother, as, as soon as the portal is open, they will kick in their client VPN so everything (the TLS traffic, DNS, whatever) gets hidden in another TLS tunnel (their VPN).
This means that I, as a pfSEnse admin, can't see any clear portal user traffic at all. This is one of the reasons I don't even bother using pfNlockerng on the portal.Btw :
I use a network domain , and asked acme.sh to get a wild card certicate.
So it is valid, and can be sued for the pfSense GUI itself, and the captive portal.
https://pfsense.xxxxxxxx.net (on 192.168.1.1 - my LAN) and https://portal.xxxxxxxx.net (192.168.2.1- my portal network)For testing the portal : this one :
is perfect.
When the portal work == the login page opens as soon as the user selects the portal Wifi SSID, you cn start adding rules to lock down what is possible, and not.These are important :
The very first one is part of a NAT rule, where I redirect all DNS traffic to the local resolver.
Keep in mind that there are a lot of people out there that feel the need to direct traffic to a public resolver, bypassing the local (pfSense) resolver, and thus their device can't resolve the local portal.xxxxxx.net URL, thus the device can't find the login page.
Normally, the device uses (have to) DHCP so it will obtain a gateway, network and DNS, which should be the IP of the portal NIC of pfSense. If the device uses some other DNS, this will braek the portal access, as it won't be able to resolve portal.xxxxxx.net (that points to an RFC1918 - so public resolver won't resolve that request).Unbound, the resolver, should listen on this IP. Btw : is unbound actually listening on your "192.168.50.211" ??
There are more portal 'pf' rules : these two are also very important :
# Captive Portal rdr on igc1 inet proto tcp from any to ! <cpzoneid_2_cpips> port 443 tagged cpzoneid_2_rdr -> 192.168.2.1 port 8003 rdr on igc1 inet proto tcp from any to ! <cpzoneid_2_cpips> port 80 tagged cpzoneid_2_rdr -> 192.168.2.1 port 8002
As you can see, the http (TCP port 80) [which does not go the the portal IP] will get redirected to port 8002, the non TLS nginx captive portal.
This nginx port 8002 (non TLS) will then - if you use the https login page, redirect the 8002 traffic to the 8003 (TLS) nginx server : and there you have your https portal login page.
Remember : a non TLS (https) can get redirect to TLS (https), not the other way around.When a device activates a network, for example it connects to a SSID, your portal and then it fires up a DHCP client to get a lease.
Right after that, the device will execute a "portal detection" test - this is build in all modern OSes these
days.
You can see the 'polling' of the device on the Status > System Logs > System > GUI Service page.Example : Just found a new one :
The test URL is http://mobilesecuritycore-detection.norton.com/msc-detections/all/network/success.html - click to see what the test should return ^^
If the return text was not "Success" then the device concludes that a portal might be present.
It will open a browser, pointing to the same URL.
What will show up : the portal login page.So, there will be a http (not https !!) request to a known exiting URL - that is the test that every device makes.
-
@michmoor said in Captive portal - what am i missing:
No internet connectivity is possible.
But do you see any connections from that client passing the firewall? And states that are not redirected?
The only way the client should try to connect without detecting the CP is if the test connection is being passed.
Do you have anything in the bypass captive portal list? -
@stephenw10
I see NO connections passing through the firewall. Once i attempt to connect to the network with CP enabled, i see the states redirected to the gateway and thats it. Clients do not get the portal sign in page at all.Below you see the redirects to 8002/8003. NGINX (pfSense process) isnt serving the page. Normally on an iphone the portal page loads up and i enter credentials. Works without issues. Im half way tempted to load up 22.05 in my boot environment and test this out because i did have this working on multiple interfaces without issues. Then again this could be my fault entirely. I just dont see how it is right now.
-
@stephenw10
https://docs.netgate.com/pfsense/en/latest/troubleshooting/captiveportal.html#captive-portal-does-not-redirectI have triple checked this piece of documentation. DNS does work. I remove CP off the interface and normal web browsing can function again. When i re-enable CP on the interface thats when things stop.
I even have a DNS Redirect rule just in case.... -
I assume if you try to visit an http site you get correctly redirected to the portal in the traditional manner?
I just can't see how the portal detection in the browser/OS wouldn't be triggered unless the test site was being passed.
-
@stephenw10
I think i may have found the potential issue within CP.I created a new VLAN for lab purposes.
Ubuntu 22.04 is the client.
CP enabled for an interface called LAB
** disregard previous notes**
I re-created the CP config but as i suspected on a new interface , NGINX is not displaying the page.eventually it times out.
Just help me understand one point. If i make my portal address of 192.168.99.1 DOES that mean that if i enabled CP on another network say 192.168.15.0/24 that network needs a firewall rule to connect to the captive portal of 192.168.99.1 ?
Based on the states i never see a connection made to the specific CaptivePortal DNS IP record. -
Yes it would need to be able to access that. By default it redirects to the interface IP address.
-
@stephenw10 said in Captive portal - what am i missing:
Yes it would need to be able to access that. By default it redirects to the interface IP address.
I suppose thats the part where im not understanding.
If i have portal.example.com at 192.168.11.1 and attached to my GuestNetwork-1.
I now want to set up another CaptivePortal network for GuestNetwork-2. What would my firewall rules look like for GuestNetwork-2 ? I assume I need DNS but if traffic gets redirected to the interface IP do i need firewall rules to allow GuestNetwork-2 to hit portal.example.com which has a different IP? What ports would I even allow? -
Only if you're hosting the portal login page there somehow. Normally the page is hosted at the interface IP address. The client gets redirected to https://192.168.11.1:8003 or http://192.168.11.1:8002 and sees the login.
-
@stephenw10
So whats best practice if you have multiple interfaces that need to be behind a captive portal?
If i create a portal address what IP do i give it?
edit -- pfSense is hosting the portal. -
Where are you actually using that FQDN? Normally I would not expect to have anything other than the interface IP which then works fine on multiple interfaces.
Otherwise anything that is on the portal login page must be added the CP pass-through list so clients can access it.
-
I think the problem at the end of the day is that Captive Portal doesnt work with multiple interfaces.
If i have GUEST1 and GUEST2 what IP do i give for HTTPS server name? If i give the portal address an IP for GUEST1 that works fine but GUEST2 will not be able to access the page. Same for the other way around.
That seems to be the limitation that ive been able to recognize but the documentation isnt clear on. The WebUI indicates you can select multiple interfaces which in theory should be true but in reality, you cant.
Should i submit a redmine for an update in documentation?@stephenw10 said in Captive portal - what am i missing:
Where are you actually using that FQDN?
Not sure I understand the question. portal.example.com is an A record that points to pfsense IP. In the example above, i have the IP pointed to GUEST1 interface IP of pfsense.
-
@stephenw10
Did i just need sleep?
Maybe staring at a problem fixed itself
I swear I dont know what i did but everything is working as i expected. CP is enabled on multiple interfaces and regardless if its a iPhone or a laptop running Windows or an Ubuntu desktop lab VM, they all detect the portal and i can see the landing page from Netgate. Sign in and all is well.
I..............really dont get it but i will take the L
It was my fault. -
@michmoor said in Captive portal - what am i missing:
Based on the states i never see a connection made to the specific CaptivePortal DNS IP record.
I presume you want to use the https login page usage.
So you have a wild card certificate, or you have these certificates :
portal.your-portal-domain.tld and portal2.your-portal-domain.tld etcYou should have a DNS override on the resolver page that says
... portal your-portal-domain.tld 192.168.15.1 Some description / zone1 portal2 your-portal-domain.tld 192.168.99.1 Some description / zone1 ...
You should be able to resolver these names :
C:\Users\Gauche>nslookup portal.your-portal-domain.tld Server : pfSense.your-portal-domain.tld Address: 2a01:cb19:dead:beef:92ec:77ff:fe29:392c Nom : portal.your-portal-domain.tld Address: 192.168.15.1 etc
Use the pfSense / Netgate default DNS resolver settings, and you'll be fine.
( so no 8.8.8.8, etc - no forward mode etc - not saying this might not work, I never tried it )When the portal works, you can see these logs here :
and more important : here :
This trace mentions / shows an experimental rfc8910.php file, I'll keep that for later, works great.
Your iPhone screen shots - Safari complaining : these are certificate error messages - that's bad indeed.
Latest iOS, right ?This is what I see when connected :
That's the classic "Bla bla wifi network isn't using an encrypted WPAx, please change your router so encryption is used ... bla bla" - No other message.
I also have this new message :
which you can point to a help page, introduction page, or the portal logout page, or whatever you want.
When your portal works, I'll show you what file (just one) to place where, and you have to add an option to the portal network DHCP server (so exit KEA, you'll be needing ISC DHCP).@michmoor said in Captive portal - what am i missing:
Sign in and all is well.
Ok.
Now read this : captive portal is not working on mobiles where @EDaleH showed an implementation, based on "How to modernize your captive network" which is became an RFC. This will open up flawless, simple, IPv4 and IPv6 captive portal support.All you need to do :
- Not KEA comptabile (yet), use ISC.
- Add ths option "114" :
This is the string :
"https://portal.your-portal-network.tld:8003/rfc8910.php?zone=cpzone1"The 8003 is the link between your network, for example 192.168.99.1 , which is using 8002 for http, which you are not using, but is is there, and "8003" which is the https port of the "182.168.99.1" portal network.
- Create a file called "rfc8910.php" :
<?php require_once("auth.inc"); require_once("util.inc"); require_once("functions.inc"); require_once("captiveportal.inc"); header("Expires: 0"); header("Cache-Control: no-cache, no-store, must-revalidate"); header("Pragma: no-cache"); header("Connection: close"); global $g, $config, $cpzone, $cpzoneid, $cpzoneprefix; $cpzone = strtolower($_REQUEST['zone']); $cpcfg = config_get_path("captiveportal/{$cpzone}"); if (empty($cpcfg)) { log_error("rfc8910 - Submission to captiveportal with unknown parameter zone: " . htmlspecialchars($cpzone)); portal_reply_page($redirurl, "error", gettext("Internal error")); ob_flush(); return; } $cpzoneid = $cpcfg['zoneid']; $clientip = $_SERVER['REMOTE_ADDR']; if (!$clientip) { /* not good - bail out */ log_error("Zone: {$cpzone} - rfc8910 - Captive portal could not determine client's IP address."); $errormsg = gettext("An error occurred. Please check the system logs for more information."); portal_reply_page($redirurl, "error", $errormsg); ob_flush(); return; } $cpsession = captiveportal_isip_logged($clientip); $sessionid = $cpsession['sessionid']; $rfc8910_url = 'https://' . $_SERVER['HTTP_HOST'] . '/index.php?zone=' . $cpzone; ob_flush(); if (empty($cpsession)) { // captiveportal_logportalauth("rfc8910", "EMPTY SESSION : {$_SERVER['HTTP_HOST']}", $clientip, $cpzone); $json_post = array ( "captive" => true, "user-portal-url" => $rfc8910_url, "venue-info-url" => $rfc8910_url, ); echo json_encode($json_post, JSON_PRETTY_PRINT); } else { // captiveportal_logportalauth("rfc8910", "EXISTING SESSION : {$_SERVER['HTTP_HOST']}", $clientip, $cpzone); $json_post = array ( "captive" => false, "user-portal-url" => $rfc8910_url, "venue-info-url" => $rfc8910_url, ); echo json_encode($json_post, JSON_PRETTY_PRINT); } ob_flush(); return; ?>
I'm using this file for a month now.
The portal has become even more faster - and I discovered that not every device support rfc8910 yet, but the more recent Samsung devices will a real, well maintained Android OS also make use of it.
The low bud phones (= low bud, non maintained OS) : that's a mess, and will always be a mess (and who cares).But the nice thing is : if the device doesn't use DHCP option 114 then nothings happens, and everything works just as it did before.
For the devices that support 114 : it's beautiful, as the portal detection on the device's end isn't needed anymore. The device will known where to go to visit the portal's access page as soon as DHCP negotiation finished. A 100 % KIS solution.Hey, @stephenw10 : this code is tested, I'm using it right now. It's just one independent PHP file. No patching of other files is needed, I presume I have to add a feature request here.
For the record, 99 % of the credits go to @EDaleH. -
@michmoor said in Captive portal - what am i missing:
Did i just need sleep?
Maybe staring at a problem fixed itselfHa, well that can happen. I'd love to know what changed though. I guess something expired somewhere. Though you would have thought anything that could apply here would have already expired during testing.