strongSwan setup where both sides are behind NAT
Due to the certificates and certificate requests IKE_AUTH
messages can get quite large, so much so that they have to be fragmented on the IP layer (you can see those fragments in the tcpdump
capture at venus
). Perhaps the NAT box at sun
has problems reassembling fragmented packets or just drops them.
As a workaround, you can try installing the two peer's certificates on both sides, then configure rightcert
accordingly so that it points to the file containing the certificate of the other peer.
With that done, you can configure rightsendcert=never
on both ends, to avoid that certificate requests are being sent. Because leftsendcert
defaults to ifasked
the peers ultimately won't send their certificates and the message size should be small enough to avoid IP fragments.
By the way, you don't have to open UDP port 50. Without NAT traversal you'd need to allow IP protocol 50 (ESP), but if a NAT is involved ESP packets get UDP encapsulated so opening UDP ports 500 and 4500 is sufficient.
![reish](https://i.stack.imgur.com/jEUAq.jpg?s=256&g=1)
reish
Updated on September 18, 2022Comments
-
reish almost 2 years
I'm trying to setup a strongSwan server in my home and connect to it from another network. Let's say
sun
is the VPN server andvenus
is the client. Bothsun
andvenus
are behind NAT networks.sun
is not the gateway of my home networks. However, ports 4500, 500 and 50 (UDP) are forwarded tosun
.ipsec.conf (sun)
# ipsec.conf - strongSwan IPsec configuration file # basic configuration config setup charonstart=yes plutostart=no conn venus left=%any leftcert=sunCert.pem right=%any leftsubnet=10.135.1.0/24 rightid="C=IL, O=KrustyKrab, CN=venus" keyexchange=ikev2 auto=add type=tunnel mobike=no include /var/lib/strongswan/ipsec.conf.inc
ipsec.conf (venus)
# ipsec.conf - strongSwan IPsec configuration file # basic configuration config setup charonstart=yes plutostart=no conn krustykrab left=%defaultroute leftsourceip=%config leftid="C=IL, O=KrustyKrab, CN=venus" leftcert=venusCert.pem right=x.x.x.x # My home public IP rightsubnet=10.135.1.0/24 rightid="C=IL, O=KrustyKrab, CN=sun" keyexchange=ikev2 auto=start type=tunnel mobike=no # include /var/lib/strongswan/ipsec.conf.inc
Sun's private IP is 10.135.1.200 and Venus's private IP is 192.168.10.200 This is what happens when I try to connect:
Sun (y.y.y.y is Venus's public IP):
13[NET] received packet: from y.y.y.y[500] to 10.135.1.200[500] 13[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) ] 13[IKE] y.y.y.y is initiating an IKE_SA 13[IKE] local host is behind NAT, sending keep alives 13[IKE] remote host is behind NAT 13[IKE] sending cert request for "C=IL, O=KrustyKrab, CN=KrustyKrab CA" 13[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) CERTREQ N(MULT_AUTH) ] 13[NET] sending packet: from 10.135.1.200[500] to y.y.y.y[500] 14[IKE] sending keep alive 14[NET] sending packet: from 10.135.1.200[500] to y.y.y.y[500] 15[JOB] deleting half open IKE_SA after timeout
Venus (x.x.x.x is Sun's public IP)
13[IKE] initiating IKE_SA krustykrab[1] to x.x.x.x 13[ENC] generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) ] 13[NET] sending packet: from 192.168.10.200[500] to x.x.x.x[500] 14[NET] received packet: from x.x.x.x[500] to 192.168.10.200[500] 14[ENC] parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) CERTREQ N(MULT_AUTH) ] 14[IKE] local host is behind NAT, sending keep alives 14[IKE] remote host is behind NAT 14[IKE] received cert request for "C=IL, O=KrustyKrab, CN=KrustyKrab CA" 14[IKE] sending cert request for "C=IL, O=KrustyKrab, CN=KrustyKrab CA" 14[IKE] authentication of 'C=IL, O=KrustyKrab, CN=venus' (myself) with RSA signature successful 14[IKE] sending end entity cert "C=IL, O=KrustyKrab, CN=venus" 14[IKE] establishing CHILD_SA krustykrab 14[ENC] generating IKE_AUTH request 1 [ IDi CERT N(INIT_CONTACT) CERTREQ IDr AUTH CP(ADDR DNS) SA TSi TSr N(MULT_AUTH) N(EAP_ONLY) ] 14[NET] sending packet: from 192.168.10.200[4500] to x.x.x.x[4500] 09[IKE] retransmit 1 of request with message ID 1 09[NET] sending packet: from 192.168.10.200[4500] to x.x.x.x[4500] 10[IKE] retransmit 2 of request with message ID 1 10[NET] sending packet: from 192.168.10.200[4500] to x.x.x.x[4500] 11[IKE] retransmit 3 of request with message ID 1 11[NET] sending packet: from 192.168.10.200[4500] to x.x.x.x[4500] 14[IKE] sending keep alive 14[NET] sending packet: from 192.168.10.200[4500] to x.x.x.x[4500] 15[IKE] retransmit 4 of request with message ID 1 15[NET] sending packet: from 192.168.10.200[4500] to x.x.x.x[4500] 10[IKE] sending keep alive 10[NET] sending packet: from 192.168.10.200[4500] to x.x.x.x[4500] 12[IKE] sending keep alive 12[NET] sending packet: from 192.168.10.200[4500] to x.x.x.x[4500] 11[IKE] retransmit 5 of request with message ID 1 11[NET] sending packet: from 192.168.10.200[4500] to x.x.x.x[4500]
tcpdump in Venus:
16:57:42.389799 IP 192.168.10.200.500 > x.x.x.x.500: isakmp: parent_sa ikev2_init[I] 16:57:42.465073 IP x.x.x.x.500 > 192.168.10.200.500: isakmp: parent_sa ikev2_init[R] 16:57:42.712016 IP 192.168.10.200.4500 > x.x.x.x.4500: NONESP-encap: isakmp: child_sa ikev2_auth[I] 16:57:42.712057 IP 192.168.10.200 > x.x.x.x: ip-proto-17 16:57:46.712854 IP 192.168.10.200.4500 > x.x.x.x.4500: NONESP-encap: isakmp: child_sa ikev2_auth[I] 16:57:46.712911 IP 192.168.10.200 > x.x.x.x: ip-proto-17 16:57:53.913742 IP 192.168.10.200.4500 > x.x.x.x.4500: NONESP-encap: isakmp: child_sa ikev2_auth[I] 16:57:53.913799 IP 192.168.10.200 > x.x.x.x: ip-proto-17 16:58:02.458669 IP x.x.x.x.500 > 192.168.10.200.500: [|isakmp] 16:58:06.874834 IP 192.168.10.200.4500 > x.x.x.x.4500: NONESP-encap: isakmp: child_sa ikev2_auth[I] 16:58:06.874884 IP 192.168.10.200 > x.x.x.x: ip-proto-17
tcpdump in Sun:
16:59:06.521762 IP y.y.y.y.500 > 10.135.1.200.500: isakmp: parent_sa ikev2_init[I] 16:59:06.556423 IP 10.135.1.200.500 > y.y.y.y.500: isakmp: parent_sa ikev2_init[R] 16:59:26.556324 IP 10.135.1.200.500 > y.y.y.y.500: [|isakmp]
It seems that
sun
doesn't get packets in port 4500, which is odd, since I opened up a Python interpreter invenus
and typed:In [1]: from socket import * In [2]: x = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) In [3]: x.sendto('', ('x.x.x.x', 4500)) Out[3]: 0
And the packet was received:
17:02:45.246769 IP y.y.y.y.44335 > 10.135.1.200.4500: [|isakmp]
I also tried setting
port_nat_t = 6000
In
charon
section in both sides, but they still try to use port 4500-
Michael Hampton over 10 yearsDid you forward UDP port 4500 to
sun
from its NAT gateway? -
Michael Hampton over 10 yearsThe packets on port 4500 are obviously not making it from
venus
tosun
. So it's probably time to break out Wireshark or something and figure out why. Oh, and if you can get rid of NAT on one or both sides, that would probably help too. -
reish over 10 years@MichaelHampton - I attached tcpdumps. Is it possible that my home router rejects ipsec packets even though port 4500 is forwarded?
-
anders about 7 yearsI realize this is super old, but why do you define a ip pool on sun with rightsourceip?
-
-
ecdsa over 10 yearsIt depends, but the initiator's
IKE_AUTH
message is usually larger than the responder's. One reason for this is that the responder sends the certificate requests in theIKE_SA_INIT
response, whereas the initiator sends them together with the certificate in theIKE_AUTH
request. So if the NAT box only has problems handling inbound fragments it could explain why it worked in that direction. Could you dotcpdump
captures of such a successful connection setup? -
reish over 10 yearsI'll do that and post the results. One more question if I may: If
sun
already hasvenus
's certificated installed thenvenus
won't be required to send the cetrificate, so how doesvenus
"proves" that it owns this certificate? -
ecdsa over 10 years
venus
provides a signature created with the private key that belongs to the public key contained in its certificate.sun
uses the public key contained invenus
's certificate to verify that the signature is correct. Ifsun
has the certificate installed locally it will trust it unconditionally and accept the signature (so it can be a self-signed certificate). On the other hand, if the certificate is sent byvenus
in theIKE_AUTH
message, it must be signed/issued by a trusted, i.e. locally installed, CA certificate (otherwise it would be trivial forvenus
to forge a certificate). -
reish over 10 yearsIt works. I don't even have to install the certificate on both sides. Just preventing venus from sending the certificate seems to be enough. Sadly I didn't find any way to prevent my NAT box from blocking fragmented packets