IPsec IKEv2 EAP-MSCHAPv2 stopped working with iOS 18.1 update

Started by d39FAPH7, November 01, 2024, 08:56:34 AM

Previous topic - Next topic
Hi,
i am strictly following this guide using "Method 1 - Shared IP pool for all roadwarriors"

https://docs.opnsense.org/manual/how-tos/ipsec-swanctl-rw-ikev2-eap-mschapv2.html

While this worked on iOS 18.01 on iPhones and iPads it stopped working on 18.1 somehow. As usual for iOS devices there is no error message at all.

log looks like this:
Quote
06[NET] <5c5afb18-9f41-4e90-8a2b-2a7534266587|18> sending packet: from IP[4500] to IP[21501] (400 bytes)
06[ENC] <5c5afb18-9f41-4e90-8a2b-2a7534266587|18> generating IKE_AUTH response 1 [ IDr AUTH EAP/REQ/ID ]
06[IKE] <5c5afb18-9f41-4e90-8a2b-2a7534266587|18> authentication of 'location.MYHOST.com' (myself) with RSA_EMSA_PKCS1_SHA2_256 successful
06[IKE] <5c5afb18-9f41-4e90-8a2b-2a7534266587|18> received ESP_TFC_PADDING_NOT_SUPPORTED, not using ESPv3 TFC padding
06[IKE] <5c5afb18-9f41-4e90-8a2b-2a7534266587|18> peer supports MOBIKE
06[IKE] <5c5afb18-9f41-4e90-8a2b-2a7534266587|18> initiating EAP_IDENTITY method (id 0x00)
06[CFG] <5c5afb18-9f41-4e90-8a2b-2a7534266587|18> selected peer config '5c5afb18-9f41-4e90-8a2b-2a7534266587'
06[CFG] <18> looking for peer configs matching IP[location.MYHOST.com]...IP[IP]
06[ENC] <18> parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr CPRQ(ADDR MASK DHCP DNS ADDR6 DHCP6 DNS6 DOMAIN) N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) SA TSi TSr N(MOBIKE_SUP) ]
06[ENC] <18> unknown attribute type INTERNAL_DNS_DOMAIN
06[NET] <18> received packet: from IP[21501] to IP[4500] (400 bytes)
06[NET] <18> sending packet: from IP[500] to IP[500] (497 bytes)
06[ENC] <18> generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) CERTREQ N(FRAG_SUP) N(HASH_ALG) N(CHDLESS_SUP) N(MULT_AUTH) ]
06[IKE] <18> sending cert request for "C=DE, ST=MYHOST-opnsense, L=MYHOST-opnsense, O=MYHOST-opnsense, OU=MYHOST-opnsense, E=MYHOST-opnsense, CN=location.MYHOST.com"
06[IKE] <18> remote host is behind NAT
06[CFG] <18> selected proposal: IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
06[IKE] <18> IP is initiating an IKE_SA
06[ENC] <18> parsed IKE_SA_INIT request 0 [ SA KE No N(REDIR_SUP) N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) ]
06[NET] <18> received packet: from IP[500] to IP[500] (562 bytes)
06[NET] <17> sending packet: from IP[500] to IP[500] (38 bytes)
06[ENC] <17> generating IKE_SA_INIT response 0 [ N(INVAL_KE) ]
06[IKE] <17> DH group ECP_256 unacceptable, requesting MODP_2048
06[IKE] <17> remote host is behind NAT
06[CFG] <17> selected proposal: IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
06[IKE] <17> IP is initiating an IKE_SA
06[ENC] <17> parsed IKE_SA_INIT request 0 [ SA KE No N(REDIR_SUP) N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) ]
06[NET] <17> received packet: from IP[500] to IP[500] (370 bytes)

actually the log looks ok to me because on a working iOS 18.01 device it looks exactly the same up to the point "sending packet: from IP[4500] to IP[21501] (400 bytes)" and continues with "received packet: from IP[41260] to IP[4500] (112 bytes)"
it simply does not go on for some reason. this is likely not an OPNsense problem but an apple bug or apple has changed something that is incompatible since 18.1 like self signed certificates that are valid too long or something that i am not aware of.

does anybody know a workaround?

thanks

//Update: When connecting the iOS device to Apple Configurator Utility there's a possibility to log things. the relevant error messages seem to be:

Quote
NEIKEv2Provider(NetworkExtension)[1483] <Error>: [IKE_SA_INIT R resp0 FA8B49559B813784-0000000000000000] Initiator init received notify error Error Domain=NEIKEv2ProtocolErrorDomain Code=17 "InvalidKEPayload" UserInfo={NSDebugDescription=InvalidKEPayload}

NEIKEv2Provider(NetworkExtension)[1483] <Error>: [IKE_AUTH R resp1 FA8B49559B813784-B1C5080634BCCCFD] No certificate payload received

NEIKEv2Provider(NetworkExtension)[1483] <Notice>: IKEv2IKESA[1.1, FA8B49559B813784-B1C5080634BCCCFD] state Connecting -> Disconnected error (null) -> Error Domain=NEIKEv2ErrorDomain Code=8 "Authentication: No certificate payload received" UserInfo={NSLocalizedDescription=Authentication: No certificate payload received}

Hello, since version 18.1, I've been experiencing the same issue. Are there any new updates or solutions regarding this?

It looks like the iOS device would like ECP_256 instead of MODP_2048.

Additionally it looks like a certificate error, the client doesnt send a certificate to the server and thus the authentication round fails.

