Recently I've been trying to set up IKEv2 EAP-TLS authentication with StrongSwan. I've managed to set everything up so that my Android client connects successfully, but ran into some trouble with iOS. The internal client just doesn't like something about my server configuration or it's certificate and sends TLS close notify
message in the middle of IKE_AUTH
exchange and shows User authentication error
to the user. At the same time, EAP-MSCHAPv2 method with the same server certificate is ok for some reason.
The server certificate has it's server_Auth
and IKEIntermediate
flags, as iOS requires, keys are 4096 bit. I've been searching for a while now and I'm out of ideas. Please help me out.
iOS 15.6.1 Release.
Connection log:
Aug 28 20:08:20 debian ipsec[1334]: 02[IKE] initiating EAP_TLS method (id 0x84)
Aug 28 20:08:20 debian ipsec[1334]: 02[IKE] received ESP_TFC_PADDING_NOT_SUPPORTED, not using ESPv3 TFC padding
Aug 28 20:08:20 debian ipsec[1334]: 02[IKE] peer supports MOBIKE
Aug 28 20:08:20 debian ipsec[1334]: 02[IKE] authentication of '192.168.50.60' (myself) with RSA signature successful
Aug 28 20:08:20 debian ipsec[1334]: 02[IKE] sending end entity cert "CN=192.168.50.60"
Aug 28 20:08:20 debian ipsec[1334]: 02[ENC] generating IKE_AUTH response 1 [ IDr CERT AUTH EAP/REQ/TLS ]
Aug 28 20:08:20 debian ipsec[1334]: 02[ENC] splitting IKE message (1916 bytes) into 2 fragments
Aug 28 20:08:20 debian ipsec[1334]: 02[ENC] generating IKE_AUTH response 1 [ EF(1/2) ]
Aug 28 20:08:20 debian ipsec[1334]: 02[ENC] generating IKE_AUTH response 1 [ EF(2/2) ]
Aug 28 20:08:20 debian ipsec[1334]: 02[NET] sending packet: from 192.168.50.60[4500] to 192.168.50.50[4500] (1248 bytes)
Aug 28 20:08:20 debian ipsec[1334]: 02[NET] sending packet: from 192.168.50.60[4500] to 192.168.50.50[4500] (736 bytes)
Aug 28 20:08:20 debian ipsec[1334]: 06[NET] received packet: from 192.168.50.50[4500] to 192.168.50.60[4500] (236 bytes)
Aug 28 20:08:20 debian ipsec[1334]: 06[ENC] parsed IKE_AUTH request 2 [ EAP/RES/TLS ]
Aug 28 20:08:20 debian ipsec[1334]: 06[TLS] negotiated TLS 1.2 using suite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Aug 28 20:08:20 debian ipsec[1334]: 06[TLS] sending TLS server certificate 'CN=192.168.50.60'
Aug 28 20:08:20 debian ipsec[1334]: 06[TLS] sending TLS cert request for 'CN=test Root CA'
Aug 28 20:08:20 debian ipsec[1334]: 06[ENC] generating IKE_AUTH response 2 [ EAP/REQ/TLS ]
Aug 28 20:08:20 debian ipsec[1334]: 06[NET] sending packet: from 192.168.50.60[4500] to 192.168.50.50[4500] (1100 bytes)
Aug 28 20:08:20 debian ipsec[1334]: 05[NET] received packet: from 192.168.50.50[4500] to 192.168.50.60[4500] (76 bytes)
Aug 28 20:08:20 debian ipsec[1334]: 05[ENC] parsed IKE_AUTH request 3 [ EAP/RES/TLS ]
Aug 28 20:08:20 debian charon: 05[NET] sending packet: from 192.168.50.60[4500] to 192.168.50.50[4500] (1100 bytes)
Aug 28 20:08:20 debian ipsec[1334]: 05[ENC] generating IKE_AUTH response 3 [ EAP/REQ/TLS ]
Aug 28 20:08:20 debian charon: 07[NET] received packet: from 192.168.50.50[4500] to 192.168.50.60[4500] (92 bytes)
Aug 28 20:08:20 debian charon: 07[ENC] parsed IKE_AUTH request 4 [ EAP/RES/TLS ]
Aug 28 20:08:20 debian charon: 07[TLS] received TLS close notify
Aug 28 20:08:20 debian charon: 07[TLS] sending TLS close notify
Aug 28 20:08:20 debian charon: 07[ENC] generating IKE_AUTH response 4 [ EAP/REQ/TLS ]
Aug 28 20:08:20 debian charon: 07[NET] sending packet: from 192.168.50.60[4500] to 192.168.50.50[4500] (92 bytes)
Aug 28 20:08:50 debian charon: 13[JOB] deleting half open IKE_SA with 192.168.50.50 after timeout
Aug 28 20:08:50 debian charon: 14[JOB] deleting half open IKE_SA with 192.168.50.50 after timeout
ipsec.conf:
config setup
charondebug="ike 1, knl 1, cfg 0"
uniqueids=no
conn ikev2-vpn
auto=add
compress=no
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
dpdaction=clear
dpddelay=300s
rekey=no
left=%any
leftid=192.168.50.60
leftcert=server-cert.pem
leftsendcert=always
leftsubnet=0.0.0.0/0
right=%any
rightid=%any
rightauth=eap-tls
rightsendcert=always
rightsourceip=10.10.10.0/24
rightdns=8.8.8.8,8.8.4.4
ike=chacha20poly1305-sha512-curve25519-prfsha512,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha1-modp1024,aes256-sha256-modp2048,3des-sha1-modp1024!
esp=chacha20poly1305-sha512,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,3des-sha1!
Server certificate:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 5326615466311432545 (0x49ebf08b84983961)
Signature Algorithm: sha384WithRSAEncryption
Issuer: CN = test Root CA
Validity
Not Before: Aug 25 20:20:04 2022 GMT
Not After : Aug 24 20:20:04 2027 GMT
Subject: CN = 192.168.50.60
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
Modulus:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Authority Key Identifier:
keyid:30:CA:E4:2A:DF:42:9D:77:E0:57:FB:8F:DE:EE:12:FA:02:EF:4B:3C
X509v3 Subject Alternative Name:
DNS:192.168.50.60, IP Address:192.168.50.60
X509v3 Extended Key Usage:
TLS Web Server Authentication, 1.3.6.1.5.5.8.2.2
Signature Algorithm: sha384WithRSAEncryption
...
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Found a workaround
Most people wouldn't even encounter this issue as everyone nowadays can buy a cheap domain name and use it in Common Name and SubjectAlternativeName of the server certificate. iOS client requires the DNS name of the TLS server to be in SANs. Remote ID
setting of my client was set to server's IP address (192.168.50.60). iOS sent it as IP of course, server decided it was perfectly okay as it's leftid
was set to 192.168.50.60
and proceeded with the authentication. At this moment iOS client checked whether DNS name of the server was amongst the SANs of the server certificate. And it was not. The server didn't even have a DNS name, it had a workaround with an IP address being interpreted as DNS name. I think it tried to match Remote ID
to DNS SAN DNS:192.168.50.60
and got confused. I'm not sure why it doesn't do that when not using certificate client authentication.
I added a fake DNS name testvpn.xyz
to the server cert's SANs, set it as leftid
in ipsec.conf
and set it as Remote ID
of the client. And it worked, iOS client establishes connection. It would be much easier to buy a domain name from the beginning. Oh well.
Server certificate:
...
X509v3 Subject Alternative Name:
IP Address:192.168.50.60, DNS:192.168.50.60, DNS:testvpn.xyz
X509v3 Extended Key Usage:
TLS Web Server Authentication, 1.3.6.1.5.5.8.2.2
...
ipsec.conf:
conn ikev2-vpn
...
left=%any
leftid=testvpn.xyz
leftcert=server-cert.pem
leftsendcert=always
...