Using IPSEC Mutual RSA with Windows clients
I've been asked to set an IPSEC VPN on pfSense 2.2.6 (yes it's old, no I can't do anything about it short term) for a machine running the Windows 10 built in IPSEC (RAS?) client. It should use RSA keys for auth which I can't get working. I can get it up using a PSK and reach hosts on pfSense network, but either way I can't get onward routing to work so I'd appreciate some help with those two issues if anyone can see the problem.
The tunnel must conform to the PRIME profile linked below, though I established that ECDSA-256 is not yet supported for auth and it was accepted to use X.509 certificates with RSA signatures (2048 bits) and SHA-256 instead as per the Foundation profile. Don't worry about it reading it, just to illustrate where the requirements come from.
After mangling around with Powershell I managed to set all the correct ciphers and hashes etc but I can't get it to auth using mutual RSA. I can get the tunnel up if I use a PSK with EAP-MSCHAPv2 as the authentication method, so I don't know what I'm missing here.
I imported the CA cert created on pfSense (2048 bits, SHA-256 as required) into Windows as a Trusted Root Certificate. I also have a server cert and a client cert, but I'm not clear on whether I need both, or just the client cert or where to import them to. I've tried to import the client and server certs into various certificate stores (personal certificate, client authentication issuers) but I'm not a Windows guy and can't find any docs that tell me what to store them or whether I need them both. There may just be some incompatibility between pfSense and Windows 10 that means mutual RSA doesn't work and I have to use a PSK. I just don't know enough in this area and can't find definitive docs. The CA and server certs are also used successfully with an OpenVPN server so they should be good. The hostname of the pfSense VPN server is publicly resolvable and set as the CN in the CA and server certs.
Second issue, even if I get the VPN up I have an issue where the client can reach the hosts it needs to in the networks local to the pfSense box it is VPNed in to, but it also needs to be able to reach some devices on networks reachable by the pfSense box over an OpenVPN as below.
[client] <->IPSEC <-> [pfSense site A] <-> [OpenVPN] <-> [pfSense site B]
The Phase 2 has a local network of 0.0.0.0/0 to force all client traffic over the IPSEC tunnel though the Windows client helpfully ignores that so I have to manually enable 'Use default gateway on remote network' in the Windows IPSEC interface configuration otherwise it can't even reach site A.
pfSense site A is an OpenVPN client of pfSense site B. The pfSense box in site A can reach stuff in site B over that VPN, but my IPSEC client can't. In the OpenVPN client configuration at site A, the networks the IPSEC client needs to reach are given in the IPv4 Remote Network/s parameter. In the OpenVPN server configuration in site B, the networks that the IPSEC client needs to reach are given in IPv4 Local Network/s and in IPv4 Remote Network/s is the IPSEC client network, so I believe it should be fully routable but those packets just don't seem to appear in site B and they're not getting blocked by the firewalls either. I have rules in place to permit the traffic and they're not appearing in the firewall logs as being blocked.
On pfSense in site A, I can see the packets from the IPSEC client hitting the outbound ovpnc interface but they're not arriving on the ovpns interface in site B. I can see the site B networks in the routing table on pfSense site A. On pfSense site B I can see the IPSEC client network in the routing table. E.g.
[site a]/root: netstat -rn 192.168.1.0/24 10.10.0.5 UGS ovpnc2 [site a]/root: tcpdump -i ovpnc2 src 10.99.100.1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ovpnc2, link-type NULL (BSD loopback), capture size 65535 bytes 18:36:00.274197 IP 10.99.100.1 > 192.168.1.10: ICMP echo request, id 1, seq 232, length 40 18:36:24.072718 IP 10.99.100.1 > 192.168.1.10: ICMP echo request, id 1, seq 233, length 40 18:36:28.781091 IP 10.99.100.1 > 192.168.1.10: ICMP echo request, id 1, seq 234, length 40
[site b]root/: netstat -rn 10.99.100.0/30 10.10.0.2 UGS ovpns2 [site b]/root: tcpdump -i ovpns2 src 10.99.100.1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ovpns2, link-type NULL (BSD loopback), capture size 65535 bytes <tumbleweeds...>
Have I missed something in the routing somewhere?
I'd be grateful if anybody is able to spot what I'm doing wrong here. I can provide config screenshots and logs if required as far as I am permitted by client confidentiality.
As an example, if I tell the Windows client to use EAP with 'Microsoft Smart Card or other certificate' and set pfSense to use Mutual RSA, I get an error on the Windows end "IKE authentication credentials are unacceptable" and on the pfSense end I see (newest first):
Jun 29 19:33:05 charon: 13[CFG] <bypasslan|27> no alternative config found Jun 29 19:33:05 charon: 13[IKE] <bypasslan|27> peer requested EAP, config inacceptable Jun 29 19:33:05 charon: 13[CFG] <con3|27> switching to peer config 'bypasslan' Jun 29 19:33:05 charon: 13[IKE] <con3|27> peer requested EAP, config inacceptable Jun 29 19:33:05 charon: 13[CFG] <con3|27> selected peer config 'con3' Jun 29 19:33:05 charon: 13[CFG] <27> looking for peer configs matching x.x.x.x[%any]...y.y.y.y[10.2.3.33] Jun 29 19:33:05 charon: 13[IKE] <27> received 60 cert requests for an unknown ca Jun 29 19:33:05 charon: 13[IKE] <27> received cert request for "C=GB, ST=London, L=London, O=XYZ, Efirstname.lastname@example.org, CN=vpn.site.xyz.com"
However if I try to use EAP-TTLS on both ends and Microsoft Smart Card or other certificate as the EAP method I get "The system cannot write to the specified device" at the Windows end.
Hopefully that's a little more helpful.
I also posted a perhaps more succinct version of this on the pfSense Reddit:
So I've managed to push this on a bit by using EAP-TLS and creating new server and user certs which contained additional alternative names as described here:
I discovered the reason Windows reported not being able to write to the device was because I was telling it to use EAP-TTLS thinking it was EAP-TLS instead of 'Microsoft Smart Card or other certificate' and for some reason it was defaulting to trying to use a smart card.
So I'm still getting 'IKE authentication credentials are unacceptable' on the Windows end but on the pfSense end I'm now getting:
Jul 1 11:59:59 charon: 09[CFG] <con3|98> selected peer config 'con3' inacceptable: non-matching authentication done Jul 1 11:59:59 charon: 09[CFG] selected peer config 'con3' inacceptable: non-matching authentication done Jul 1 11:59:59 charon: 09[CFG] <con3|98> constraint check failed: peer not authenticated by CA 'C=GB, ST=London, L=London, O=XYZ, Eemail@example.com, CN=vpn.site.xyz.com' Jul 1 11:59:59 charon: 09[CFG] constraint check failed: peer not authenticated by CA 'C=GB, ST=London, L=London, O=XYZ, Efirstname.lastname@example.org, CN=vpn.site.xyz.com' Jul 1 11:59:59 charon: 09[IKE] <con3|98> authentication of '10.2.4.33' with EAP successful Jul 1 11:59:59 charon: 09[IKE] authentication of '10.2.4.33' with EAP successful
Can anybody see what my mistake might be here? What does that 'constraint check failed' mean?
I've had to give up on this and use a PSK after all, the deadline is tomorrow :-/
EAP-TLS is the correct choice. Though I do not know if it was all working properly on pfSense 2.2.x, which is extremely old. I know it works on recent versions because I set up a windows client not long ago.
On Windows you'll need to:
- Import the CA which signed the client TLS cert:
Import-Certificate -FilePath "userca.pem" -CertStoreLocation Cert:\LocalMachine\Root\
- Import the client TLS cert/key:
Import-PfxCertificate -FilePath "usercert.p12" -CertStoreLocation Cert:\CurrentUser\My\ -Password abc123(password on the .p12, if it has one)
- Import the CA which signed the server TLS cert:
Import-Certificate -FilePath "serverca.pem" -CertStoreLocation Cert:\LocalMachine\Root\
- (optional, but recommended) Add a custom EAP XML config which enables server cert verification for the hostname. IIRC this can be done in the GUI later but is more of a pain to automate.
- Do the usual
Add-VpnConnectionbits with the parameters to add the VPN, set for IKEv2, EAP, and so on.
- Import the CA which signed the client TLS cert:
Also it's worth mentioning:
pfSense 2.2.6 (yes it's old, no I can't do anything about it short term)
It's not just old, it's nearly five years old and over four years out of date. Having a secure VPN is a secondary concern to having such an outdated and insecure firewall in place. Upgrading that (and, more likely, replacing the hardware) should be a very short term and high priority concern.
Thanks for that. I realise the pfSense version is badly out of date and needs updating. Unfortunately it has been planned then postponed by the people that own the firewalls several times after I'd done all of the work to prepare. It was discussed again a few days ago and the hardware will be replaced with a fresh pfSense install. I believe they had CARP break in an upgrade between 2.1.x to 2.2 and have been reluctant to upgrade them ever since.