Fun with Vyatta VC5 and IPsec tunnel mode s2s VPN when both Vyattas VPN gateways are behind NAT devices using dynamic public IP addresses

Recently the bellow scenario was bought to my attention:

net_145_diag

As we can see, we have two Vyattas VC5 VPN gateways behind two NAT devices, and these NAT devices use dynamic public IP addresses on their external interfaces(and DynDNS is configured on these NAT devices).
So, can an IPsec tunnel mode s2s VPN can be created between the two Vyattas ?
The short answer may be: no, not from Vyatta’s CLI.
Actually, we may be able to get this working, with some small changes outside Vyatta’s CLI just on one Vyatta, but a problem would still remain.

I fired a quick lab, out of curiosity, like in the above diagram, the only little problem was that DynDNS was not available in my lab, so I had to “figure” something.

 

Anyway, on the left router, I don’t want to be forced to configure something outside Vyatta’s CLI.

First basic config(I will also NAT on Vyatta too, to hide the subnet behind it being seen by the NAT device in front of Vyatta):

set interfaces ethernet eth0 address 192.168.60.2/24
set interfaces ethernet eth1 address 192.168.40.1/24
set service ssh protocol-version 2
set protocols static route 0.0.0.0/0 next-hop 192.168.60.1
set system host-name r1
commit

set service nat rule 10 type source
set service nat rule 10 source address 192.168.40.0/24
set service nat rule 10 destination address 192.168.10.0/24
set service nat rule 10 outbound-interface eth0
set service nat rule 10 outside-address address 192.168.60.2
set service nat rule 10 exclude

set service nat rule 100 type source
set service nat rule 100 source address 192.168.40.0/24
set service nat rule 100 outbound-interface eth0
set service nat rule 100 outside-address address 192.168.60.2
commit

 

Next, the IPsec tunnel mode s2s VPN config:

set vpn ipsec ipsec-interfaces interface eth0
set vpn ipsec nat-traversal enable

set vpn ipsec ike-group IKE1 proposal 1
set vpn ipsec ike-group IKE1 proposal 1 encryption aes128
set vpn ipsec ike-group IKE1 proposal 1 hash sha1
set vpn ipsec ike-group IKE1 proposal 1 dh-group 5
set vpn ipsec ike-group IKE1 lifetime 28800
set vpn ipsec ike-group IKE1 dead-peer-detection action clear
set vpn ipsec ike-group IKE1 dead-peer-detection interval 15
set vpn ipsec ike-group IKE1 dead-peer-detection timeout 45

set vpn ipsec esp-group ESP1 proposal 1
set vpn ipsec esp-group ESP1 proposal 1 encryption aes128
set vpn ipsec esp-group ESP1 proposal 1 hash sha1
set vpn ipsec esp-group ESP1 pfs
set vpn ipsec esp-group ESP1 lifetime 3600

edit vpn ipsec site-to-site peer @rightvyatta
set authentication mode pre-shared-secret
set authentication pre-shared-secret 12345
set authentication id @leftvyatta
set ike-group IKE1
set local-ip 0.0.0.0
set tunnel 1 local-subnet 192.168.40.0/24
set tunnel 1 remote-subnet 192.168.10.0/24
set tunnel 1 esp-group ESP1
top

commit

As can be noted, the left Vyatta is in “waiting mode”. The local ip was set to 0.0.0.0 and an id, @leftvyatta, to be used during IKE MM authentication was configured.
Also the remote VPN gateway can use any IP address, as long as it will present the id @rightvyatta during IKE MM authentication. Since we have a single s2s right now, we can have a pre-shared key for IKE MM authentication too.
And, DPD will be used, please note that on left Vyatta, the action was set to clear, note the timeout value too.

 

Moving to right Vyatta now, unfortunately we need some extra touches outside the CLI to make it work up to a certain point.

First basic config(I will also NAT on Vyatta too, to hide the subnet behind it being seen by the NAT device in front of Vyatta):

