captive portal is not working on mobiles
-
To make this discussion complete and to provide a diagnostic process to test if Captive Portal is working in response to this topic itself:
@Gertjan said in captive portal is not working on mobiles:
"Because of the web server's redirection instructions,
and pfSense 'pf' firewall rues ( see /tmp/rules.debug) the https request will get redirected to
http://192.168.2.1:8002/...... if you've chosen http login, or
https://portal.yourlocaldomain.tld:8003/ if you have chosen https login."- The reason the device sends an http:// URL to captive portal, after failing to receive a "Success" response, rather than an https:// URL to the captive portal is because the captive portal can redirect http:// simply because it is not encrypted. Any https:// URL would not be intercepted because the captive portal/firewall would not be able to decode it into a url to recognize/resolve and redirect to the login page. One exception is the https://portal.yourlocaldomain.tld:8003/.... URL of the login screen itself as it does not need to be redirected at all.
- Likewise, the reason http://neverssl.com will still work in a device browser and will almost always launch the login screen is because it can be decoded and redirected by the captive portal/rules to the captive portal login page. This is not always true of the temp browser launched by the operating system of the device, iOS for eg, it may require a secure login. In that case, close the temp browser, open another browser like safari, and enter http://neverssl.com and it will launch the login screen if captive portal is set up correctly.
The most reliable fix is to "forget" the wifi station and then reconnect to the Access Point. Most often that corrects the login issue. If it does not, then exiting the temp browser, "Done, use without internet" option or just bailing out, and using something like Safari or Chrome with a url of http://neverssl.com, or other http:// URL, will launch the login screen and captive portal can then activate the session. If it does not, then captive portal setup may be incomplete.
In my experience, this is less likely to happen if iOS has access to valid DHCP option 114 data. This can happen even if you are using DHCP 114 because bailing out of the login screen without responding can confuse iOS and Captive Portal if the wifi connection remains intact.
-
@EDaleH said in captive portal is not working on mobiles:
In an attempt to answer this and explain why I prefer the DHCP 114 approach ...
When I found Apple's suggestion, the proposed RFC solution you've showed above, I knew that that was the way to go.
My thoughts are this : DHCP negotiation telling the device that a portal is present. It knows right from the network connection start what URL to present to the user so he/she can login.
Just perfect. It can be https right away.@EDaleH said in captive portal is not working on mobiles:
check to see if it says "Success", timeouts and sometimes the word "Success" is so small on the temp browser screen that users can't see it at all
The user can't see success ??
The user never should see that word. The test URL is send right after DHCP negotiation, typically by a command line like 'lynx'.
I need two command on a pfSEnse to do this manually :[23.09.1-RELEASE][root@pfSense.bhf.tld]/root: fetch http://captive.apple.com/hotspot-detect.html hotspot-detect.html 69 B 437 kBps 00s [23.09.1-RELEASE][root@pfSense.bhf.tld]/root: cat hotspot-detect.html <HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>
An example on a Debian host :
root@ns311465:~# lynx -dump http://captive.apple.com/hotspot-detect.html Success
@EDaleH said in captive portal is not working on mobiles:
It takes time for everything to process, wait for a response, .... delays ....
I've read (forum) about delays.
My captive portal has 20 max connected users so my 4100 can handle the load quiet easily.
Btw : I've 4 access points in my portal network.@EDaleH said in captive portal is not working on mobiles:
Another issue I encountered is that the same URL can resolve to multiple IPs over time on many sites.
The IP resolved to doesn't matter.
If a portal is present, the http (TCP port 80) request gets redirect to the pfSense portal web server.@EDaleH said in captive portal is not working on mobiles:
The assumption that the device connection test always goes to the same URL is incorrect.
My device, over the year : a a 3G, GS, a 4, 5 7 10 and now iPhone 12, using whatever iOS available during there life span, did.
But, what http test site is used doesn't matter. It should be a http request and that URL should give a known answer back, that's all that counts.@EDaleH said in captive portal is not working on mobiles:
I found that was one of the reasons for it being intermittent, especially if it couldn't be resolved through the portal
That's bad : for a portal to work, DNS should work.
If the device's OS uses a test URL that doesn't exist (isn't resolvable - doesn't have a web server behind it answers "Success" or whatever it should answer) .... well .... then you have a device with a questionable OS. The OS would break captive portal support.
I can image that when you buy a no-brand phone with a cloned android for that device, and the portal detection URL is taken down then for that device portal detection breaks ...
In that case, the issue isn't on my side (the pfSense captive portal), neither the user. "They have what they paid for".
I'm don't want to be that iPhone fan boy, but I never had issues with their devices/OS.@EDaleH said in captive portal is not working on mobiles:
You are relying on this fixed URL to launch the rule for redirect to captive portal login as well so if it checks a different one
Again : the url used isn't hard coded in pfSense. It doesn't care.
No where I've "http://captive.apple.com/hotspot-detect.html" in my pfSense portal settings.
It is hard coded in my phone, that's for sure. Maybe it can fall back to other URLS, I don't know, never saw them.What I've also have seen : Microsoft OS device use a couple of different http URLs.
Android devices users other URL's of course, some are going to a google owned site, some go straight to China .... all depends on the device's OS version an whatever.@EDaleH said in captive portal is not working on mobiles:
Using DHCP custom option114
It has also a IPv6 DHCP solution !
The pfSense portal is IPv4 only right now. The DHCP solution will add full IPv6 support, something I've tried adding myself several times. It was mission impossible. -
I agree that when nothing goes wrong, the login screen will launch and any http:// URL will launch the login screen. The problem is that the real world user does not know that and they "mess with it".
A successful login screen involves both Captive Portal and the Device, so, let's look at it from the Device's perspective:
One common example: A user lands at your installation with an iPhone and looks around. They find a bunch of captive portals available, Day, Week, Month, Recurring, Data, etc. So they try them and connect to each in turn and when the login launches they seem to be stuck on the screen so they make the only choice they have, (Done or Cancel depending upon if this is the first time or they have been here before) they select either Done which closes the browser and typically iOS displays "No Internet Connection" but not always; or, they select "Cancel" which will prompt them to "Use Other Network" or to "Use Without Internet". In many cases they select to use it without internet. Both Done and "Use Without Internet" have turned off the "Auto Login" feature so the next time they connect to this network, it won't launch the login screen simply because it doesn't check for internet connectivity and thus does not try to access an http:// site, therefore failing to trigger the Captive Portal login page. Now they walk up to the Owner and say, the WiFi is not working and the inexperienced Owner of the facility contacts you and says the Captive Portal is broken. The severity of this varies and the current iOS 17+ has yet again improved and this "self corrects" more often, but it still happens, I just duplicated it on an iPhone 12 iOS 17.2.1 while writing this response. Also of note is that iOS does not always display the "No Internet Connection" warning, (because it is no longer checking?) it often just shows a connection so there is no feedback as to what is wrong. If they try to access a secure site like www.google.com, it will display security messages that make users uncomfortable. Those https:// sites do not trigger the captive portal login page, only an http:// link will. The problem is that as long as that WiFi Station ID is in the "My Networks" list, the Auto Login feature will remain off and there will be no Login page when they connect.
Now this broken Captive Portal/Phone needs to be fixed: What do you do next.
- Launch Safari and go to an http:// site (http://neverssl.com) to see if the captive portal launches the login screen and voila, it does. It also will leave the logout window/tab open in the browser if you need to enable your users to logout. The temp browser on the other hand will display but will close the logout window. when you leave the browser to use the phone.
- Tell them to forget the network and reconnect. This will clear the "Auto Login" setting so they see the login screen one more time. The is the quick and dirty solution to put into your handouts.
- Tell them to turn the "Auto Login" feature back on.
As far as issues with the DNS Resolver, pre-fetch, etc, they tend to affect the end user when they are trying to access secure URLs without authentication through the Captive Portal. This is especially true for payment systems if your login process includes an online payment link that must be redirected to before completing the pfSense login (voucher sent automatically to login screen for eg.). All of those links must get through the firewall to work and they are the IPs that are constantly changing. When an user bails out of the payment system, it produces the same results as bailing out of the temp browser login screen does.
Having iOS display the word "Success" in the temporary browser rather than the login screen occurs less frequently but it is also a symptom of this state of confusion. The redirect URL in Captive Portal may be set to go to the original URL which of course is the http://captive.apple.com...... which will display the "Success" text.
-
-
I had some time during lunch break, and went for it.
Step 1 :
Instead of your "dhcp_cp3.php" I've changed the file name to "rfc8910.php", and cleaned up a bit the file you proposed :<?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); ob_flush(); if (empty($cpsession)) { header("Location: https://portal.bhf.tld:8003/rfc8910-T.json?zone={$cpzone}"); } else { header("Location: https://portal.bhf.tld:8003/rfc8910-F.json?zone={$cpzone}"); } ob_flush(); return; }
edit : a lot more stuff could be removed I guess. As small is beautiful .... but I was impatient, so I used "quick is fine also".
Step 2 :
I've created two more files in the /usr/local/captiveportal/ :[23.09.1-RELEASE][root@pfSense.bhf.tld]/usr/local/captiveportal: cat rfc8910-T.json { "captive": true, "user-portal-url": "https://portal.bhf.tld:8003/index.php?zone=cpzone1" } [23.09.1-RELEASE][root@pfSense.bhf.tld]/usr/local/captiveportal: cat rfc8910-F.json { "captive": false, "user-portal-url": "https://portal.bhf.tld:8003/index.php?zone=cpzone1" }
Step 3 :
Add option "114" to the captive portal network DHCP server - must must be ISC.
I've set custom option value to "https://portal.bhf.tld:8003/rfc8910.php?zone=cpzone1"
And yes, I have the pfsense captive portal web server running with a cert that says it's "portal.bhf.tld". It TLS port is 8003 in my case.
My captive portal zone is called "cpzone1"edit :
I did make a packet capture to inspect the DHCP handshake between captive portal pfSense DHCP server and the iPhone device, and saw that DHCP option 114 was there.Step 4 :
I deleted the Wifi/SSID "known network" from my iPhone.
And connected back to the captive portal.Worked flawlessly....... I guess.
I even have the impression it is faster, the login page shows up faster.So make sure I wasn't seeing things that I wanted to see, not that there ware actually not happening, I edited the the file and added a lot of log lines like this :
if (empty($cpsession)) {
captiveportal_logportalauth("rfc8910", "EMPTY SESSION", $clientip, $cpzone);
} else {
captiveportal_logportalauth("rfc8910", "EXISTING SESSION", $clientip, $cpzone);
}so I could see see what part was reached when under with conditions.
I actually saw that when connecting the iPhone to the captive portal SSID, it made a request for the URL, given to the phone with DHCP +option 114
Then the "rfc18910.php" file gave the phone the "rfc8910-T.json" file which indicated the phone that a portal exists.
So, according to the "rfc8910-T.json" content, it used the "https://portal.bhf.tld:8003/index.php?zone=cpzone1" which showed the login page on te phone..And all this magic worked after some plain copy paste (and some small edits).
Wow .... a RFC defined captive portal.
Thank you @EDaleHMinimal changes are needed - no pfSense scripts files changes are needed.
The bad news : works for iPhones only. Other phones : dono (probably not / later / I don't have an android device .... ).
-
@Gertjan
Excellent, nicely cleaned up.I got the impression it was working with Android but did not check it. We had fewer issues there too but I don't believe Android has the equivalent to "auto_logon=False".
I also think Windows is now recognizing 114 based on how fast it loads.In the midst of this, phone users have gotten better at understanding captive portals as well.
-
@EDaleH said in captive portal is not working on mobiles:
I also think Windows is now recognizing 114 based on how fast it loads.
I've brought my Windows 11 pro laptop in.
I removed from the known Wifi networks my captive portal record - and connected to portal network.
It looks like it totally ignores "DHCP option 114" as is didn't make any request for "rfc8910.php" -
Some progress :
/usr/local/captiveportal/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.php - 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.php - 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']; ob_flush(); if (empty($cpsession)) { captiveportal_logportalauth("rfc8910", "EMPTY SESSION", $clientip, $cpzone); $seconds_remaining = $cpcfg['timeout']*60; $json_post = array ( 'captive' => true, 'user-portal-url' => "https://portal.bhf.tld:8003/index.php?zone=$cpzone", 'venue-info-url' => "https://portal.bhf.tld:8003/index.php?zone=$cpzone", 'seconds-remaining' => $seconds_remaining, 'can-extend-session' => true ); echo json_encode($json_post, JSON_PRETTY_PRINT); } else { captiveportal_logportalauth("rfc8910", "EXISTING SESSION", $clientip, $cpzone); $seconds_remaining = (time()-$cpsession['allow_time'])+($cpcfg['timeout']*60); $json_post = array ( 'captive' => false, 'user-portal-url' => "https://portal.bhf.tld:8003/index.php?zone=$cpzone", 'venue-info-url' => "https://portal.bhf.tld:8003/index.php?zone=$cpzone", 'seconds-remaining' => $seconds_remaining, 'can-extend-session' => true ); echo json_encode($json_post, JSON_PRETTY_PRINT); } ob_flush(); return; ?>
edit : for those who never look at logs, you could remove the two lines that start with "captiveportal_logportalauth( ....."
No more need to create/maintain/use the two json files "rfc8910-F.json" and "rfc8910-T.json", as they are now generated by rfc8910.php on the dynamically.
The
'venue-info-url' => "https://portal.bhf.tld:8003/index.php?zone=$cpzone",
will show useful info : tap on the SSID of the portal and something news shows up : and bring you to theURL you've chosen under 'venue-info-url'. I've put in place the same URL as the login page : what will happen is that, if the device is logged in already, the logout page is shown !
( Not that someone will make use of this - as you have to find it first )I'm also adding 'seconds-remaining', not sure the iPhone actually uses it.
Small recap about how to use all this :
Place the file I've shown above (this post) here : /usr/local/cativeportal/rfc8910.php
Then, make sure you use the ISC DHCP (no Kea for now), and add an "DHCP OPTION 114" :
My 'text string' : "https://portal.bhf.tld:8003/rfc8910.php?zone=cpzone1"
Where : "cpzone1" is the name of your captive portal zone.
"portal.bhf.tld" is the host name of your captive portal, which should TLS as it it mandatory.
Define the host name "portal.bhf.tld" as a host override under Services > DNS Resolver > General Settings.Take note : TLS means : you should won (rent) a domain name (otherwise the "captive portal" is not something for you).
And that's it.
From now on, devices that support RFC8910 will play nicely.
As no pfSense core files are edited, it's "upgrade" proof, and easy to put in place in case of a re install.
-
@Gertjan said in captive portal is not working on mobiles:
/usr/local/captiveportal/rfc8910.php
Integrating the json data into the code is cleaner but I would like to point out that every instance/zone of the captive portal needs a unique rfc8910.php file, thus I would name them like this: rfc8901_cp1.php, rfc8901_cp2.php,,, etc. If you were ambitious, you could likely create json data on the fly, changing sub-domain, port and zone info on the fly. The simplicity of separate files appeals to my KISS preferences.
@Gertjan said in captive portal is not working on mobiles:
captiveportal_logportalauth("rfc8910", "EXISTING SESSION", $clientip, $cpzone);
$seconds_remaining = (time()-$cpsession['allow_time'])+($cpcfg['timeout']*60);
$json_post = array (
'captive' => false,
'user-portal-url' => "https://portal.bhf.tld:8003/index.php?zone=$cpzone",
'venue-info-url' => "https://portal.bhf.tld:8003/index.php?zone=$cpzone",
'seconds-remaining' => $seconds_remaining,
'can-extend-session' => trueIncluding all the data supported is likely useful as devices adopt full functionality going forward. I do not use this because multiple connections to a single user does not currently accurately cumulate time or data and the result from the code can be simply wrong. Instead, we use custom code to calculate the time remaining for multiple connections to a single account. In that way we can apply a time/quota limit to the user and it will cumulate across all connections on that user account. As captive portal ends the session on a logout, we do not permit a logout, instead we publish a "dashboard" that shows time and data quota remaining or that user account. As stated above, although this launches (it is actually the logout code) in the temp browser, it immediately disappears when the temp browser closes. All of that only happens on the first connection to that Station ID/zone/Portal. For this reason, we provide the link to the "logout" code in our handout and instead it launches this dashboard of info when they want to check it. On Windows systems, there is no temp browser so the end user can leave this "logout" dashboard tab open and we refresh it's contents every 2.5 minutes.
-
@EDaleH said in captive portal is not working on mobiles:
but I would like to point out that every instance/zone of the captive portal needs a unique rfc8910.php file, thus I would name them like this: rfc8901_cp1.php, rfc8901_cp2.php,,, etc
Lol.
That's why I rewrote my rfc810Look again :
'user-portal-url' => "https://portal.bhf.tld:8003/index.php?zone=$cpzone",
the zone parameter is a variable, and the $cpzone available is extracted from the URL used to access the page (and to get the right portal session, etc).
I the device asks for a status update, the
$seconds_remaining = (time()-$cpsession['allow_time'])+($cpcfg['timeout']*60);
field is recalculated so the device knows that after xx seconds my hard time out will apply.I've just one portal instance, and will be testing with 'two' instances in a near future.
@EDaleH said in captive portal is not working on mobiles:
For this reason, we provide the link to the "logout" code
I've found it on the profile page on my iPhone device :
Clicking (taping) on Open (Ouvrir la page d'acceuil ...) will open the logout page - or whatever 'venue-info-url' points to.
As said earlier, no one will find it there.
Btw : I've added all the known RFC fields, just to see what happens - what is usefull, what is supported, etc.
-
@Gertjan said in captive portal is not working on mobiles:
Look again :
'user-portal-url' => "https://portal.bhf.tld:8003/index.php?zone=$cpzone",
the zone parameter is a variable, and the $cpzone available is extracted from the URL used to access the page (and to get the right portal session, etc).Once you setup your extra portals, I think you will find that the "portal.bhf.tld" is pointing at an IP in DNS that is unique to the DHCP assigned to the first captive portal zone. Port 8003 is the https port for that zone only, it won't work on other zones, they have their own unique ports.
Thus, you will need portal2.bhf.tld pointing at the IP of the DHCP lease for the second zone, say zone2, and captive portal will provide the https login page on 8005, etc for other portals. your "user-portal-url" becomes 'user-portal-url' => "https://portal2.bhf.tld:8005/index.php?zone=$cpzone". You can only leave the zone=$cpzone in place because it will correctly resolve based on the session ID but it will change from zone1 to zone2 for the URL.
We are using 8 portals this way as the Access Points are limited to 8 - 802.1Q Vlans per frequency. with 2.4 and 5 GHz that could also be 16 portals if you separate them by frequency as well.
-
I just had a friend drop by with an Android 14 Samsung phone and did a quick test. It supports DHCP 114 for both the login screen and more important, it supports the Venu option as well. iOS as of 17 still does not support Venu. When you reconnect to an active Captive Portal user account with the Android, it loads the Venu link through a notification, which in our case is a "dashboard" that displays your username, amount of data remaining and time remaining as applicable. This is a huge asset, I hope Apple and Microsoft support it soon! As you pointed out in:
@Gertjan said in captive portal is not working on mobiles:
will show useful info : tap on the SSID of the portal and something news shows up : and bring you to theURL you've chosen under 'venue-info-url'. I've put in place the same URL as the login page : what will happen is that, if the device is logged in already, the logout page is shown !
( Not that someone will make use of this - as you have to find it first )Now they don't have to "find it first".
-
@EDaleH said in captive portal is not working on mobiles:
Once you setup your extra portals, I think you will find that the "portal.bhf.tld" is pointing at an IP in DNS that is unique to the DHCP assigned to the first captive portal zone. Port 8003 is the https port for that zone only, it won't work on other zones, they have their own unique ports.
Thus, you will need portal2.bhf.tld pointing at the IP of the DHCP lease for the second zone, say zone2, and captive portal will provide the https login page on 8005, etc for other portals. your "user-portal-url" becomes 'user-portal-url' => "https://portal2.bhf.tld:8005/index.php?zone=$cpzone". You can only leave the zone=$cpzone in place because it will correctly resolve based on the session ID but it will change from zone1 to zone2 for the URL.
My "portal.bhf.tld" is hard coded in my rfc8190.php above.
It's already gone in the file I'm using right now.
The URL used to access the portal contains the &zone=ZONEINDICATOR parameter.
With that info, server IP (the portal base network) is known, so is the host name, like "portalX.bhf.tld".So everything can be generated on the fly, on demand.
@EDaleH said in captive portal is not working on mobiles:
Android 14 Samsung phone and did a quick test. It supports DHCP 114
Good news.
Apple will probably follow very soon. Maybe the upcoming 17.4 'dev' version, we'll see.
That is, I hope.@EDaleH said in captive portal is not working on mobiles:
iOS as of 17 still does not support Venu
It does, the venu URL is there, see the image in my previous post, but to hidden to be actually usefull for the average wifi (portal) user.
-
@Gertjan said in captive portal is not working on mobiles:
I've found it on the profile page on my iPhone device :
I missed it because I think of that page as the "info" page (but it is a profile) due to the i inside the circle that launches it.
Now that I know where they link it, I think that is easy to add to the handout so thanks for finding it.For others reading this: on Apple iOS, Settings, WiFi, connect to the portal, click the i with the circle around it,
Because of the DHCP option 114 code/data sent, there will now be a section called "Portal" where it will say:
"This network provides a portal webpage at subdomain.domain.com (for example).
This is the venue link uploaded in the json data file by DHCP option 114, but in this discussion we are pointing it at the "custom" page associated with Services, Captive Portal, click pencil to edit your portal, HTML Page Contents, portal page contents.If we usee the captive portal logon page link; if the session is already authenticated/active, captive portal (through index.php) will launch the logout page you upload under Logout page contents section for the captive portal.
In our case, we use that logout page to display user id, remaining time & data quota as applicable. Ours is NOT a popup window.
Windows does leave the logout tab open when you connect but once closed you need the url to get it open again. For windows users, publishing the url in a handout/email is the only way for them to return to the "logout" page. As this is the least common denominator, that published URL will work in a browser tab on Windows, Android and iOS devices so the venue url utility is diminished in terms of usefulness. Individual device users may prefer the Android Notification or iOS info/profile link so it is wise to implement it through DHCP 114 for their convenience.
@Gertjan said in captive portal is not working on mobiles:
My "portal.bhf.tld" is hard coded in my rfc8190.php above.
It's already gone in the file I'm using right now.
The URL used to access the portal contains the &zone=ZONEINDICATOR parameter.
With that info, server IP (the portal base network) is known, so is the host name, like "portalX.bhf.tld".So everything can be generated on the fly, on demand.
I am not sure I agree, hopefully I am not missing something here?
What we know is the IP of the device ($clientip = $_SERVER['REMOTE_ADDR'];), not the URL. Normally Captive Portal generates the url that executes index.php but with DHCP 114, there is no "capture" per-se; captive portal is not yet involved so we would have to connect to the URL directly as if the end user typed it in, rather than the rule based process that captures the http:// port 80 request and then creates that url for us. This means we must construct the login URL in advance of sending the json data file to the device through DHCP option 114 so the device's temporary browser can call it directly on an SSL/TLS port. To construct that URL we need to know:- The subdomain of the certificate: "portal" in your example. We know each portal has a different subdomain so that it can be associated with the unique DHCP pool of the specific captive portal.
- The domain of the certificate: This is typically/likely the same for all captive portals: "bhf.tld" in your example.
- The port this portal is on. Although the rfc8910.php code is trying to resolve the zone, I don't think we can determine which portal it is associated with so here we have to hard code it. 8003 for the first, 8005 for the second, etc, etc.
4 The zone: in this case we can determine that from the $cpcfg array.
All of the above information is (can be) in the URL coded into the DHCP option 114 so I think we should be able to parse the URL that called us and by doing so, make a single, universal, rfc8910.php file. I will look into that and post back here if I succeed. I am still not convinced that a file per captive portal is not easier to administer but a universal solution is better if we look at it from the user community perspective. If we succeed, then it could even become part of the project or a patch.
I also want to point out, to those not using multiple portals yet; that you need a Level 2 switch on OPT1(tagged)/LAN(untagged) that supports the VLans (one fore each captive portal), or separate network cards, to implement multiple captive portals. Each portal is assigned to a separate interface in System, Captive Portal, Portal Name. Once that is done, it is easy to construct (hard code) the URL because pfSense/Captive Portal never intercept the URL, the temporary browser goes directly to executing index.php through the URL provided in the json data file sent by the DHCP option 114 which is executing the suggested rfc8910.php file through the "temporary" browser prior to anything being captive, it is done at the time of assigning the client IP when initially connecting to the network.
-
This post is deleted! -
This post is deleted! -
I modified your rfc8910.php to parse the url passed from the DHCP option 114 string such that it launches the correct login URL for each portal through the json data string without any additional files required. It is universal as long as the string placed in the DHCP option 114 server contains the subdomain.domain.com:port info. I checked it on 6 portals with voucher, user and freeRadius authentication. If keeping things clean is an objective, this approach is a one file solution to all DHCP option 114 RFC8910 syntax for user and venue options.
Note that I commented out the seconds_remaining code as it was throwing an exception on my portals authenticated by freeRadius. I did not debug that further.
-
Note: the Apple example has the json URL links inside double quotes as a string. In the above code that would suggest => "$rfc8910_url", not just => $rfc8910_url. In testing it worked equally well both ways.
-
$rfc8910_url = 'https://' . $_SERVER['HTTP_HOST'] . '/index.php?zone=' . $cpzone; .... "user-portal-url" => $rfc8910_url, "venue-info-url" => $rfc8910_url,
Ok .... you've found the fun part It was one line.
All reduced to a bare minimum.
I've also ditched the 'remaining time' lines, and use you version right now.
I still have to find a spare AP so I can spin of a second portal, but since you've tested it on 6 portals, you've got me already convinced.@EDaleH said in captive portal is not working on mobiles:
or a patch
Exact.
Now it's just one stand alone file, and for every portal network, the DHCP server needs an 'option 114' correctly set up, so ISC-DHCP is needed, not KEA.
It's very close to a click-and-play addition.So, very nice that this works. Last question : what are the side effects that we haven't discovered ?
-
@Gertjan said in captive portal is not working on mobiles:
I still have to find a spare AP so I can spin of a second portal
Check if your AP runs OpenWRT (https://openwrt.org/toh/start), it supports multiple VLans and StationIDs. I use an Archer C7 in the Lab and have 14 separate Captive Portals on it which are on two separate pfSense configurations simultaneously. I paid $20 CDN for it on Facebook Marketplace. You will need a simple level 2 managed switch, I bought a $35 CDN 8 port TP-Link unit (TL-SG108E) on Amazon and you will need to configure WAN, Lan, Opt1 network interfaces to support the setup of the VLans required for each Captive Portal. You needed a new project anyway, didn't you? FYI, I also use DHCP 114 on the DNS for a different OpenWrt Router setup as a hotspot on a pfSense Network. It loads the "logout" page through the index.php link on pfSense and will load on any device connected to the Hotspot. This provides service to individual, self contained, sites where they use it for local WIFI access and we control bandwidth/time/data quota through the single pfSense freeRadius account that serves them. In this way we distribute the load on pfSense and more important, we have more control over bandwidth/quota/time usage for multiple logins to a single account as pfSense's Captive Portal provides full bandwidth, quota and time to each individual login to a multiple concurrent logins user account. freeRadius does not suffer from the 4096GB limit issue so custom code disables that check and uses freeRadius to manage data, with custom code to manage time within captiveportal.inc. Most have 500 GB to 1 TB data limits per month and ran flawlessly in 2023. see Redmines 13843, 13844 for more info.
-
@EDaleH said in captive portal is not working on mobiles:
Check if your AP runs OpenWRT
They do....
I've 4 of these in the building.
Rather ancient
I'm not using any VLAN stuf, as I have a SG4100, so LAN ports enough.
A year or so I bought a TL-SG108E to 'play' with, but that never happened.I'm using the pfSense FreeRadius package just for the 'authorization', I'm (normally) not byte counting neither bandwidth limiting (accounting). My AP's limit the connection by themselves already (30 Mbits max).
My main down link/up link is about 1 Gbits/sec, so "the can have it".