Captive Portal not working on iOS devices only (DHCP 114)
-
Thank you @Gertjan , I did a thorough testing but nothing worked. Let me explain exactly what I did and ask you some questions.
- I created a Captive Portal Zone named "cpzone" with these options checked.
I had to use HTTP for the Pre-authentication redirect URL in order for the pfsesne Captive Portal page to open quickly. When I used HTTPS, the browser kept loading and loading until it opened the portal page. However, I used HTTPS for the After authentication Redirection URL.
- I created the file rfc8910.php with your code and uploaded it to /usr/local/captiveportal/. but pfsense changed its name to captiveportal-rfc8910.php.
What file name am I supposed to use in the DHCP 114 text string value? Isn't the new file name?
- When it comes to the text string value:
"https://portal.bhf.tld:8003/rfc8910.php?zone=cpzone1".
You said that 'cpzone' is the name of your captive portal, so is the #1 at the end a typo, or must it be added to the zone name regardless?
Also, my Captive Portal URL is http://192.168.1.1:8002/index.php?zone=cpzone. So If I understand correctly, should my correct customized URL be "https://192.168.1.1:8002/captiveportal-rfc8910.php?zone=$cpzone" ?
-
I did all the above steps, but still the Captive Portal is not showing in iOS, and on PCs, the Captive Portal page is still pointing to index.php not to the rfc8910.php.
-
In your rfc8910.php, what values should 'user-portal-url' => and 'venue-info-url' have?
According to my situation, I assumed they should be "https://192.168.1.1:8002/index.php?zone=$cpzone". Correct or wrong? -
When it comes to the HTTPS Host Name of our Captive Portal. Does it have to be a real website that we own or rent or can it be the pfsense's IP 192.168.1.1?
We own https://www.afamiahotelresort.com/ which is the Hotel's website, how can we make it a Captive Portal? Is it something we add to the site or we just use this URL as is? -
I couldn't do the DNS Resolver part, because the whole HTTPS Server Name and TLS are still unclear to me.
- I created a Captive Portal Zone named "cpzone" with these options checked.
-
Hi @Gertjan, Excuse my persistence. Please let me know if the Captive Portal will work for us or not so we don't waste time trying and trying.
-
@basharsaba
@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
I did all the above steps, but still the Captive Portal is not showing in iOS, and on PCs, the Captive Portal page is still pointing to index.php not to the rfc8910.php.
Already one issue in plain sight :
Your file names conflicts.
When you upload the rfc8910.php file with the portal file-manger, it will get renamed.
You see it now ? It gets renamed in "captiveportal-rfc8910.php".
That ok, but also change the "DHCP option 114" also : the one you use right now does not reflect that change.
Try https://portal.bhf.tld:8003/captiveportal-rfc8910.php?zone=cpzone1.Again :
You did change the host name (mine !!) for yours ?
You did change the portal zone name for yours ? "cpzone1" is mine.@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
When it comes to the HTTPS Host Name of our Captive Portal. Does it have to be a real website that we own or rent or can it be the pfsense's IP 192.168.1.1?
httops means : exist IP addresses, and self invented host names.
You need a host name - get one from a registrar. This enables you to get a signed certificat that every browser trusts out of the box.@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
In your rfc8910.php, what values should 'user-portal-url' => and 'venue-info-url' have?
These fields are defined in the RFC but, AFAIK, modern OS's like iOS 17.x, latest orignal Samsung Android) do not use them yet. So no need to set them.
-
@Gertjan Thank you for your reply,
I knew I had to change the filename and the zone name in the URL. I only asked to confirm and clear my doubts. The final one I used for the DHCP 114 was "https://192.168.1.1:8002/captiveportal-rfc8910.php?zone=$cpzone".
It's now clear that the correct URL for my situation should be https://HTTPS Host Name:Port/captiveportal-rfc8910.php?zone=cpzone.
I feel I'm pretty close to achieving this if I get the HTTPS Hostname part correct.
Any advice on where can I buy a hostname from? Just go to GoDaddy or Namecheap for example and buy a domain name with TLS (not SSL)? Any specific name format? .com or .net or or or? where did you purchase yours "portal.bhf.tld" from?
Also when it comes to TLS certificates, what type shall I get? Domain Validation (DV), Organization Validation (OV) or Extended Validation (EV)?
After I buy one, do I need to host it somewhere and build anything on its first main page? Or we are only concerned about the domain name?
I asked you if I could benefit from our existing website https://www.afamiahotelresort.com/ and use it for the URL, or do we need to buy a completely new and separate one just for the Captive Portal?
-
@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
for my situation should be https://HTTPS Host Name:Port/
You could use
https://192.168.1.1:8002/
if you're able to get your hands on a certificat that contains this "192.168.1.1" . You most probably can't.
@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
Any advice on where can I buy a hostname from? Just go to GoDaddy or Namecheap for example and buy a domain name with TLS (not SSL)? Any specific name format? .com or .net or or or? where did you purchase yours "portal.bhf.tld" from?
"portal.bhf.tld" isn't my real (sub) domain name. I use a dot net btw, but that doesn't matter. You take your pick.
All registrars are fine, but you have to check if they support for Letsencrypt : one of the dns acme API methods. Personally, I would stay away of the two you mentioned as their names come back here on the forum, "because things don't work". The first because it's probably to cheap (so its hurt quality) and the seconds isn't moving fast when its comes to making things back work again.
But let me underline : I don't use them, neither the DNS facilities of my own registrar : I'm using my own domain name servers, so I control the entire DNS thing of my own domains names. Not something I advise you to, do btw, as this needs you to known 'everything' of DNS.@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
Also when it comes to TLS certificates, what type shall I get? Domain Validation (DV), Organization Validation (OV) or Extended Validation (EV)?
EV is very expensive. And involves a lot of paperwork.
Certs from LE are free, and just great for the job.@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
After I buy one, do I need to host it somewhere
Noop.
- get a domaine name.
- get a certificat for that domain, and you should be able to download it. Both the key and the crt file.
- Stash them both in the certificat manage.
- Declare a host override into the Resolver, at the bottom :
- Use this cert on the captive portal page.
and your good.
@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
existing website https://www.*fam**hotelresort.com/
If you can get your hands on the certificate, import it, declare the host over ride
portal.fam**hotelresort.com that point to your LAN Portal IP.
and your about done.
-
Hi @Gertjan,
Thank you for the information. Our site's registrar and web hosting is NameSilo.
We created a sub-domain called portal.*fam**hotelresort.com and contacted their support and asked them. They said that they only sell SSL, not TLS (no issue since we are planning to use Let's Encrypt). They also don't support Domains ACME DNS API method, but they have APIs available to list/create and update required records, please see https://www.namesilo.com/api-reference#dns/dns-update-recordI don't feel NameSilo will be helpful in our case, better to search for a different registrar, right?
-
@basharsaba
Ask the (any) oracle, for example acme.sh namesilo
This shows that the pfSense acme.sh package supports namesilo.The second link (the manual ^^) tells me you need a API key.
@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
They said that they only sell SSL, not TLS (no issue since we are planning to use Let's Encrypt).
Small misunderstanding ?
TLS, SSL : read, for example, this or this one. -
Hi @Gertjan, We have made some progress but there was no outcome. Let me explain.
- We were the whole time focusing on the possibility of getting the TLS certificate via the Registrar, but we didn't notice that the Web Hosting company has already provided us with a Let's Encrypt certificate :-)
-
So, we went to pfsense's Certificate Manager, used the Import an Existing Certificate method, and copied/pasted the CRT and KEY data.
-
We created the DNS Resolver and pointed our sub-domain portal.af*****.com to our pfsense's internal IP and made sure we chose the new Certificate we imported.
- We also modified your PHP file to reflect the new PHP file name that pfsense keeps renaming and the new URL and port (although you said it's not necessary) by modifying these lines:
if (empty($cpcfg)) {
log_error("captiveportal-rfc8910.php - Submission to captiveportal with unknown parameter zone: " . htmlspecialchars($cpzone));
portal_reply_page($redirurl, "error", gettext("Internal error"));
ob_flush();
return;'user-portal-url' => "https://portal.af*****.com:8002/captiveportal-rfc8910.php?zone=$cpzone",
'venue-info-url' => "https://portal.af*****.com:8002/captiveportal-rfc8910.php?zone=$cpzone",- We restarted the pfsense and tried, but unfortunately, we observed the same behavior. iPhone doesn't pop up the Captive Portal page automatically. It just says in orange No Internet Connection.
If we try to manually go to an HTTP site (not HTTPS), it will redirect us to the Captive Portal page, but what we noticed is that its URL does show http://192.168.1.1:8002/index.php?zone=cpzone.
Isn't supposed to at least show captiveportal-rfc8910.php ? Who is forcing it to always use index.php?
Another question crossed my mind. Since we overrode the host, this means if we type in the browser https://portal.af*****.com:8002/index.php?zone=cpzone, it should take us to http://192.168.1.1:8002/index.php?zone=cpzone, right? We tried it and it gave us "Fatal Error...etc"
Thanks,
-
I forgot to mention that we did change the DHCP 114 string to "https://portal.af*****.com:8002/captiveportal-rfc8910.php?zone=$cpzone"
-
@basharsaba
My "rfc8910.php" is called
... "rfc8910.php" !
Because I didn't use the pfSense Portal File Manager, but SFTP (see image : WinSCP - it's free).
I didn't use the pfSense Portal File Manager ( !! ) so my file didn't get renamed.
It's fine to use the portal File Manager :but in that case you have to rename "rfc8910.php" into "captiveportal-rfc8910.php" in the DHCP option string. And that's it ( !!! ).
You did that.
But then you started to change more ..... not sure why.This :
log_error("captiveportal-rfc8910.php - Submission to captiveportal with unknown parameter zone: " . htmlspecialchars($cpzone));
is just an error log message. Changing it wasn't really needed. But doesn't hurt.
This
'user-portal-url' => "https://portal.af*****.com:8002/captiveportal-rfc8910.php?zone=$cpzone",
'venue-info-url' => "https://portal.af*****.com:8002/captiveportal-rfc8910.php?zone=$cpzone",will break everything.
It should be kept at :
"user-portal-url" => $rfc8910_url, "venue-info-url" => $rfc8910_url,
as the variable "$rfc8910_url" has been set to
$rfc8910_url = 'https://' . $_SERVER['HTTP_HOST'] . '/index.php?zone=' . $cpzone;
which is the orignal 'index.php login page.
-
@Gertjan Thanks again for looking into this.
The PHP code I used is the one you wrote here https://forum.netgate.com/topic/184936/captive-portal-is-not-working-on-mobiles/21
I then noticed you mentioned the $rfc8910_url here https://forum.netgate.com/topic/184936/captive-portal-is-not-working-on-mobiles/32
So I added this part but it didn't work, then I thought that maybe I also needed to define $rfc8910_url after global as same as the other variables like this:
global $g, $config, $cpzone, $cpzoneid, $cpzoneprefix, $rfc8910_url; but it also didn't work.Here is the whole PHP code I'm using right now. Could you please take a look and tell me if it's correct or not?
<?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, $rfc8910_url; $rfc8910_url = 'https://' . $_SERVER['HTTP_HOST'] . '/index.php?zone=' . $cpzone; $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} - captiveportal-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']; 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' => $rfc8910_url, 'venue-info-url' => $rfc8910_url, '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' => $rfc8910_url, 'venue-info-url' => $rfc8910_url, 'seconds-remaining' => $seconds_remaining, 'can-extend-session' => true ); echo json_encode($json_post, JSON_PRETTY_PRINT); } ob_flush(); return; ?>
-
@basharsaba
I found it hard to follow this discussion to date so I thought I would first state the fundamentals for consideration:
Fundamentals:
- iOS requires a secure "user-portal-url" in order to recognize a captive portal through DHCP 114 option.
- The user-portal-url must use a valid TLS/SSL certificate. I personally user cloudflare because they support free subdomains on an inexpensive primary domain registration. eg. subdomain,sercuredomain.extension
- pfSense Captive portal assigns odd port numbers to secure links which would result in: https://subdomain.securedomain.extension:8003 for example. the :8002, which is for http, above will simply not work with iOS, but will work with Captive Portal capture in a laptop browser for example. The rfc8910.php code uses the "user-portal-url" text to construct the URL for captive portal. This means the DHCP 114 text/string value of "https://subdomain.sercuredomain.extension:8003/rfc8910.php?zone=$cpzone" is parsed to create the url for the captive portal which will look like: "https://subdomain.sercuredomain.extension:8003/index.php?zone=$cpzone". This simplifies the rfc8910.php code and makes it possible to have one file to support multiple captive portal instances.
- ACME can be used to create and renew the certificate. Once you have the subdomain registered in the DNS of the provider (Cloudflare in this eg.), you setup ACME to renew it. This is critical to meeting point 1 above, i.e. a secure session. The IP at the DNS provider points to the IP of the Captive Portal in this case. As Captive Portals should not be on the LAN, I use a VLAN for each captive portal. In the above example, port 8003 corresponds to the first captive portal; often VLan10, i.e. 192.168.10.1. This is just a suggestion though. To simplify the explanation, it can be any IP as long as it resolves to the captive portal login address you use to test that captive portal in a browser. That test must use the https://subdomain.securedomain.com:8003/index.php?zone=vlan10 in my above example, where the port is the correct one for your captive portal. Hint: the zone matches that shown under services, captive portal column labelled "Zone".
Discussion:
My advice, get the secure url working in a browser with Captive Portal and ignore the DHCP 114 requirement unitl you have it working in a secure https session. This will likely have to be done on a laptop or your system you use to access pfSense Console. Once you can consistently log into captive portal, copy the url and convert it as above to become the DHCP 114 text value by simply changing index.php to rfc8910.php for the string value of the DHCP 114 option. Hint: if the laptop browser does not launch the captive portal login page automatically, enter http://neverssl.com, or any other http:// url that is valid, to force the captive portal to "capture" you.
On the iOS side it is common for the Settings, wifi "profile" (i in a circle) to get set to auto-login off or other states that interfere with troubleshooting. I suggest during testing you always forget the profile name and reconnect through "other" to ensure you are able to use the DHCP 114 json data to launch the login page directly. Yes, DHCP 114 bypasses the captive portal "capture" process in pfSense Captive Portal by setting the iOS temporary browser URL to point directly at the login page, not unlike what pfSense captive portal does when it "captures" you. If you like, it is the DHCP 114 option that enables iOS to do the "capturing", forcing the launch of the login page (index.php) and verifying internet access is subsequently attained. In this way they ensure the session is secure and prevent access if it is not. pfSense captive portal on the other hand will permit access through the "http://subdomain.securedomain.com:8002/index.php?zone=vlan10", using the example URL above, in a windows browser. Windows (Edger/Chrome/etc) will warn you it is insecure but not prevent you from continuing if you wish to. If you get that message, you are not correctly configured yet.
Final comment: if you can't log into a secure pfSense Captive Portal session in a laptop browser, don't waste your time on DHCP 114 yet.
-
@EDaleH said in Captive Portal not working on iOS devices only (DHCP 114):
I found it hard to follow this discussion to date
Because not you, and not me, but (all the) others used this :
to upload the "rfc8910.php" file.
And now the file will be renamed, and changes into :so the URL in the DHCP 114 option text string has to reflect that change.
-
If there is a tendency to use the Captive Portal File Manager, then the instructions could read:
The method you use to upload the rfc8910.php file can affect the resulting file name. It is wise to check the resulting file name before configuring DHCP. To do that, go into Diagnostics, Edit File, Browse, and click on usr, local, captiveportal and verify the name of the file. if it is renamed to captiveportal-rfc8910.php then that is the filename you use for setting up the DHCP 114 option text/string in setting up the DHCP server (ICE for now as Kea does not yet support DHCP options).
Independent of name, it is essential that the rfc8910.php file reside in the same directory as the index.php file used by captive portal for the login page. This directory is /usr/local/captiveportal. The exact name of the file is not important except for the .php extension. What is important is that when your DHCP 114 URL is called, the name you use for "rfc8910.php" or "captiveportal-rfc8910.php" or other name as applicable; actually exists!
The addition of "captiveportal-" in front of the file you are uploading is a feature of uploading through the Captive Portal file manager. If you subsequently want to remove the "captiveportal-" from the front of the file, you can use the shell built into the pfSense Console to do so. This would be done by going to Diagnostics, Command Prompt and typing "mv /usr/local/captiveportal/captiveportal-rfc8910.php /usr/local/captiveportal/rfc8910.php" followed by pressing execute. Then use the instructions above to browse to the /usr/local/captiveportal directory to verify the file was renamed correctly.
-
@EDaleH Thank you for the valuable advice about getting first the pfSense Captive Portal to log into a secure session.
After numerous attempts and playing around with the SSL Certificate, DNS Resolver, and Host Overrides, I was able to get this part done.Right now, the moment I connect my Laptop or iPhone to the guest network, the Captive Portal page pops up using my default browser and I can see the URL is https://portal.af*****.com:8003/index.php?zone=$cpzone".
I then applied the same configuration on my friend's pfSense who resides in a country where http://captive.apple.com/hotspot-detect.html is unfortunately blocked and there was some progress.
Before, we had to manually and exclusively go to an HTTP site in order for the Captive Portal page to open, but now, we can go to any HTTPS site and we will get a message to visit this website (only for the first time) and then we will be redirected to the Captive Portal page.
Now, here is the tricky part of my friend's situation for which I created this new topic.
Since http://captive.apple.com/hotspot-detect.html is blocked, we had to use the DHCP 114 along with the modified PHP file presented by @Gertjan. I did that and set the String to "https://portal.af*****.com:8003/captiveportal-rfc8910.php?zone=$cpzone" and used the PHP code I mentioned in my previous reply https://forum.netgate.com/topic/188402/captive-portal-not-working-on-ios-devices-only-dhcp-114/13.
The issue is that the Captive Portal page on iOS doesn't pop up, but it does pop up on Laptop.
The Hotel guests must open Safari or Chrome on their iPhones and type an HTTPS site to get to the Captive Portal page. Unfortunately, the great majority will not guess they have to do that. They will just think there is an internet connection problem, especially if the WiFi network states that.As the DHCP 114 and the modified PHP file are the way to bypass the http://captive.apple.com/hotspot-detect.html challenge/detection. What could be stopping the Captive Portal page from automatically popping up?
I'm trying from the U.S. where nothing is blocked and the Captive Portal page is automatically popping up on my iPhone even after using the DHCP 114 and the modified PHP file. This makes me think that there could be something incorrect with either the DHCP 114 or the PHP code since they are not doing their job in bypassing the Apple Captive Portal detection.@Gertjan Could you please take a look at the code I'm using? Is it correct? Am I missing any line?
I know I can name the file as rfc8910.php by using WinSCP, but it's ok, let it be captiveportal-rfc8910.php and I can change the code and the string accordingly.Thanks,
-
-
@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
@Gertjan Could you please take a look at the code I'm using? Is it correct? Am I missing any line?
Where did you get the code from ?
Something is wrong.
Look here :The variable $cpzone is set = see the green statement.
But this variable $cpzone is already 'used' (so it will contain nothing or an empty string) the line above : that is a bug.So your $rfc8910_url will contain only this :
'https://'portal.pfsense.tld:800x/index.php?zone='
The "cpzone" html variable isn't set ...... things will go wrong.
This is what I'm using right now, for the last two month :
<?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; ?>
To check if a portal client device is using the DHCP method (is using the URL that DHCP option 114 has been given to the device when it obtained a lease), to this :
Look at the logs !!
Here : Status > System Logs > System > GUI ServiceExample :
Question : how would a device a device know that it should do a get "GET /rfc89410.php ..... " ?
Answer : because it uses the "DHCP option 114" it got from the captive portal DHCP server !
AFAIK, Apple device do this, but they are not the only ones using this RFC method.If you are not finding any "GET /rfc89410.php ..... " in the logs, your device are not using the "DHCP Option 114" method.
Btw : the beauty of the ""DHCP option 114" : no "http" 'polling' is needed to have the request redirected to a portal login page.
No more initial DNS request, the one for captiveportal.apple.com to get the address of this http challenge page, is needed.
The device can go straight to the login page, and the URL used, example : portal.pfsense.tld is a host name that has been set up as a static host override into the resolver.
Because the DHCP lease informed (has to inform !) that pfSense is the local networks DNS, the portal visiting device will use the pfSense DNS to get portal.pfsense.tld resolved.
And that always works out.
The "DHCP option 114" is faster as the actual pfSense captive portal login process, although te original "/index.php ...." of the portal is still used ;) because less DNS requests, no web request redirections needed.
Bonus : a connection status page is avaible, although somewhat hidden, I can see it in the 'properties' under the wifi of my SSID on my iPhone.
Btw : I've said this earlier : please, please, tell me why something some one shoe how had decided that apple.com has to be blocked.
Don't let this feeling get to me that your friend is really living in a really sick place. I can't find a reason why people are not allowed ( ? ) to visit apple.com. Is this apple doing this ? The ISP ? -
@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
Before, we had to manually and exclusively go to an HTTP site in order for the Captive Portal page to open, but now, we can go to any HTTPS site and we will get a message to visit this website (only for the first time) and then we will be redirected to the Captive Portal page.
This behaviour is characteristic of the pfSense Captive Portal. The capture of traffic on HTTP port 80 or , sometimes HTTPS 443 is done by the Captive Portal. It has nothing to do with rfc8910 (DHCP option 114). Your need to enter a url to get the login page always means you are being captured by pfSense Captive Portal and your DHCP 114 through captiveportal-rfc8910.php is not parsing correctly. We know this quite simply because iOS does not use your phone's browser for the login screen, it uses a temporary, purpose specific browser just for the login screen. You can't enter or change the url, it either launches because rfc8910.php provided a valid, secure URL to iOS with "true" set, which tells it to go that URL or nothing happens. When you subsequently launch Safari, for example, and enter a url, you are now sending that url to pfSense Captive Portal and iOS is only acknowledging a connection to a WiFi station ID, and pfSense Captive Portal has you "captive", i.e. "No Internet Access". In Windows, you can send an http request to the Captive Portal and it will recognize an attempt to go to the internet and then redirect you to the login page. Unfortunately by definition, an HTTPS request is "encrypted" and pfSense Captive Portal may not recognize it and thus not launch the login screen. In iOS, any http request is blocked until internet access is verified through the captive.apple.com "Success" reply. This is why you do not get the pfSense Captive Portal login screen unless you bypass it through using DHCP 114 by having iOS request the Captive Portal login screen directly by accessing that URL BEFORE it checks captive.apple.com.
Observations:
- There will never be a $ after the zone= in the url. The correct value is found under System, Captive Portal column labelled "Zone". In the rfc8910.php code it is looked up automatically.
- Apple introduced this feature around 2020 and it has evolved. It is only fully supported from iOS 17 on. It does work under earlier versions but does not always behave the same way. Follow @Gertjan's advice and check:
@Gertjan said in Captive Portal not working on iOS devices only (DHCP 114):
Here : Status > System Logs > System > GUI Service
to ensure the zone is correct.
-
If captive.apple.com is not available but the login to pfSense Captive Portal is successful, it is likely that the "No Internet Access" state will remain on the iOS Settings, Wifi screen. If you then open Safari or other browser and go to a SECURE web site, first iOS will now let it through because it is secure, then Captive Portal will let it through because you are logged in and granted internet access. Once iOS detects valid internet traffic it will belatedly clear the No Internet Service warning and continue working. From that point on for new connections on that phone to that station ID, DHCP option114 through rfc8910.php will send a "false" in the json data and iOS will simply pass you through as long as "Auto Login is set to ON" in the profile for that wifi station id. Now iOS knows you have internet access because of the response from captive.apple.com. In the absence of that reply, it may not do so. If this persists, you might want to modify rfc8910.php to always send a "true" which will mean the user gets the captive portal login page (or logout if already logged in), thus enabling the user to close the temporary browser and "fool" iOS. However, the No Internet Access message will still have to be cleared. You may have an app running on the phone that accesses the internet and does that for you. That situation is "undefined" if you like.
-
The "This Connection is not Private" warning suggests a certificate issue so you need to make sure the Captive Portal and pfSense firewall are correctly configured to receive the certificate data from the internet certificate server. Many devices cache this data and it can become out of date if the device is not on the internet for a long time or the server is blocked. The certificate server on the internet has been updated but the device is not checking it. Debugging this can be difficult as well. If the error clears after you get through the Captive Portal then it is the certificate Data cached on the phone that is out of date.
-
@Gertjan and @EDaleH... I'd like to extend my sincere thankfulness for your time, efforts, and determination to help me resolve this issue.
Finally, it's flawlessly working and my friend was able to get to the secured Captive Portal page and bypass the blocked http://captive.apple.com/hotspot-detect.html. It was a dream that had come true No more iOS guest complaints
Without your advice, deep troubleshooting, and attention to detail, we wouldn't succeed in this small project.
Regards.
-
I'm back again with another issue. You're my last resort.
So yesterday we went live with pfSense and the Captive Portal on the entire network. All iOS users were so happy, they all were getting the Captive Portal page in seconds and getting connected to the internet.
On the contrary, Android users who used to be happy before implementing pfSense became upset.
There were 2 types of Android users.:
Type 1, is those with Android 11.x and above which supports DHCP 114. They weren't getting the Captive Portal immediately, but instead, they were getting the Chrome page that says "Your connection is not private" and "Turn on enhanced protection" and then "Proceed to https://portal.afxxxxx.com which would eventually take them to the Captive Portal page.
Type 2, is those with the older Android versions that don't support DHCP 114, which constitute the vast majority.
They were not getting to the Captive Portal page at all even if the above-mentioned alerts of Type 1 appeared. Some of them didn't get any alerts, but still no Captive Portal page.The Android Developer site states: If the API is not available, or if no portal is advertised, the system will continue to detect portals and verify internet connectivity using HTTP/HTTPS probes, as before.
https://developer.android.com/about/versions/11/features/captive-portalBut apparently, these old Android phones are still failing to detect portals using the old method, or somehow, the rfc8910.php is forcing them to use the unsupported DHCP 114.
My questions:
-
is there a way to exclude non-iOS users (mainly any Android version) from using DHCP 114? because Android never had any issues from the start. The only reason I had to start this new topic was because iOS users were having issues.
-
If #1 cannot be done, is there anything that we can do for Type 1 to get the Captive Portal page immediately without seeing the alerts? Not everybody knows what to do and how to proceed. These alerts were very confusing to them.
-
Regarding Type 2, Can we for example create a separate DHCP Pool or Captive Portal for these devices? but will we be able to distinguish the old Androids from the new ones?
Thanks.
-
-
@basharsaba
The good news is the bad news : you didn't understand RFC8910.
If the client isn't asking for DHCP 114, it doesn't get one. edit : have to check this. But I'm sure that if a DHCPO client gets an option that it doesn't know, it will ignore it.
So it will know nothing about the file/url "https://portal.bhf.tld:8003/rfc8910.php?zone=cpzone1" and everything is as before.
If it does know about RFC8910, then it will ask for the usual minimal DHCP options, like 'IP', network, DNS, gateway and some more stuff : these are part of the bare minimal "how to get a DHCP lease" and it will also receive a DHCP 114, and know what to do with it = use the URL directly.
A device could even receive option 114, and decided to neglect it : portal detection will work out the good old known way.So, the beauty about RFC8910 : it enhances possibilities, without loosing backwards compatibility.
After all : adding loads of options to your DHCP server doesn't harm anything, as the client doesn't deal with if it can't understand them.
The file "rfc8910.php" on the portal web server will not get loaded, the client device doesn't even know it exist.I know it works, as I can't control what devices people bring to my hotel. But they connect to my portal.
And they won't complain to me, as I always make a bet with them : "If I make your device connect, do you pay me a beer ?" I was drunk the better part of my live.
Btw : the sub 50 $ phones, I don't touch them anymore.
And the worst is : I'll promise to refund the free ($ or โฌ) service .... so I never lost money here.
Most come back with stuff that 'just works'.About your type 2 devices : and now I state right upfront : I don't know them, I have no android phones or devices that I'm aware of.
@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
My questions:
is there a way to exclude non-iOS users (mainly any Android version) from using DHCP 114?
Not sure.
Packet capture a DHCP negotiation. Is option 114 systematically given by the server ? Or only if it is asked for ?
And even if the option is there, and the device doesn't know what it is, it should just neglect it, and when doing so, the old behavior is back.
With the devices these days randomize their MAC addresses, you can filter what so ever to know if a device is an iOS, or something else. This is what I think - I might be wrong, but I never saw a list with "these are the possible iOS random MACs" and "these are the random android MACs" etc. As such a list makes the random list not random anymore.
So, no go.If've seen devices that block and or panic on : Wifi not encrypted - even Apple gives this messages : and this scares the user. Although the Apple user manual says : this is an informal message, not necessarily a failure. But Portal never really be encrypted. If they were, you have to show everywhere, on every wall, the WPA2 password first. That great for "security". Most traffic is TLS anyway these days.
Other devices don't like 'unknown' RFC1918 .... these users won't be able to use a captive portal. You can't save them.
And so on ....The message "connection not secure" actually means : (for me) : as soon as you are connected to the portal, fire up your VPN.
That's it. And their you have it : for ones I advertise that VPN suppliers can have some benefits.@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
If #1 cannot be done, is there anything that we can do for Type 1 to get the Captive Portal page immediately without seeing the alerts?
What alerts ? The "you didn't encrypt the wifi" .... well, encrypt it .... This will ditch the message, as long as everybody has the WPA2 password first. The choice is up to you. You - and me - can't have it both ways.
@basharsaba said in Captive Portal not working on iOS devices only (DHCP 114):
Regarding Type 2, Can we for example create a separate DHCP Pool or Captive Portal for these devices?
As explained above : in short : no.