set interfaces ethernet eth0 address 192.168.50.2/24
set interfaces ethernet eth1 address 192.168.10.1/24
set service ssh protocol-version 2
set protocols static route 0.0.0.0/0 next-hop 192.168.50.1
set system host-name r4
commit

set service nat rule 10 type source
set service nat rule 10 source address 192.168.10.0/24
set service nat rule 10 destination address 192.168.40.0/24
set service nat rule 10 outbound-interface eth0
set service nat rule 10 outside-address address 192.168.50.2
set service nat rule 10 exclude

set service nat rule 100 type source
set service nat rule 100 source address 192.168.10.0/24
set service nat rule 100 outbound-interface eth0
set service nat rule 100 outside-address address 192.168.50.2
commit

And the IPsec tunnel mode s2s VPN config:

set vpn ipsec ipsec-interfaces interface eth0
set vpn ipsec nat-traversal enable

set vpn ipsec ike-group IKE1 proposal 1
set vpn ipsec ike-group IKE1 proposal 1 encryption aes128
set vpn ipsec ike-group IKE1 proposal 1 hash sha1
set vpn ipsec ike-group IKE1 proposal 1 dh-group 5
set vpn ipsec ike-group IKE1 lifetime 28800
set vpn ipsec ike-group IKE1 dead-peer-detection action restart
set vpn ipsec ike-group IKE1 dead-peer-detection interval 15
set vpn ipsec ike-group IKE1 dead-peer-detection timeout 60

set vpn ipsec esp-group ESP1 proposal 1
set vpn ipsec esp-group ESP1 proposal 1 encryption aes128
set vpn ipsec esp-group ESP1 proposal 1 hash sha1
set vpn ipsec esp-group ESP1 pfs
set vpn ipsec esp-group ESP1 lifetime 3600

edit vpn ipsec site-to-site peer left.carbonwind.net
set authentication mode pre-shared-secret
set authentication pre-shared-secret 12345
set authentication id @rightvyatta
set ike-group IKE1
set local-ip 0.0.0.0
set tunnel 1 local-subnet 192.168.10.0/24
set tunnel 1 remote-subnet 192.168.40.0/24
set tunnel 1 esp-group ESP1
top

commit

Here, as can be seen we have some changes compared with left Vyatta.
First we defined the peer using a host name, assuming that DynDNS is working correctly.
Here too the local IP was defines as 0.0.0.0, and local Vyatta was configured to use the id @rightvyatta during IKE MM authentication.
And DPD action was set to restart, a higher timeout value was used, so left Vyatta will figure it first that the tunnel is down, clear the IKE MM and QM SAs, then right Vyatta will figure this, and will try to bring up the tunnel again, initiating new IKE MM negotiations.

The first problem, is the IKE MM id the left Vyatta will use, as can be seen from above the right Vyatta is not aware of it, thus IKE MM negotiations will fail. Something like(left.carbonwind.net was resolved to 192.168.22.240):
"peer-left.carbonwind.net-tunnel-1" #2: we require peer to have ID '192.168.22.240', but peer declares '@leftvyatta'.

To correct this, as apparently it’s not doable from the CLI, I've edited the /etc/ipsec.conf file and added the rightid=@leftvyatta line.

conn peer-left.carbonwind.net-tunnel-1
    left=%defaultroute
    leftid=@rightvyatta
    right=left.carbonwind.net
    rightid=@leftvyatta
    leftsubnet=192.168.10.0/24
    rightsubnet=192.168.40.0/24
    ike=aes128-sha1-modp1536
    ikelifetime=28800s
    aggrmode=no
    dpddelay=15s
    dpdtimeout=60s
    dpdaction=restart
    esp=aes128-sha1
    keylife=3600s
    rekeymargin=540s
    type=tunnel
    pfs=yes
    compress=no
    authby=secret
    auto=start

But we’re not done, we need to make sure the needed pre-shared key will be found, so I’ve edited the /etc/ipsec.secrets file:

