Srongswan : Endpoint behind a NAT



In this short post I will describre the problems I met (as well as workarrounds) while I configured a Strongswan service (hosted on a VPS) to establish an IPSec tunnel (policy-based) with an ASA enpoint behind a NAT.

VPN diagram

Strongswan configuration

ipsec.conf

conn centos-to-ftd
        type=tunnel
        auto=start
        keyexchange=ikev2
        authby=secret
        left=10.10.10.10
        leftsubnet=192.168.1.0/24
        right=20.20.20.20
        rightsubnet=10.32.0.0/16
        ike=aes256-sha256-modp2048!
        esp=aes256-sha256!
        aggressive=no
        keyingtries=%forever
        ikelifetime=28800s
        lifetime=3600s
        dpddelay=30s
        dpdtimeout=120s
        dpdaction=restart

ipsec.secret

10.10.10.10 20.20.20.20 : PSK "0123456789ABCDEF"

I will not display the ASA configuration, it is not very interesting for this post.

The configuration is ready but when I start the strongswan daemon the tunnel is failing to establish (it should mount automaticly when the daemon is up). There is an error that is preventing the tunnel to go up.

If we have a look at logs, we can see this:

Jan 2 21:02:24 09[NET] sending packet: from 10.10.10.10[4500] to 20.20.20.20[4500] (320 bytes)
Jan 2 21:02:24 10[NET] received packet: from 20.20.20.20[4500] to 10.10.10.10[4500] (256 bytes)
Jan 2 21:02:24 10[ENC] parsed IKE_AUTH response 1 [ V IDr AUTH SA TSi TSr N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) N(MOBIKE_SUP) ]
Jan 2 21:02:24 10[IKE] authentication of '10.31.99.13' with pre-shared key successful
Jan 2 21:02:24 10[CFG] constraint check failed: identity '20.20.20.20' required
Jan 2 21:02:24 10[CFG] selected peer config 'centos-to-ftd' unacceptable: constraint checking failed
Jan 2 21:02:24 10[CFG] no alternative config found
Jan 2 21:02:24 10[ENC] generating INFORMATIONAL request 2 [ N(AUTH_FAILED) ]

constraint check failed: identity ‘20.20.20.20’ required

Strongswan is expecting to find the IP 10.31.99.13 (which is the true IP address of the endpoint) within the ipsec.conf file, but we did not put it in there.

We cannot fix that by just changing the value of the right field by 10.31.99.13. This is a private IP address and it is unreachable from the internet. A workarround (if not the solution) is to use rightid and assign it to the real IP address of the source interface used to create the VPN tunnel on the ASA side.

conn centos-to-ftd
        <#TRUNCATED#> 

        left=10.10.10.10
        leftsubnet=192.168.1.0/24
        right=20.20.20.20
        rightid=10.31.99.13             # NEW ! 
        rightsubnet=10.32.0.0/16
        
        <#TRUNCATED#>

This time, after rebooting the strongswan deamon, the tunnel is established and no more errors are found in the logs.

Jan 2 21:04:30 09[NET] sending packet: from 10.10.10.10[4500] to 20.20.20.20[4500] (320 bytes)
Jan 2 21:04:30 10[NET] received packet: from 20.20.20.20[4500] to 10.10.10.10[4500] (256 bytes)
Jan 2 21:04:30 10[ENC] parsed IKE_AUTH response 1 [ V IDr AUTH SA TSi TSr N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) N(MOBIKE_SUP) ]
Jan 2 21:04:30 10[IKE] authentication of '10.31.99.13' with pre-shared key successful
Jan 2 21:04:30 10[IKE] IKE_SA centos-to-ftd[1] established between 10.10.10.10[10.10.10.10]...20.20.20.20[10.31.99.13]
Jan 2 21:04:30 10[IKE] scheduling reauthentication in 28179s
Jan 2 21:04:30 10[IKE] maximum IKE_SA lifetime 28719s
Jan 2 21:04:30 10[IKE] received ESP_TFC_PADDING_NOT_SUPPORTED, not using ESPv3 TFC padding
Jan 2 21:04:30 10[CFG] selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
Jan 2 21:04:30 10[IKE] CHILD_SA centos-to-ftd{1} established with SPIs xxxxxx
[root@labfabear strongswan]# strongswan status
Security Associations (1 up, 0 connecting):
centos-to-ftd[3]: ESTABLISHED 2 minutes ago, 10.10.10.10[10.10.10.10]...20.20.20.20[10.31.99.13]
centos-to-ftd{3}: INSTALLED, TUNNEL, reqid 3, ESP in UDP SPIs: cf879764_i 2fae57a3_o
centos-to-ftd{3}: 192.168.1.0/24 === 10.32.0.0/16

While you could thinkg everything is okay it is actually not the truth. The tunnel will only bring itself up if Strongswan is initiatting the connection.

If the ASA firewall is trying to establish the tunnel, it will not work and the Strongswan logs will show this:

Jan 2 21:08:45 11[ENC] parsed IKE_AUTH request 1 [ V IDi AUTH SA TSi TSr N(INIT_CONTACT) N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) ]
Jan 2 21:08:45 11[CFG] looking for peer configs matching 10.10.10.10[%any]...20.20.20.20[10.31.99.13]
Jan 2 21:08:45 11[CFG] candidate "centos-to-ftd", match: 1/20/3100 (me/other/ike)
Jan 2 21:08:45 11[CFG] selected peer config 'centos-to-ftd'
Jan 2 21:08:45 11[IKE] no shared key found for '%any' - '10.31.99.13'

no shared key found for ‘%any’ - ‘10.31.99.13’

IKE_AUTH packets are getting denied by Strongswan because it does not find the pre-shared key linked with the endpoint 10.31.99.13 in the ipsec.secret file.

I did it wrong, I put the reachable public IP of the NAT as the remote endpoint IP instead of the real IP address on the ASA interface. While you are supposed to do that in ipsec.conf to that Strongswan can reach the endpoint, it is not the case on ipsec.secret where you have to put the actual IP address of the endpoint.

To fix the issue, we just have to modify this line:

10.10.10.10 20.20.20.20 : PSK "0123456789ABCDEF"

Like this:

10.10.10.10 10.31.99.13 : PSK "0123456789ABCDEF"

And now it is working. The IPsec tunnel will be established no matter which endpoint is initiating the tunnel.