Hello Apple Developer Community,
I have been investigating the challenges with captive portal authentication on Apple devices, particularly regarding Google's OAuth 2.0 authorization in embedded WebViews and the resulting disallowed_useragent error. For Wi-Fi networks providing a captive portal with a 'Sign in with Google' option, reconnecting to the network after forgetting it triggers the portal page. However, attempting to sign in with Google results in an error. Additionally, on macOS Sonoma 14.1.1, clicking the Google Authenticate button elicits no response.
I recently discovered that this issue has been resolved in an iPad Pro updated to iOS 17.1.1. However, I've also tested with an iPhone 7 running iOS 15.4.1 and found that the issue persists on this version.
Could you provide information on which versions of iOS, macOS, and iPadOS have addressed this issue? It would be immensely helpful for developers and users to know from which version onwards this fix has been implemented, ensuring a consistent and secure experience across Apple platforms.
Thank you for your assistance and looking forward to your response.
Post
Replies
Boosts
Views
Activity
Recently I tested my VPN application on iOS 15 beta 8 / Xcode 13 beta 5.
It looks like that the precedence is
IPSec VPN > iCloud private relay > NEPacketTunnelProvider VPN.
When the iCloud private relay is switched on if use IPSec VPN(I think it's using the IPSec interface) the browser's network traffic is still being routed to the IPSec tunnel.
But for the implementation with NEPacetTunnelProvider VPN(UTUN interface) the browser's traffic is being routed to the private relay. I don't see any doc describing this but it seems this is the design.
And another question is the IncludeAllNetworks setting for the VPN. If set the IncludeAllNetworks to be 1 then the device global traffic would be routed to the VPN, but the excludedRoutes settings in the VPN would be unavailable, no routes would be excluded.
Is the above understanding correct?
Recently found some different results on iOS 12 and iOS 14.
I have an application that is using NEPacketTunnelProvider to establish a VPN tunnel with a remote server. The VPN tunnel is using NWUDPSession and process the inbound packets with the
open func setReadHandler(_ handler: @escaping ([Data]?, Error?) -> Void, maxDatagrams: Int)
If I shutdown the remote VPN server,
on iOS 12 an error will occur
Error Domain=NSPOSIXErrorDomain Code=89 "Operation canceled"
but on iOS 14+ there will be no such error happens.
Is this a bug in iOS 14+ compared with iOS 12?
I have an MDM-managed iPhone 6(iOS 12.5.1) with IPSec(IKEv2) VPN enabled. VPN connects onDemandRules were set in the profiles.
When the VPN is connected and running(both mobile and WIFI network are switched on) I switched off the mobile network, then the VPN stuck on Connecting... state. And I can always reproduce the same issue with the same operations.
I checked the log on the Console and the following messages seems suspicous:
default 11:30:27.808837+0800 nesessionmanager NESMIKEv2VPNSession[blob VPN:C350FBBE-06BE-41AD-8558-277DCECC5C4A]: got On Demand start message from pid 98
default 11:30:27.809324+0800 nesessionmanager NESMIKEv2VPNSession[blob VPN:C350FBBE-06BE-41AD-8558-277DCECC5C4A]: Received a start command from apsd[98]
default 11:30:27.809504+0800 nesessionmanager NESMIKEv2VPNSession[blob VPN:C350FBBE-06BE-41AD-8558-277DCECC5C4A]: Skip a start command from apsd[98]: session in state reasserting
info 11:30:27.809952+0800 nesessionmanager Handling a com.apple.networkextension.file-descriptor-maintainer event
debug 11:30:27.810134+0800 nesessionmanager Ignoring additional event in owner mode
To my understanding, it seems that when I toggled off the mobile network the VPN went into a reasserting state, and at that moment an onDemandRule was matched but was skipped due to the reasserting state.
When I tried the same operations on an iPhone 12 mini(14.2) there is no such issue.
Is it a known issue on iOS 12?
Is NEDNSProxyProvider supported on macOS?
According to this page - https://developer.apple.com/documentation/networkextension/nednsproxyprovider
Availability
iOS 11.0+
macOS 10.15+
Mac Catalyst 13.0+
But on this page - https://developer.apple.com/documentation/networkextension/dns_proxy_provider it says
DNS proxy providers are only supported on supervised iOS devices.
I tested a DNS proxy application on the mac which runs well on iOS devices(I made some project settings change such as profiles, platform settings) and got following error in the console logs
Looking for an extension with identifier com.blob.macappproxy.dns and extension point com.apple.networkextension.dns-proxy
Failed to find an app extension with identifier com.blob.macappproxy.dns and extension point com.apple.networkextension.dns-proxy: (null)
And in the network preferences there is a DNS proxy service added but not running, it shows a message on the panel says
Please use "macappproxy" to control this DNS proxy configuration.
Can someone tell me what's the cause of this error and how can I fix it? Thanks a lot!
When I'm debugging my VPN tunnel provider application on the iPhone device I found some error logs in the console:
udp_validate_cksum_internal [C8.1:1] udp incorrect IPv4-UDP non-offload checksum 0xeaff ulen 1502
It only appears when I'm tuning the MTU to a bigger value for the NEPacketTunnelNetworkSettings.
What does this message mean? Does it mean the inbound udp packet has a bad checksum and will it be dropped by iOS?
When I tested with my iPhone SE(1st generation, iOS 14.0.1) I found that with the VPN(NETunnelProvider) switched on there are no messages shown on the console and also on Xcode it shows iPhone(unavailable). After I switched off the VPN it came back to normal.
Is there anyone else has this problem?
I checked MTU on my MacBook Pro and found that after switch on Internet Sharing the MTU changed. I don't know if this is an issue or it's normal.
Test env:
macOS Catalina
Version 10.15.7
With thunderbolt ethernet connected run following ping to detect the MTU:
% ping -D -s 8164 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 8164 data bytes
ping: sendto: Message too long
ping: sendto: Message too long
Request timeout for icmp_seq 0
ping: sendto: Message too long
Request timeout for icmp_seq 1
^C-- 1.1.1.1 ping statistics
3 packets transmitted, 0 packets received, 100.0% packet loss
% ping -D -s 1473 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 1473 data bytes
ping: sendto: Message too long
ping: sendto: Message too long
Request timeout for icmp_seq 0
ping: sendto: Message too long
Request timeout for icmp_seq 1
^C-- 1.1.1.1 ping statistics
3 packets transmitted, 0 packets received, 100.0% packet loss
% ping -D -s 1472 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 1472 data bytes
1480 bytes from 1.1.1.1: icmp_seq=0 ttl=59 time=0.987 ms
1480 bytes from 1.1.1.1: icmp_seq=1 ttl=59 time=1.253 ms
1480 bytes from 1.1.1.1: icmp_seq=2 ttl=59 time=1.172 ms
^C-- 1.1.1.1 ping statistics
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.987/1.137/1.253/0.111 ms
The MTU should be 1500.
Then switch on Internet Sharing and ping again:
% ping -D -s 8164 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 8164 data bytes
8172 bytes from 1.1.1.1: icmp_seq=0 ttl=59 time=1.417 ms
8172 bytes from 1.1.1.1: icmp_seq=1 ttl=59 time=1.541 ms
8172 bytes from 1.1.1.1: icmp_seq=2 ttl=59 time=1.508 ms
^C-- 1.1.1.1 ping statistics
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.417/1.489/1.541/0.052 ms
% ping -D -s 8165 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 8165 data bytes
ping: sendto: Message too long
ping: sendto: Message too long
Request timeout for icmp_seq 0
ping: sendto: Message too long
Request timeout for icmp_seq 1
ping: sendto: Message too long
Request timeout for icmp_seq 2
^C-- 1.1.1.1 ping statistics
4 packets transmitted, 0 packets received, 100.0% packet loss
The MTU seems changed to 8192.
With ifconfig it shows
en5: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
From packet capture could see that what sent out from en5 are Fragmented IP protocol (proto=ICMP 1... and the length is 1514. So although the ping command set don't fragment the packets are still fragmented.
Can someone tell me if this is normal and how it works? Thanks a lot.
Recently I experienced some weird issues with iOS VPN including personal VPN(IPsec VPN) and enterprise VPN(custom ssl VPN) when running some applications on both mac and iOS.
I coded a network extension program which can run on both mac and iOS. In the network extension it intercepts the packets from the NEPacketTunnelFlow and encap them with a self defined header which is 16 bytes and send them via a UDP session to the remote server.
test env: Xcode 12.0.1 / iOS 14.0 SDK / iPhone iOS 12.4.8
Here are some test results as following. IPSec VPN(personal VPN) which is supported natively by iOS: when running Speedtest from OOKLA it failed to test on mobile network(in my case it's 4G). The message shows
ERROR
Test failed to complete. Check your internet connection and try again
OK
There is no such issue on WIFI network.
custom ssl VPN(enterprise VPN) created by using NETunnelProviderManager:
On WIFI network run Roblox application on iPhone it failed when joining the server with error message
Disconnected
Failed to connect to the Game.(ID=17:Connection attempt failed.)(Error Code: 279)
Leave
I suspect it's related to the mtu setting so I tried
with different tunnelOverheadBytes or mtu values:
on wifi network(my router's mtu is 1480):
work: -100/-16/20 (<=20)
not work: 21 (> 20)
on mobile network:
work:0/-16/-100(very slow)
not work: 1/2/5/10/20/21/28 (> 0)
It's weird that negative numbers work for overhead setting.
And it seems on WIFI network the range of x <= 20 work for the Roblox game application( can join the server and play some games without any problems) and on mobile network the range is x <=0.
Or set mtu instead of tunnelOverheadBytes:
on wifi network:
work:1480/1485/1490/1500
not work:1464/1479/1600
on mobile network:
work:1480/1485/1490/1500
not work:1464/1479/1600/2000
It seems the working value range is [1480, 1500] for both WIFI and mobile network.
And also, Speedtest works on WIFI network but not on mobile network.
To my understanding in the network extension we only need to set the tunnelOverheadBytes and the iOS will compute the mtu size and we don't need to care about the difference between different type of network.
But actually there are differences.
Now I'm totally confused. Apparently the value of tunnelOverheadBytes or mtu is quite critical for the network traffic. How to correctly set the tunnelOverheadBytes in the network extension for both WIFI and mobile network?
I build an app on macOS with NETransparentProxyManager to capture the TCP and UDP traffic on port 80 and 443. There is an issue baffles me.
If I create a UDP session on port 443 like following
sudo nc -ul 443
on one VM and on local macOS
nc -u remoteipofVM 443
then the NEAppProxyProvider can capture the UDP flow and data can be transferred without issues.
But if it was applied to google chrome with the QUIC traffic I can see that in the method handleNewFlow the NEAppProxyUDPFlow was captured but no datagrams could be read out.
Is this because the NETransparentProxy doesn't handle the QUIC traffic or something else?
Recently I met with a weird VPN bypassing problem which seems related to the mobile data network.I wrote an application that created a personal VPN with protocol IPsec(IKEv2) and it connected to a VPN server. On the VPN server side do some traffic filter job.With packet capture on the iOS mobile phone could seeWhen there was only a Wi-Fi network connected all packets were in the IPsec VPN tunnel(could tell it by the packets' source IP and destination IP). Block the WhatsApp traffic on the VPN server-side and it worked well. WhatsApp showed connecting and after on messages were blocked;Switched on mobile data and ran WhatsApp could see WhatsApp traffic was in the VPN tunnel which was connected under the Wi-Fi network. But after a few seconds(around 30 secs) could see WhatsApp traffic was sent out via mobile data network which was 4G network there;If only mobile data network is switched on and Wi-Fi network switched off then could see after trying connecting for a few seconds(around 30 secs) the WhatsApp traffic bypassed VPN and it was not blocked.In summary, I was trying to block the WhatsApp traffic on the VPN server side, but somehow once mobile data was enabled on the iOS device then there will be VPN bypassing issue and WhatsApp can not be blocked.And with more tests ( on iOS 12.4.5 / 13.4.1 / 13.5.1 ), I found thatWith or without WLAN Assist the results are the same;Enterprise VPN written with Network Extension has the same problem;I also tried similar software like Slack but didn't found the same issue.I have no idea how WhatsApp bypass VPN when its traffic was blocked. Is it a bug of the iOS VPN?