Recently the bellow scenario was bought to my attention:
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}
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.