It seems like both of these issues would need to be fixed, but its hard (with the certificate) without knowing what apple changed or expects now.
Hardware:
DEC740

True. I overlooked that. This can be fixed by setting proposals to aes256/sha256/ecp256 [DH19, NIST EC]. I can comfirm that with ecp256 instead of modp2048 macOS Sequoia 15.1 is still perfectly able to connect, so ecp256 seems to be the new way to go on newer apple devices/OSes.
however on iOS it will still not proceed after "sending packet: from IP[4500] to IP[21501] (400 bytes)"

I would test if it works with a publicly trusted certificate instead of a self signed one. It looks like the client does not offer any certificate to the server, that is strange. Maybe there have been changes to the internal certificate store in iOS.
Hardware:
DEC740

I configured the VPN using Apple Configurator and boom it works (using the same details as on the GUI but anyway). While playing around i created a profile which did *not* include the CA Certificate. It is also not installed on the iOS device from previous configurations. This made me think and i tried to configure a VPN connection on a macOS sequoia 15.1 mac that has never seen the self signed CA certificate and i can perfectly log in. Now is that intended behaviour?
I know for sure that on previous OPNsense installations using the legacy methond https://docs.opnsense.org/manual/how-tos/ipsec-rw-srv-mschapv2.html i could never login before manually trusting the self signed certificate in macOS keychain storage.

//Update: Is it possible that this is wrong in the documentation https://docs.opnsense.org/manual/how-tos/ipsec-swanctl-rw-ikev2-eap-mschapv2.html where it says:

Local Authentication
Authentication: "Public Key"

Doesn't this have to be "Pre-Shared Key" instead of "Public Key" ?

So what you are saying is that iOS starts to work again without any certificate on the OPNsense and the iOS device?

The local authentication should be correct with public key, since Strongswan itself uses the certificate. It does not use a Pre-Shared Key for self authentication.

06[IKE] <5c5afb18-9f41-4e90-8a2b-2a7534266587|18> authentication of 'location.MYHOST.com' (myself) with RSA_EMSA_PKCS1_SHA2_256 successful

Here it uses RSA to verify the authenticity of the peer (itself): https://docs.strongswan.org/docs/5.9/howtos/introduction.html#_authentication_basics

Without any certificate this might work but its less secure. I have not tried it actually.

I will try this out with my own iPhone when I have time and correct the documentation if there is something wrong here.
Hardware:
DEC740

yes you're right. when setting it to pre-shared key no login is possible. what made me curious was that with "Public Key" selected the list of selected "Public Keys" is completely empty.

I think there are two aspects here
1: is probably an iOS problem where it won't work on the GUI but with the same details entered in Apple Configurator it will work. This started with iOS18.1 - on 18.01 it worked the on-device-GUI (or wizard) way. This is why i believe that this is an apple related problem or change.

2: is that it doesn't make a difference if i install a self signed certificate or not. That applies to both iOS and macOS. I can login with both methods and i diffed the logs. there's absoluty no difference. I know that with older pfSense or OPNsense configurations using the older legacy method guide it was impossible to log in if you didn't trust the CA certificate on iOS or macOS. i don't know if that is a possible security issue

Thanks for the explanation. I will test this on my iPhone soon.  :)
Hardware:
DEC740

Just for the record:
To fix the iOS 18.1 Problem you need to set "Send certificate" under p1 settings to "Always" as described here:
https://github.com/opnsense/docs/issues/639
Other method is to use Apple configurator which i already found out ealier in this post but is also mentioned here: https://docs.strongswan.org/docs/5.9/interop/ios.html#_ikev2_on_ios_9_and_macos_10_11

Maybe someone will be interested, I use this config for my phones. Authorization via freeradius and certificate from letsencrypt. It works for several years without problems.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>IKEv2</key>
<dict>
<key>AuthName</key>
<string>username</string>
<key>AuthPassword</key>
<string>verystrongpassword</string>
<key>AuthenticationMethod</key>
<string>None</string>
<key>ChildSecurityAssociationParameters</key>
<dict>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-384</string>
</dict>
<key>DeadPeerDetectionRate</key>
<string>Low</string>
<key>EnableFallback</key>
<false/>
<key>EnablePFS</key>
<true/>
<key>ExtendedAuthEnabled</key>
<integer>1</integer>
<key>IKESecurityAssociationParameters</key>
<dict>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-384</string>
</dict>
<key>LocalIdentifier</key>
<string>username</string>
<key>NATKeepAliveOffloadEnable</key>
<integer>1</integer>
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Disconnect</string>
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
<key>SSIDMatch</key>
<array>
<string>SSID</string>
<string>SSID_1</string>
</array>
</dict>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
<key>RemoteAddress</key>
<string>vpn.example.net</string>
<key>RemoteIdentifier</key>
<string>vpn.example.net</string>
<key>ServerCertificateCommonName</key>
<string>vpn.example.net</string>
<key>UseConfigurationAttributeInternalIPSubnet</key>
<false/>
</dict>
<key>PayloadDisplayName</key>
<string>ikev2.home</string>
<key>PayloadIdentifier</key>
<string>net.example.vpn.conf1</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadUUID</key>
<string>cf6e0c93-a7f4-485b-90ff-7904668e68cd</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>UserDefinedName</key>
<string>ikev2.home</string>
<key>VPNType</key>
<string>IKEv2</string>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>ikev2.home</string>
<key>PayloadIdentifier</key>
<string>ikev2.home</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>7aadc059-c7c4-4034-ac96-e1b6ccb69b81</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>