** WARNING THIS WILL BREAK ALL EXISTING IPSEC CONNECTIONS, YOU WILL NEED TO MAKE NEW CERTIFICATES FOR EXISTING CONNECTIONS **
Having setup IPsec roadwarrior IPFire - Windows 10 recently, I noticed that the ciphers chosen in Windows 10 were quite bad.
IPFire in fact tells you that the modp-1024 used by default in a Windows 10 connection is considered broken.
By default Windows 10 wants to use AES256-CBC/SHA1/MODP-1024 and really none of these are fantastic for the task.
It should be said that whilst SHA1 is considered weak, this is mostly from an auth context. Comparing password hashes or certificate/file fingerprints using SHA1 is bad. Doing integrity checking of data with SHA1 (HMAC-SHA1 in fact) is less bad, because by the time an attacker can generate a collision, we’re already onto new packets and new hashes. But still some risk remains, if they precompute some bad packets I guess it could be possible, and we can do better, so we should.
Go ahead and use this wiki article to set up a working config for your Windows devices to connect to your IPFire appliance.
Through the process, once you connect a Windows 10 device to your IPsec VPN, you will want to SSH into your IPFire appliance and use cat /var/log/messages
to see entries from charon regarding what ciphers are being selected. It is also good to look here for errors.
Now we are going to deliberately break things.
On your Windows 10 client, open PowerShell and type the following:
Set-VpnConnectionIPsecConfiguration -Name "<nameOfYourVPNConnectionHere>" `
>> -AuthenticationTransformConstants GCMAES128 `
>> -CipherTransformConstants GCMAES128`
>> -DHGroup ECP384 `
>> -IntegrityCheckMethod SHA384 `
>> -PfsGroup ECP384 `
>> -EncryptionMethod GCMAES128
You can substitute GCMAES128 with GCMAES256 if you are one of those people that must 256bit key all the things, or are dealing with Government compliance surrounding the transmission of Top Secret data. If you do not fall into those categories, I’d suggest you stick with 128.
Now try and connect the VPN, you will get an error about the IKE machine certificate being invalid. This is because when using ECP384 for the VPN, Windows requires the host certificate and client certificate to also be using ECP384.
By default, IPFire is creating an RSA4096 CA (Root) certificate, and a RSA 2048 host certificate for IPsec. We will need to manually create ECP384 (ECDSA) certificates instead, to use with our hardened Windows 10 clients.
The following commands will need to be done by you via SSH to your IPFire appliance:
It is important to note the different commands for creating the CA, Host and Client certificates. There are subtle differences, we give different usage permissions to each certificate type, so please ensure you follow and paste each command below in exact order, substituting your own values in <> fields.
CA cert creation
Create CA key
pki --gen --type ecdsa --size 384 --outform pem > cakey.pem
Create CA x509 certificate
pki --self --in cakey.pem --dn "C = <Country Code i.e. US>, ST = <State i.e. IL>, L = <City>, O = <Company Name>, OU = <Department>, CN = <Company Name> CA" --ca --outform pem > cacert.pem
Host cert creation
Create host key
pki --gen --type ecdsa --size 384 --outform pem > hostkey.pem
Create Host x509 certificate
pki --issue --in hostkey.pem --type priv --cacert cacert.pem --cakey cakey.pem
--dn "C=<Country>,ST=<State>,O=<Company Name>,OU=<Department>,CN=<FQDN of VPN Server i.e. vpn.contoso.com>" --flag serverAuth
--flag ikeIntermediate --san <FQDN of VPN Server i.e. vpn.contoso.com> --outform pem > hostcert.pem
Move newly created certs to their respective stores, set permissions
mv cacert.pem /var/ipfire/ca/cacert.pem
mv cakey.pem /var/ipfire/private/cakey.pem
mv hostcert.pem /var/ipfire/certs/hostcert.pem
mv hostkey.pem /var/ipfire/certs/hostkey.pem
chown nobody:nobody /var/ipfire/private/cakey.pem
chown nobody:nobody /var/ipfire/ca/cacert.pem
chown nobody:nobody /var/ipfire/certs/hostcert.pem
chown nobody:nobody /var/ipfire/certs/hostkey.pem
chmod 600 /var/ipfire/private/cakey.pem
chmod 644 /var/ipfire/ca/cacert.pem
chmod 644 /var/ipfire/certs/hostcert.pem
chmod 600 /var/ipfire/certs/hostkey.pem
Add ECDSA host key to ipsec.user.secrets
echo ": ECDSA /var/ipfire/certs/hostkey.pem" >> ipsec.user.secrets
Create WIndows Client Certificate
Create client key
pki --gen --type ecdsa --size 384 --outform pem > clientkey.pem
Create client x509 certificate
pki --issue --in clientkey.pem --type priv --cacert /var/ipfire/ca/cacert.pem
--cakey /var/ipfire/private/cakey.pem --dn "C=<Country Code>,ST=<State>,O=<Company Name>,OU=<Department>,CN=<Connection Name>"
--flag clientAuth --outform pem > clientcert.pem
Create PKCS#12 certificate store file (.p12)
openssl pkcs12 -in clientcert.pem -inkey clientkey.pem \
-certfile /var/ipfire/ca/cacert.pem -export -out clientcert.p12
Move the client certificate, certificate store, and set permissions
mv clientcert.p12 /var/ipfire/certs/<Connection Name>.p12
chown nobody:nobody /var/ipfire/certs/<Connection Name>.p12
chmod 600 /var/ipfire/certs/<Connection Name>.p12
mv clientcert.pem /var/ipfire/certs/<Connection Name>cert.pem
chown nobody:nobody /var/ipfire/certs/<Connection Name>cert.pem
chmod 644 /var/ipfire/certs/<Connection Name>cert.pem
Restart IPsec
ipsec restart
Now navigate to the IPSec page in the WUI, and download the .p12 certificate store for your Windows connection, just as you did previously following the wiki, and import them into Windows once again.
While you are in the WUI, also edit the ciphers that your IPsec connection is using like so:
Now you can try and connect the VPN once more, and it should succeed.
The command on IPFire cat /var/log/messages
should show the following in the charon output: selected proposal: IKE:AES_GCM_16_128/PRF_HMAC_SHA2_384/ECP_384
This means that the WIndows client successfully negotiated and connected with our hardened configuration. Yay!
Note: I use AES-128-GCM because it is widely accepted that there is no great benefit to be obtained by using 256 over 128 bit keys in AES. AES-256 is mostly for resistance against future quantum threats, threats which are not known to exist yet. AES-128-GCM is the perfect algo for streaming like this, it is fast and when AES is used in GCM mode, it is actually providing integrity checking of the data as it is decrypting, making it a wonderful algorithm for streaming data we need to both encrypt and validate as is the case.
Edit Here is the cypher recommendations from my countries cyber spies. If you go with GCMAES256 using the above configuration, you will be meeting the necessary cipher combinations for TOP SECRET in Australia. Probably USA as well given that we really just copy everything USA does, one of five eyes and all that.