[Swan] Options for Windows clients

Manfred mx2927 at gmail.com
Thu Dec 31 16:36:21 UTC 2020


On 12/31/2020 4:14 AM, Alex wrote:
> Hi,
>>> certutil -S -c "Example CA" -n "win10client.example.com" \
>>>           -s "O=Example,CN=win10client.example.com" -k rsa \
>>>           -g 4096 -v 36 -d sql:/etc/ipsec.d -t ",," -1 -6 -8
>>> "win10client.example.com"
>> I see that the options -1 and -6 have no argument. Apparently this
>> triggers an interactive loop to specify the respective properties.
>> I think the client options should be:
>> -1 "digitalSignature,keyEncipherment"
>> -6 "clientAuth"
>> For the server:
>> -1 "digitalSignature,keyEncipherment"
>> -6 "serverAuth,ipsecIKEIntermediate"
> I believe it was either the first or second message on this thread I
> asked if it was a problem that I was testing on the same network I was
> located on, but perhaps that got overlooked :-)
That's possible, I was not sure about that either, and eventually ended 
up giving the wrong answer! Sorry about that.

  I recalled it being a
> problem when I did this like fifteen years ago, lol. I've since
> connected through my phone.
> Anyway, it was either that or a combination of changes I made to the
> certutil command that got me a bit further.
Probably both.
After seeing your commands I'd say --extKeyUsage for the client cert had 
a role too.

> Dec 30 22:06:47.568952: "ikev2-cp"[2] local IKE
> proposals (IKE SA responder matching remote proposals):
> Dec 30 22:06:47.569014: "ikev2-cp"[2]
> 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 30 22:06:47.569029: "ikev2-cp"[2]
> 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 30 22:06:47.569041: "ikev2-cp"[2]
> 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 30 22:06:47.569052: "ikev2-cp"[2]
> 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 30 22:06:47.569083: "ikev2-cp"[2] #3: proposal
> 2:IKE=AES_CBC_256-HMAC_SHA2_256-HMAC_SHA2_256_128-MODP2048 chosen from
> r
> emote proposals
> 2:IKE:ENCR=AES_CBC_256;INTEG=HMAC_SHA2_256_128;PRF=HMAC_SHA2_256;DH=MODP2048[first-match]
> Dec 30 22:06:47.573387: "ikev2-cp"[2] #3: sent
> IKE_SA_INIT reply {auth=IKEv2 cipher=AES_CBC_256
> integ=HMAC_SHA2_256_128 prf
> =HMAC_SHA2_256 group=MODP2048}
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.
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.

> Dec 30 22:06:47.702497: "ikev2-cp"[2] #3: processing
> decrypted IKE_AUTH request: SK{IDi,CERT,CERTREQ,AUTH,CP,SA,TSi,TSr}
> Dec 30 22:06:47.704044: "ikev2-cp"[2] #3: certificate
> verified OK: O=Example,CN=win10client.example.com
> Dec 30 22:06:47.704103: "ikev2-cp"[2] #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] #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.

> Dec 30 22:06:47.718096: "ikev2-cp"[2] #4: no local
> proposal matches remote proposals
> Dec 30 22:06:47.718122: "ikev2-cp"[2] #4: IKE_AUTH
> responder matching remote ESP/AH proposals failed, responder SA
> processing returned STF_FAIL+v2N_NO_PROPOSAL_CHOSEN
This is phase 2 which fails.
The relevant parameters of Set-VpnConnectionIPsecConfiguration at this 
stage are:
-AuthenticationTransformConstants SHA256128
-CipherTransformConstants AES256
(The relevant part in the libreswan config is the esp=... line or its 
default value if not present.)

The log shows that the (failing) proposal sent by Windows is

This does not match the parameters of Set-VpnConnectionIPsecConfiguration.

It appears that Windows is not sending the proposals as required by 
 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?

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.

> Dec 30 22:06:47.718134: "ikev2-cp"[2] #4: responding to
> IKE_AUTH message (ID 1) from with encrypted
> notification NO_PROPOSAL_CHOSEN
> Dec 30 22:06:47.718209: "ikev2-cp"[2] #4: state
> transition 'Responder: process IKE_AUTH request' failed
> Dec 30 22:06:47.718250: "ikev2-cp"[2] #4: deleting
> state (STATE_V2_IKE_AUTH_CHILD_R0) aged 0.00017s and NOT sending
> notification
> Windows reports the same "policy match error".
> 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:" --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

By adding -8 "orion.example.com" and --extSAN "ip:" I 
believe you are adding two entries to the subjectAltName extension, 
resulting in something like:
subjectAltName = "dns:orion.example.com,ip:"
This is technically correct, /if/ 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"

I'd drop the "ip:" part anyway because you have to 
configure this IP address in Windows or DNS anyway[*], and this is best 
set in one place only.

> # generate Windows certificate
> 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 \
>          --extSAN "ip:" --keyUsage
> digitalSignature,keyEncipherment \
>          --extKeyUsage "clientAuth"

Same story about
-8 "win10client.example.com"
--extSAN "ip:"

However, this time the "ip:" 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:") altogether.

> certutil -L -d /var/lib/ipsec/nss
> pk12util -o win10client.example.com.p12 -n "win10client.example.com"
> -d /var/lib/ipsec/nss

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 

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.

> Some of this is adapted from
> https://github.com/hwdsl2/setup-ipsec-vpn
> Here is the set-vpnconnection command:
> Set-VpnConnectionIPsecConfiguration -ConnectionName ikev2-cp
> -EncryptionMethod AES256 -DHGroup Group14 -IntegrityCheckMethod SHA384
> -PfsGroup PFS2048 -AuthenticationTransformConstants SHA256128
> -CipherTransformConstants AES256
Recalling from the above, I'd change -IntegrityCheckMethod SHA384 into 
-IntegrityCheckMethod SHA256 unless you configure your ike=... line 
But first of all I would check the registry if it still contains the 
tweaked entry and restore that to default state (which might mean 
removing the entry).

> Thank you again for your help.

[*] Your cert uses the FQDN in CN, so in Windows you need to use the VPN 
responder hostname, giving it means to resolve it to an IP address.

More information about the Swan mailing list