[Swan] Options for Windows clients

Manfred mx2927 at gmail.com
Fri Jan 1 17:45:20 UTC 2021


Hi Alex,

I see you managed to get a connection up.
I think I still see some issues in the log though, but I won't repeat 
myself since it is all in my previous posts.

Good luck!

On 12/31/2020 8:14 PM, Alex wrote:
> Hi Manfred,
> 
> I got it to work subsequent to your email. I'll explain how I got it
> to work, but my next issue is with DHCP.
> 
>> OK, so phase 1 passes.
>> However, it still looks like Windows is sending multiple proposals,
>> while when using Set-VpnConnectionIPsecConfiguration I think only one
>> should be sent.
>> Moreover:
>> The relevant parameters of Set-VpnConnectionIPsecConfiguration at this
>> stage (phase 1) are:
>> -EncryptionMethod AES256
>> -IntegrityCheckMethod SHA384
>> -DHGroup Group14
>> (The relevant part in the libreswan config is the ike=... line or its
>> default value if not present.)
>>
>> -IntegrityCheckMethod SHA384 (as in you command below) does not match
>> INTEG=HMAC_SHA2_256_128 which appears to be sent by Windows and logged
>> as the accepted proposal by libreswan.
> 
> Here is a working example of using add/set-vpnconnection:
> Add-VpnConnection -Name "ikev2-cp" -ServerAddress orion.example.com
> -TunnelType "Ikev2" -PassThru -Force -EncryptionLevel "Required"
> -AllUserConnection -AuthenticationMethod MachineCertificate
> Set-VpnConnectionIPsecConfiguration
> -ConnectionName "ikev2-cp"
> -EncryptionMethod AES256
> -DHGroup Group14
> -IntegrityCheckMethod SHA384
> -PfsGroup PFS2048
> -AuthenticationTransformConstants SHA256128
> -CipherTransformConstants AES256
> 
> The following also works, using these two changes:
> -AuthenticationTransformConstants GCMAES256
> -CipherTransformConstants GCMAES256
> 
>>> Dec 30 22:06:47.702497: "ikev2-cp"[2] 172.58.238.215 #3: processing
>>> decrypted IKE_AUTH request: SK{IDi,CERT,CERTREQ,AUTH,CP,SA,TSi,TSr}
>>> Dec 30 22:06:47.704044: "ikev2-cp"[2] 172.58.238.215 #3: certificate
>>> verified OK: O=Example,CN=win10client.example.com
>>> Dec 30 22:06:47.704103: "ikev2-cp"[2] 172.58.238.215 #3: IKEv2 mode
>>> peer ID is ID_DER_ASN1_DN: 'CN=win10client.example.com, O=Example'
>>> Dec 30 22:06:47.704669: "ikev2-cp"[2] 172.58.238.215 #3: authenticated
>>> using RSA with SHA1
>> Client authentication passes too. It says "RSA with SHA1", which should
>> map to authby=rsasig in your conf file.
> 
> Turns out authby= isn't even necessary in order to work.
> 
>> The log shows that the (failing) proposal sent by Windows is
>> 1:ESP:ENCR=AES_CBC_128;INTEG=HMAC_SHA1_96;ESN=DISABLED
>>
>> This does not match the parameters of Set-VpnConnectionIPsecConfiguration.
>>
>> It appears that Windows is not sending the proposals as required by
>> Set-VpnConnectionIPsecConfiguration.
>>   From the strongswan thread you posted earlier I remember the last
>> comment about the manually tweaked registry entry overriding some
>> parametres of Set-VpnConnectionIPsecConfiguration. Do you still have
>> that registry entry in place?
> 
> I've tested it both with and without and it works either way. Looks
> like it's not necessary (anymore?).
> 
>> On the libreswan side do you have an esp=... line in your config? If so
>> compare that with the proposal sent by Windows. It looks like the phase
>> 2 proposal sent by Windows has weak ciphers, though - meaning you may
>> really want to change the registry rather than the esp=... line. Paul
>> might be more specific on this.
> 
> Yes, just before your email I added the following:
> 
> esp=aes_gcm256-null,aes_gcm128-null,aes256-sha2_512,aes128-sha2_512,aes256-sha1,aes128-sha1,aes_gcm256-null
> 
> This was pulled from an Oct 2019 post to this list that included
> modp1024 at the end that I stripped off here.
> 
>>> Here are the certutil commands I am now using:
>>>
>>> # generate CA certificate
>>> echo "Generating CA certificate...."
>>> certutil -z <(head -c 1024 /dev/urandom) \
>>>           -S -x -n "Example CA" -s "O=Example,CN=Example CA" -k rsa \
>>>           -g 4096 -v 36 -t "CT,," -2 -d /var/lib/ipsec/nss
>>>
>>> # generate orion client certificate
>>> echo "Generating orion client certificate..."
>>> certutil -z <(head -c 1024 /dev/urandom) \
>>>           -S -c "Example CA" -n "orion.example.com" -s
>>> "O=Example,CN=orion.example.com" \
>>>           -k rsa -g 4096 -v 120 -t ",," -1 -6 -8 "orion.example.com" -d
>>> /var/lib/ipsec/nss \
>>>           --extSAN "ip:68.195.111.42" --keyUsage
>>> "digitalSignature,keyEncipherment" \
>>>           --extKeyUsage "serverAuth,ipsecIKEIntermediate"
>> Option -1 is an alias for --keyUsage, since you are using --keyUsage
>> with an explicit argument I would drop -1
>> Same for option -6 and --extKeyUsage
> 
> it turns out --extKeyUsage is necessary - I went through the process
> of recreating the entire thing then transferring the Windows cert
> again, but it then produces the following error:
> 
> certificate O=Example,CN=Example CA failed IPsec verification
> NSS ERROR: Peer's certificate has an invalid signature.
> 
> This is with "orion.example.com" set in the Windows connection issue.
> 
>> By adding -8 "orion.example.com" and --extSAN "ip:68.195.111.42" I
>> believe you are adding two entries to the subjectAltName extension,
>> resulting in something like:
>> subjectAltName = "dns:orion.example.com,ip:68.195.111.42"
>> This is technically correct, /if/ 68.195.111.42 is the IP address of the
>> VPN gatweay as seen by the Windows client, however it might be more
>> complicated that it needs be.
>> You may verify that this is the actual result with
>>     certutil -L -d sql:/var/lib/ipsec/nss -n "orion.example.com"
> 
> Yes, that's what it produced, but somehow appears necessary. btw, the
> 68.195.111.42 is the IP of the VPN gateway and 192.168.1.1 is its
> internal gateway address.
> 
>>> certutil -z <(head -c 1024 /dev/urandom) \
>>>           -S -c "Example CA" -n "win10client.example.com" \
>>>           -s "O=Example,CN=win10client.example.com" -k rsa \
>>>           -g 4096 -v 120 -t ",," -8 "win10client.example.com" -d
>>> /var/lib/ipsec/nss \
>>>           --extSAN "ip:68.195.111.42" --keyUsage
>>> digitalSignature,keyEncipherment \
>>>           --extKeyUsage "clientAuth"
>>
>> Same story about
>> -8 "win10client.example.com"
>> --extSAN "ip:68.195.111.42"
> 
> I've re-added this to the cert here too.
> 
>> However, this time the "ip:68.195.111.42" part is most probably wrong,
>> because it should contain the IP address of the client, that can't be
>> the same as the server's.
>> Considering that the client may be a roadwarrior with dynamic IP, I
>> would drop this part (--extSAN "ip:68.195.111.42") altogether.
> 
> Perhaps it was only the VPN server cert that this change was necessary.
> 
>> The first comment below is about the following two lines.
>>> pk12util -o orion.example.com.p12 -n "orion.example.com" -d /var/lib/ipsec/nss
>>> ipsec import orion.example.com.p12
>>
>> Two comments about -d /var/lib/ipsec/nss - only informational, don't let
>> them confuse you:
>> 1) If /var/lib/ipsec/nss is the default database path used by ipsec,
>> then since you generate the server certificate in that database I think
>> you don't need to export to p12 and import again in the same database.
>> Take this with a grain of salt since I don't use certutil to create my
>> certs.
>>
>> 2) creating the client certificate in /var/lib/ipsec/nss means you'll
>> have that certificate in the default ipsec database too. This is not
>> needed by libreswan. The client certificate is meant to be sent by the
>> initiator(client) to the responder(server) which will validate it
>> according to its trusted CA and requirements on client identity.
>>
>> The example in the libreswan page uses ${HOME}/tmpdb (IIRC) which is a
>> private location in the user's home directory. Note that in this
>> scenario the commands given take care of importing the applicable CA(s)
>> together with the certificate - the server cert and CA in the ipsec
>> database, and the client cert and CA to the Windows client.
>>
>> I'm not saying the way you're doing this above is wrong, just pointing
>> out a couple of differences with the example in the libreswan page.
> 
> Understood. Makes sense. Works without it.
> 
> Okay, so here's the output from a working connection. An explanation
> of what protocols are actually being used (chosen) here would be
> helpful, just so I can better understand.
> 
> Dec 31 13:53:06.175169: "ikev2-cp"[1] 172.58.239.44: local IKE
> proposals (IKE SA responder matching remote proposals):
> Dec 31 13:53:06.175231: "ikev2-cp"[1] 172.58.239.44:
> 1:IKE=AES_GCM_C_256-HMAC_SHA2_512+HMAC_SHA2_256-NONE-MODP2048+MODP3072+MODP4096+MODP8192+ECP_256+ECP_384+ECP_521+CURVE25519
> Dec 31 13:53:06.175245: "ikev2-cp"[1] 172.58.239.44:
> 2:IKE=AES_GCM_C_128-HMAC_SHA2_512+HMAC_SHA2_256-NONE-MODP2048+MODP3072+MODP4096+MODP8192+ECP_256+ECP_384+ECP_521+CURVE25519
> Dec 31 13:53:06.175255: "ikev2-cp"[1] 172.58.239.44:
> 3:IKE=AES_CBC_256-HMAC_SHA2_512+HMAC_SHA2_256-HMAC_SHA2_512_256+HMAC_SHA2_256_128-MODP2048+MODP3072+MODP4096+MODP8192+ECP_256+ECP_384+ECP_521+CURVE25519
> Dec 31 13:53:06.175264: "ikev2-cp"[1] 172.58.239.44:
> 4:IKE=AES_CBC_128-HMAC_SHA2_512+HMAC_SHA2_256-HMAC_SHA2_512_256+HMAC_SHA2_256_128-MODP2048+MODP3072+MODP4096+MODP8192+ECP_256+ECP_384+ECP_521+CURVE25519
> Dec 31 13:53:06.175292: "ikev2-cp"[1] 172.58.239.44 #1: proposal
> 2:IKE=AES_CBC_256-HMAC_SHA2_256-HMAC_SHA2_256_128-MODP2048 chosen from
> remote proposals
> 1:IKE:ENCR=AES_CBC_256;INTEG=HMAC_SHA1_96;PRF=HMAC_SHA1;DH=MODP2048
> 2:IKE:ENCR=AES_CBC_256;INTEG=HMAC_SHA2_256_128;PRF=HMAC_SHA2_256;DH=MODP2048[first-match]
> 3:IKE:ENCR=AES_CBC_256;INTEG=HMAC_SHA2_384_192;PRF=HMAC_SHA2_384;DH=MODP2048
> Dec 31 13:53:06.180370: "ikev2-cp"[1] 172.58.239.44 #1: sent
> IKE_SA_INIT reply {auth=IKEv2 cipher=AES_CBC_256
> integ=HMAC_SHA2_256_128 prf=HMAC_SHA2_256 group=MODP2048}
> Dec 31 13:53:06.338336: "ikev2-cp"[1] 172.58.239.44 #1: processing
> decrypted IKE_AUTH request: SK{IDi,CERT,CERTREQ,AUTH,CP,SA,TSi,TSr}
> Dec 31 13:53:06.338370: loading root certificate cache
> Dec 31 13:53:06.342990: "ikev2-cp"[1] 172.58.239.44 #1: certificate
> verified OK: O=Example,CN=win10client.example.com
> Dec 31 13:53:06.343028: "ikev2-cp"[1] 172.58.239.44 #1: certificate
> subjectAltName extension does not match ID_IPV4_ADDR '172.58.239.44'
> Dec 31 13:53:06.343035: "ikev2-cp"[1] 172.58.239.44 #1: Peer CERT
> payload SubjectAltName does not match peer ID for this connection
> Dec 31 13:53:06.343038: "ikev2-cp"[1] 172.58.239.44 #1: X509:
> connection failed due to unmatched IKE ID in certificate SAN
> Dec 31 13:53:06.347987: "ikev2-cp"[1] 172.58.239.44 #1: reloaded
> private key matching left certificate 'orion.example.com'
> Dec 31 13:53:06.348005: "ikev2-cp"[1] 172.58.239.44 #1: switched from
> "ikev2-cp"[1] 172.58.239.44 to "ikev2-cp"
> Dec 31 13:53:06.348021: "ikev2-cp"[1] 172.58.239.44: deleting
> connection instance with peer 172.58.239.44 {isakmp=#0/ipsec=#0}
> Dec 31 13:53:06.348038: "ikev2-cp"[2] 172.58.239.44 #1: IKEv2 mode
> peer ID is ID_DER_ASN1_DN: 'CN=win10client.example.com, O=Example'
> Dec 31 13:53:06.348241: "ikev2-cp"[2] 172.58.239.44 #1: authenticated
> using RSA with SHA1
> Dec 31 13:53:06.370523: | pool 192.168.6.2-192.168.6.254: growing
> address pool from 0 to 1
> Dec 31 13:53:06.370591: "ikev2-cp"[2] 172.58.239.44: local ESP/AH
> proposals (IKE_AUTH responder matching remote ESP/AH proposals):
> Dec 31 13:53:06.370601: "ikev2-cp"[2] 172.58.239.44:
> 1:ESP=AES_GCM_C_256-NONE-NONE-DISABLED
> Dec 31 13:53:06.370612: "ikev2-cp"[2] 172.58.239.44:
> 2:ESP=AES_GCM_C_128-NONE-NONE-DISABLED
> Dec 31 13:53:06.370615: "ikev2-cp"[2] 172.58.239.44:
> 3:ESP=AES_CBC_256-HMAC_SHA2_512_256-NONE-DISABLED
> Dec 31 13:53:06.370618: "ikev2-cp"[2] 172.58.239.44:
> 4:ESP=AES_CBC_128-HMAC_SHA2_512_256-NONE-DISABLED
> Dec 31 13:53:06.370621: "ikev2-cp"[2] 172.58.239.44:
> 5:ESP=AES_CBC_256-HMAC_SHA1_96-NONE-DISABLED
> Dec 31 13:53:06.370624: "ikev2-cp"[2] 172.58.239.44:
> 6:ESP=AES_CBC_128-HMAC_SHA1_96-NONE-DISABLED
> Dec 31 13:53:06.370633: "ikev2-cp"[2] 172.58.239.44 #2: proposal
> 1:ESP=AES_CBC_128-HMAC_SHA1_96-DISABLED SPI=7e4be64a chosen from
> remote proposals
> 1:ESP:ENCR=AES_CBC_128;INTEG=HMAC_SHA1_96;ESN=DISABLED[first-match]
> Dec 31 13:53:06.432432: "ikev2-cp"[2] 172.58.239.44 #2: negotiated
> connection [0.0.0.0-255.255.255.255:0-65535 0] ->
> [192.168.6.2-192.168.6.2:0-65535 0]
> Dec 31 13:53:06.432482: "ikev2-cp"[2] 172.58.239.44 #2: IPsec SA
> established tunnel mode {ESPinUDP=>0x7e4be64a <0xa7eb30f0
> xfrm=AES_CBC_128-HMAC_SHA1_96 NATOA=none NATD=172.58.239.44:28512
> DPD=active}
> 
> Here is my working config. No ike= or authby= entry necessary.
> 
> conn ikev2-cp
>      left=68.195.111.42
>      leftcert=orion.example.com
>      leftid=@68.195.111.42
>      leftsendcert=always
>      leftsubnet=0.0.0.0/0
>      leftrsasigkey=%cert
>      right=%any
>      rightaddresspool=192.168.6.2-192.168.6.254
>      rightca=%same
>      rightrsasigkey=%cert
>      modecfgdns=8.8.8.8,193.100.157.123
>      narrowing=yes
>      dpddelay=30
>      dpdtimeout=120
>      dpdaction=clear
>      auto=add
>      ikev2=insist
>      rekey=no
>      fragmentation=yes
>      esp=aes_gcm256-null,aes_gcm128-null,aes256-sha2_512,aes128-sha2_512,aes256-sha1,aes128-sha1,aes_gcm256-null
> 
> Here is my working script to produce the Windows certs:
> 
> #!/bin/bash
> rm -f /var/lib/ipsec/nss/*db
> ipsec initnss
> 
> # No password needed for database.
> certutil -N -d /var/lib/ipsec/nss
> 
> echo "Generating CA certificate...."
> certutil -z <(head -c 1024 /dev/urandom) \
>          -S -x -n "Example CA" -s "O=Example,CN=Example CA" -k rsa \
>          -g 4096 -v 36 -t "CT,," -2 -d /var/lib/ipsec/nss
> 
> echo "Generating orion client certificate..."
> certutil -z <(head -c 1024 /dev/urandom) \
>          -S -c "Example CA" -n "orion.example.com" -s
> "O=Example,CN=orion.example.com" \
>          -k rsa -g 4096 -v 120 -t ",," -8 "orion.example.com" -d
> /var/lib/ipsec/nss \
>          --keyUsage "digitalSignature,keyEncipherment" --extKeyUsage
> "serverAuth,ipsecIKEIntermediate" \
>          --extSAN "ip:68.195.111.42"
> 
> echo "Generating Windows certificate..."
> certutil -z <(head -c 1024 /dev/urandom) \
>          -S -c "Example CA" -n "win10client.example.com" \
>          -s "O=Example,CN=win10client.example.com" -k rsa \
>          -g 4096 -v 120 -t ",," -8 "win10client.example.com" -d
> /var/lib/ipsec/nss \
>          --keyUsage digitalSignature,keyEncipherment --extKeyUsage "clientAuth" \
>          --extSAN "ip:68.195.111.42"
> 
> certutil -L -d /var/lib/ipsec/nss
> 
> pk12util -o win10client.example.com.p12 -n "win10client.example.com"
> -d /var/lib/ipsec/nss
> #pk12util -o orion.example.com.p12 -n "orion.example.com" -d /var/lib/ipsec/nss
> #ipsec import orion.example.com.p12
> 
> Can we add some of this to the wiki so someone else doesn't have to go
> through all of this? There's no way the wiki entry would work as it is
> currently.
> 
> I also want to experiment a bit more with the add/set-vpnconnection
> commands - it seems unreasonable for end-users to have to enter those
> commands.
> 


More information about the Swan mailing list