and modified:
@rightvyatta left.carbonwind.net : PSK "12345"

into:
@rightvyatta @leftvyatta : PSK "12345"

 

A quick clear vpn ipsec-process command on the right Vyatta, and the VPN tunnel is up and running(an excerpt of the logs):

Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: initiating Main Mode
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: received Vendor ID payload [Openswan (this version) 2.4.12  LDAP_V3 PLUTO_SENDS_VENDORID PLUTO_USES_KEYRR]
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: received Vendor ID payload [Dead Peer Detection]
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: received Vendor ID payload [RFC 3947] method set to=109
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: enabling possible NAT-traversal with method RFC 3947 (NAT-Traversal)
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: transition from state STATE_MAIN_I1 to state STATE_MAIN_I2
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: STATE_MAIN_I2: sent MI2, expecting MR2
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: I did not send a certificate because I do not have one.
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: NAT-Traversal: Result using RFC 3947 (NAT-Traversal): both are NATed
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: transition from state STATE_MAIN_I2 to state STATE_MAIN_I3
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: STATE_MAIN_I3: sent MI3, expecting Mr4
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: Main mode peer ID is ID_FQDN: '@leftvyatta'
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: transition from state STATE_MAIN_I3 to state STATE_MAIN_I4
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: STATE_MAIN_I4: ISAKMP SA established {auth=OAKLEY_PRESHARED_KEY cipher=aes_128 prf=oakley_sha group=modp1536}
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #1: Dead Peer Detection (RFC 3706): enabled
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #2: initiating Quick Mode PSK+ENCRYPT+TUNNEL+PFS+UP {using isakmp#1}
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #2: Dead Peer Detection (RFC 3706): enabled
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #2: transition from state STATE_QUICK_I1 to state STATE_QUICK_I2
Jul 30 16:12:52 r4 pluto[6855]: "peer-left.carbonwind.net-tunnel-1" #2: STATE_QUICK_I2: sent QI2, IPsec SA established {ESP=>0x5d269320 <0xfe8aafa4 xfrm=AES_128-HMAC_SHA1 NATD=192.168.22.240:4500 DPD=enabled}

sh_r1_ike_sa
sh_r1_ipsec_sa
sh_r1_ipsec_sa_det

 

The first issue after we brought the VPN tunnel up, the IP address in front of right Vyatta will change.
This is not exactly an issue, as right Vyatta is quite not aware of the IP address of the NAT device in front of it.
Let assume this address will change. DPD will kick in, left Vyatta will clear it’s IKE MM and QM SAs, and sit and wait. Right Vyatta will also clear it’s IKE MM and QM SAs and attempt to bring the tunnel up.
So the traffic will be NATed with a different IP address. But left Vyatta does not care about that, it accepts any source IP address.
So, till DPD does its thing, say around one minute, the VPN tunnel will be down, and after this short interval the tunnel will eventually come up. Actually this interval can be shortened, depending on DPD’s configuration.
Around 1 minute is not that bad(and likely the IP address will change once a day or within a few days interval), knowing that even at least one site was not provided with a static IP address. Low cost may have a price.

 

The problem is what happens when the NAT device in front of left Vyatta changes its IP address.
DPD will kick in, left Vyatta will clear it’s IKE MM and QM SAs, and sit and wait, it does not listen on a specific IP address, so the change of IP address in front of it does no affect it.
Right Vyatta will also clear it’s IKE MM and QM SAs and attempt to bring the tunnel up. But when doing that, will it try to resolve left.carbonwind.net and initiate IKE MM to the new IP address(assuming DynDNS was configured correctly) ?
Well, as already said, I did not have DynDNS in my lab, but apparently, right Vyatta will not do that, and will try to initiate the IKE MM to the old IP address(if I issue a ping command to left.carbonwind.net in my lab, right Vyatta pings the correct new IP address), at least without my intervention.

There is a script(janus.pl) in the /contrib directory if you download Openswan that may help, but I haven’t gone that way right now, maybe another time.


