strongSwan setup where both sides are behind NAT

33,479

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.

Share:
33,479
reish
Author by

reish

Updated on September 18, 2022

Comments

  • reish
    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 and venus is the client. Both sun and venus are behind NAT networks. sun is not the gateway of my home networks. However, ports 4500, 500 and 50 (UDP) are forwarded to sun.

    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 in venus 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
      Michael Hampton over 10 years
      Did you forward UDP port 4500 to sun from its NAT gateway?
    • Michael Hampton
      Michael Hampton over 10 years
      The packets on port 4500 are obviously not making it from venus to sun. 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
      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
      anders about 7 years
      I realize this is super old, but why do you define a ip pool on sun with rightsourceip?
  • ecdsa
    ecdsa over 10 years
    It 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 the IKE_SA_INIT response, whereas the initiator sends them together with the certificate in the IKE_AUTH request. So if the NAT box only has problems handling inbound fragments it could explain why it worked in that direction. Could you do tcpdump captures of such a successful connection setup?
  • reish
    reish over 10 years
    I'll do that and post the results. One more question if I may: If sun already has venus's certificated installed then venus won't be required to send the cetrificate, so how does venus "proves" that it owns this certificate?
  • ecdsa
    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 in venus's certificate to verify that the signature is correct. If sun 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 by venus in the IKE_AUTH message, it must be signed/issued by a trusted, i.e. locally installed, CA certificate (otherwise it would be trivial for venus to forge a certificate).
  • reish
    reish over 10 years
    It 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