So, if the NAT device in front of left Vyatta would have had a static IP address, this scenario would have been possible with some extra touches.

I haven’t tried yet, but you may be able to get this scenario to work using OpenVPN s2s VPN instead of IPsec tunnel mode s2s VPN, without any extra touches outside the CLI.

Comments (12) -

  • Rajeev

    8/6/2009 7:52:37 AM |

    Dear Adrian,

    could you please clarify why we give this rule
    set service nat rule 10 exclude

    thanks
    Rajeev

    • adimcev

      8/6/2009 1:24:31 PM |

      Hi Rajeev,

      That rule was added to exclude the s2s VPN traffic from the NAT process.
      Otherwise traffic from 192.168.10.0/24(local subnet) destined to 192.168.40.0/24(remote subnet) would have been NATed, ad we don't want this to happen.

      Thanks,
      Adrian

      • Rajeev

        8/6/2009 2:33:42 PM |

        Thanks Adrian, I got you.

  • ardian

    2/8/2010 8:06:39 AM |

    hi adrian..
    i've try to make my own ipsec s2s..but error message appears when i commit vpn config

    padlock: VIA Padlock Hash Engine not detected
    padlock: VIA Padlock Hash Engine not detected
    padlock: VIA Padlock not detected

    and when i type  "run show vpn ike sa" command, appears..
    local                        peer                               state                  encrypt               hash               NAT-T     A-Time      L-Time
    -------                      ----------                        -------------       ----------              ------------    --------    ---------      ---------
    @righvyatta         left.carbonwind        down                  n/a                       n/a                 No            0                   0


    hope you could explain and give solutions...

    thanks
    ardian

    • adimcev

      2/8/2010 11:51:56 AM |

      Hi Ardian,

      If you don't have a VIA CPU, then you can ignore that error.
      www.vyatta.org/forum/viewtopic.php?p=4689#4689

      The above configuration was not quite supported with VC5 out-of-the-box, so might be normal to ran into some issues(can't tell what's happening on your side as I don't know what you've configured).

      If both VPN gateways are Vyatta, you may try using OpenVPN instead.

      Thanks,
      Adrian

      • Ardian

        2/8/2010 7:35:45 PM |

        hi Adrian..

        here's my configuration..

        192.168.1.0/24-----[IPSEC0]------X------[IPSEC1]-----192.168.2.0/24

        IPSEC 0:
        ------------
        Interface{
          ethernet eth0{
            address 192.168.12.1/24
            description ISP
          }
          ethernet eth1 {
            address 192.168.1.254/24
            description LAN
          }
          loopback lo {
          }
        }
        protocols {
          static {
            route 0.0.0.0/0 {
              next-hop 192.168.12.2 {
              }
            }
          }
        }
        service {
          nat {
            rule 10 {
              destination {
                address 192.168.2.0/24
              }
              exclude
              outbound-interface eth0
              outside-address {
                address 192.168.12.1
              }
              source {
                address 192.168.1.0/24
              }
              type source
            }
            rule 100 {
              outbound-interface eth0
              outside-address {
                address 192.168.12.1
              }
              source {
                address 192.168.1.0/24
              }
              type source
            }
          }
          ssh {
            allow-root false
            protocol-version 2
          }
        }
        vpn {
          ipsec {
            copy-tos disable
            esp-group ESP1 {
              compression disable
              proposal 1 {
                encryptio aes128
              }
            }
            ike-group IKE1 {
              aggressive-mode disable
              dead-peer-detection {
                action clear
                interval 15
                timeout 45
              }
              proposal 1 {
                dh-group 5
              }
            }
            ipsec-interface {
              interace eth0
            }
            nat-traversal enable
            site-to-site {
              peer @rightvyatta {
                authentication {
                  id @ leftvyatta
                  pre-shared-secret 12345
                }
                ike-groupIKE1
                local-ip 0.0.0.0
                tunnel 1 {
                  allow-nat-networks disable
                  esp-group ESP1
                  local-subnet 192.168.1.0/24
                  remote-subnet 192.168.2.0/24
                }
              }
            }
          }
        }    

        IPSEC 1 :
        -------------
        Interface {
          ethernet eth0{
            address 192.168.15.1/24
            description ISP
          }
          ethernet eth1 {
            address 192.168.2.254/24
            description LAN
          }
          loopback lo {
          }
        }
        protocols {
          static {
            route 0.0.0.0/0 {
              next-hop 192.168.15.2 {
              }
            }
          }
        }
        service {
          nat {
            rule 10 {
              destination {
                address 192.168.1.0/24
              }
              exclude
              outbound-interface eth0
              outside-address {
                address 192.168.15.1
              }
              source {
                address 192.168.2.0/24
              }
              type source
            }
            rule 100 {
              outbound-interface eth0
              outside-address {
                address 192.168.15.1
              }
              source {
                address 192.168.2.0/24
              }
              type source
            }
          }
          ssh {
            allow-root false
            protocol-version 2
          }
        }
        vpn {
          ipsec {
            copy-tos disable
            esp-group ESP1 {
              compression disable
              proposal 1 {
                encryptio aes128
              }
            }
            ike-group IKE1 {
              aggressive-mode disable
              dead-peer-detection {
                action clear
                interval 15
                timeout 45
              }
              proposal 1 {
                dh-group 5
              }
            }
            ipsec-interface {
              interace eth0
            }
            nat-traversal enable
            site-to-site {
              peer @leftvyatta {
                authentication {
                  id @rightvyatta
                  pre-shared-secret 12345
                }
                ike-groupIKE1
                local-ip 0.0.0.0
                tunnel 1 {
                  allow-nat-networks disable
                  esp-group ESP1
                  local-subnet 192.168.2.0/24
                  remote-subnet 192.168.1.0/24
                }
              }
            }
          }
        }    

        if i don't have a hash engine..how data through the tunnel will be encrypted..?
        as long as i know hash engine use for encrypt the data..
        and how to install openvpn on vyatta...??

        i'm sorry if i ask many questions, since i just newbie who want to know more..^_^

        big thanks,
        Ardian

  • adimcev

    2/8/2010 9:26:59 PM |

    On your current config both Vyattas just sit and wait.
    You need to tell to one of them to initiate the tunnel.
    In my blog entry this was done on the right router, under its s2s config, the remote peer address is a DNS name.

    You don't have to install OpenVPN on Vyatta.
    It's installed by default, you can configure it from the CLI.
    Take a look at the VPN documentation available here:
    http://www.vyatta.org/documentation

    The encryption is done in software.

    Thanks,
    Adrian

    • Ardian

      2/9/2010 6:15:08 AM |

      thanks adrian..you really helpful..!!

      • ardian

        2/10/2010 3:40:35 AM |

        hi adrian...

        how do I change the access permission on Vyatta, because when I want to save the /etc /ipsec.conf file, the file is read only...or I should login as root first??

        thanks,
        ardian

        • adimcev

          2/10/2010 12:21:42 PM |

          if you do that over ssh, try using sudo, like 'sudo vi /etc/ipsec.conf' or what file you want to edit. Note that through a reboot or ipsec service restart, the changes won't persist.
          root login over ssh is disabled by default.

          Thanks,
          Adrian

          • ardian

            2/15/2010 7:30:15 AM |

            hi..adrian

            i've changed the ipsec.conf file, but when i type "show vpn ike sa" on the left vyatta..

            state = down
            encrypt = n/a
            hash = n/a
            nat-t = no
            a-time = 0
            L-time = 28800

            does it mean my tunnel didn't work..??

            thanks
            ardian..

  • adimcev

    2/15/2010 6:31:15 PM |

    If the state isn't up, probably. Smile

    As I said before, if the VPN gateways are both Vyattas it would probably be easier to use OpenVPN for the s2s in this case.

    Thanks,
    Adrian

Comments are closed