DMVPN setup with PSK (GNS3 Lab)

DMVPN setup with PSK (GNS3 Lab)

Dynamic Multipoint VPNs (DMVPN) offer a low admin overhead and scalable VPN solution. It is also efficient at routing traffic as it can dynamically reconfigure itself from a hub and spoke to a partial or full mesh topology! This means that not all traffic has to pass through the hub device and we can prove/test this in our lab. There is a similar lab [here] for a cert based setup but CCIEv5 is specifically looking at PSK (PSK being slightly more straight forward).

Two protocols that enable DMVPN deployments are Multipoint Generic Routing Encapsulation (mGRE) rfc2735 / rfc1701and Next Hop Resolution Protocol (NHRP) rfc2735. There is also a very good post on Packetlife about DMVPN.

The following if a GNS3 lab is relatively long compared to the other labs I have done and has quite a few steps so I have tried to arrange them in a logical order thats hopefully easy to follow with basic DMVPN setup on this page then adding encryption on the 2nd page. As always any feedback is welcome.

We will use the basic topology above and the initial GNS3 net file can be found [here]. It includes all the basic config and addressing done. There is full connectivity between the physical interfaces. I made this lab using 3600 running Version 12.4(25a) IOS.

Hub config

Step Description
1 ISAKMP Policy
2 Transform Set / IPSEC Profile
3 mGRE interface
4 NHRP Server
5 Addressing / MTU

We will start with the Hub configuration. The first two steps a pretty much the same for any IPSEC VPN setup. Steps 3 & 4 are where we make it a DMVPN :)

ISAKMP Policy

Just like a normal point to point VPN we need to configure phase one encrption parameters that need to match or be avilable on all devices in our DMVPN. In this example we configure AES 256, DH group 5, SHA-1 for hashing and define a preshared key for authentication rather than certs. Important to note the difference here is that for the key we need to define a host/mask of 0.0.0.0 since we might have lots of distinct sources connecting to our DMVPN.

HUB(config)#crypto isakmp policy 10
HUB(config-isakmp)#encryption aes 256
HUB(config-isakmp)#group 5
HUB(config-isakmp)#hash sha
HUB(config-isakmp)#authentication pre-share
HUB(config)#exit
HUB(config)#crypto isakmp key 0 MYDMVPN address 0.0.0.0 0.0.0.0

Transform Set / IPSEC profile

Now we configure our own custom transform set and get it to use tunnel mode. There are default transform sets so this step can be optional. Then we apply the transform set to the IPSEC protection profile we create also applying this to protect traffic traversing tun0. Again this config is common (and needs to match!) on all Hubs and spokes we configure here:

HUB(config)#crypto ipsec transform-set AES_128-SHA esp-aes 128 ah-sha-hmac
HUB(cfg-crypto-trans)#exit
HUB(config)#crypto ipsec profile IPsecProfile
HUB(ipsec-profile)#set transform-set AES_128-SHA
HUB(config)#int tun 0
HUB(config-if)#tunnel protection ipsec profile IPsecProfile

mGRE interface

Now we configure our tunnel interface then ask it to be a mGRE interface. It is possible to have multiple DMVPN networks running in parallel i.e a second DMVPN for failover. The "key" is used to distinguish between these. The tunnel source interface is the physical interface which the mGRE tunnel is bound to.

HUB(config)#int tunnel 0
HUB(config-if)#tunnel mode gre multipoint
HUB(config-if)#tunnel key 1
HUB(config-if)#tunnel source eth 0/0

NHRP Server

NHRP is configured on the tunnel interface. Again it is possible to have multiple NHRP networks so a network-id is used to differentiate them and we add an authentication password (max of 8 characters).

HUB(config)#int tun 0
HUB(config-if)#ip nhrp network-id 1
HUB(config-if)#ip nhrp authentication IMAPASSWORD
% Authentication string exceeds 8 character maximum
HUB(config-if)#ip nhrp authentication IMAPASS
HUB(config-if)#ip nhrp map multicast dynamic

Addressing / MTU

Now we simply configure the IP of the mGRE interface. Its important to note that all tunnel interfaces across the DMVPN must be in the same subnet! This is so all next hops appear as directly connected to the tunnel interfaces. In our case we'll use 172.16.16.0/24 so it can be easily differentiated then a quick review of all the config we have under the tunnel interface since that us completed the HUB config :)

HUB(config)#int tun 0
HUB(config-if)#ip add 172.16.16.1 255.255.255.0
HUB(config-if)#ip mtu 1450
HUB(config-if)#ip tcp adjust-mss 1410
HUB(config-if)#
HUB(config-if)#do show run int tun 0
Building configuration...

Current configuration : 271 bytes
!
interface Tunnel0
ip address 172.16.16.1 255.255.255.0
no ip redirects
ip mtu 1450
ip nhrp authentication IMAPASS
ip nhrp map multicast dynamic
ip nhrp network-id 1
ip tcp adjust-mss 1410
tunnel source Ethernet0/0
tunnel mode gre multipoint
tunnel key 1
tunnel protection ipsec profile IPsecProfile
end

Thats the config done for the HUB :)

Spoke Config

The configuration of the spokes is very similar so I'll just copy the similar config below. You can use either mGRE or GRE tunnels on the spokes. mGRE gives the option to dynamically build meshed topologies bypassing the HUB for spoke to spoke on the fly (almost the best thing about DMVPN? :))which is what we will configure.

ISAKMP / Transform set / IPSEC profile

Exactly the same as the Hub:

crypto isakmp policy 10
encr aes 256
authentication pre-share
group 5
crypto isakmp key MYDMVPN address 0.0.0.0 0.0.0.0
!
crypto ipsec transform-set AES_128-SHA ah-sha-hmac esp-aes
!
crypto ipsec profile IPsecProfile
set transform-set AES_128-SHA

mGRE interface

Again pretty much the same as the configuration of the Hub router. Enable multipoint GRE make the key the same and add the physical interface as the source. Also adding the previously configured IPSEC protection profile. This config is quite standard only the IP is different I used .2 for left and .3 for right

interface Tunnel0
ip address 172.16.16.3 255.255.255.0
no ip redirects
ip mtu 1450
ip nhrp authentication IMAPASS
ip nhrp network-id 1
ip tcp adjust-mss 1410
tunnel source Ethernet0/0
tunnel mode gre multipoint
tunnel key 1
tunnel protection ipsec profile IPsecProfile

NHRP Client

Now the NHRP config is a little different on the spokes than the Hub. Make the network-id match as well as the authentication. For NHRP clients we must configure the location of the NHRP server so we can resolve next hop IPs (nhs command and IP of Tun0 on HUB). In this case its the IP of the Hub routers eth0/0 interface for the map commands too.This config is the same for all spokes.

int tun 0
ip nhrp nhs 172.16.16.1
ip nhrp map multicast 192.168.1.1
ip nhrp map 172.16.16.1 192.168.1.1

Now you should have an ISAKMP and IPSEC SA's built and stable between both spokes and the HUB.

Spoke_Right#show crypto isakmp sa
dst         src         state conn-id slot  status
192.168.1.1 192.168.3.1 QM_IDLE 1       0   ACTIVE


Spoke_Right#
Spoke_Right#show crypto ipsec sa

interface: Tunnel0
Crypto map tag: Tunnel0-head-0, local addr 192.168.3.1

protected vrf: (none)
local  ident (addr/mask/prot/port): (192.168.3.1/255.255.255.255/47/0)
remote ident (addr/mask/prot/port): (192.168.1.1/255.255.255.255/47/0)
current_peer 192.168.1.1 port 500
PERMIT, flags={origin_is_acl,}
#pkts encaps: 2, #pkts encrypt: 2, #pkts digest: 2
#pkts decaps: 1, #pkts decrypt: 1, #pkts verify: 1
#pkts compressed: 0, #pkts decompressed: 0
#pkts not compressed: 0, #pkts compr. failed: 0
#pkts not decompressed: 0, #pkts decompress failed: 0
#send errors 0, #recv errors 0

local crypto endpt.: 192.168.3.1, remote crypto endpt.: 192.168.1.1
path mtu 1500, ip mtu 1500, ip mtu idb Ethernet0/0
current outbound spi: 0xDFCB88B8(3754657976)

inbound esp sas:
spi: 0x29A8A942(698919234)
transform: esp-aes ,
in use settings ={Tunnel, }
conn id: 2001, flow_id: SW:1, crypto map: Tunnel0-head-0
sa timing: remaining key lifetime (k/sec): (4413228/3538)
IV size: 16 bytes
replay detection support: Y
Status: ACTIVE

inbound ah sas:
spi: 0xD1CA2E5A(3519688282)
transform: ah-sha-hmac ,
in use settings ={Tunnel, }
conn id: 2001, flow_id: SW:1, crypto map: Tunnel0-head-0
sa timing: remaining key lifetime (k/sec): (4413228/3536)
replay detection support: Y
Status: ACTIVE

inbound pcp sas:

outbound esp sas:
spi: 0xDFCB88B8(3754657976)
transform: esp-aes ,
in use settings ={Tunnel, }
conn id: 2002, flow_id: SW:2, crypto map: Tunnel0-head-0
sa timing: remaining key lifetime (k/sec): (4413228/3536)
IV size: 16 bytes
replay detection support: Y
Status: ACTIVE

outbound ah sas:
spi: 0x2EA812D3(782766803)
transform: ah-sha-hmac ,
in use settings ={Tunnel, }
conn id: 2002, flow_id: SW:2, crypto map: Tunnel0-head-0
sa timing: remaining key lifetime (k/sec): (4413228/3535)
replay detection support: Y
Status: ACTIVE

outbound pcp sas:

Routing / Dynamic Mesh

Now we have a stable hub and spoke topology its time to add some routing :) Just some short notes on using either EIGRP or OSPF :) Although DMVPN can pass multicast traffic there is an initial problem of spokes not being able to exchange routing info directly with other spokes even though logically they are on the same subnet.

EIGRP

EIGRP uses the multicast address of 224.0.0.10 to send its updates but if all updates are initially sent to the HUB router the next hop would always be the HUB. To avoid this we can use the no ip next-hop-self eigrp interface command on the HUB. This we mean that forwarded EIGRP updates contain the original spoke IP and will allow for spoke to spoke communication! The following will configure EIGRP on the topology and allow for dynamic mesh formations. We also need to turn auto split horizon loop prevention since we may want to advertise routes learned from Tun0 back out via Tun0 (this is specific to a HUB!)

HUB(config-router)#network 10.10.10.0 0.0.0.255
HUB(config-router)#network 172.16.16.0 0.0.0.255
HUB(config-router)#no auto-summary
HUB(config-router)#exit
HUB(config)#int tun 0
HUB(config-if)#no ip next-hop-self eigrp 1
HUB(config-if)#no ip split-horizon eigrp 1

The configuration on the spoke routers is just a basic EIGRP config eg Left:

Spoke_Left(config-router)#network 10.10.200.0 0.0.0.255
Spoke_Left(config-router)#network 172.16.16.0 0.0.0.255
*Mar  1 01:22:26.455: %DUAL-5-NBRCHANGE: IP-EIGRP(0) 1: Neighbor 172.16.16.1 (Tunnel0) is up: new adjacency
Spoke_Left(config-router)#no auto-summary

Config for Right is basically just the same.

Now we can see from the routing table on Left it has the correct next hop (logical tunnel interfaces) for the 10.x.x.x subnets! :)

Gateway of last resort is 192.168.2.2 to network 0.0.0.0

     172.16.0.0/24 is subnetted, 1 subnets
C       172.16.16.0 is directly connected, Tunnel0
     10.0.0.0/24 is subnetted, 3 subnets
D       10.10.10.0 [90/297372416] via 172.16.16.1, 00:03:43, Tunnel0
D       10.10.100.0 [90/310172416] via 172.16.16.3, 00:00:18, Tunnel0
C       10.10.200.0 is directly connected, Loopback0
C    192.168.2.0/24 is directly connected, Ethernet0/0
S*   0.0.0.0/0 [1/0] via 192.168.2.2

But if we check the SA's there is still only a single connection to the HUB rather than a connection to another spoke (you can check with wireshark on the link between ISP3 and ISP2!)

dst             src             state          conn-id slot status
192.168.1.1     192.168.2.1     QM_IDLE              1    0 ACTIVE

Try an extended ping from Letf's loopback to Rights's loopback then see what happens :) Below we can see the spoke to spoke tunnel dynamically created! Its important to note that previous to this traffic is still passed via the HUB while the spoke to spoke tunnel is brought up (again watch this in wireshark on the link between ISP2/3)

Spoke_Left#
Spoke_Left#ping
Protocol [ip]:
Target IP address: 10.10.100.1
Repeat count [5]: 30
Datagram size [100]:
Timeout in seconds [2]:
Extended commands [n]: y
Source address or interface: 10.10.200.1
Type of service [0]:
Set DF bit in IP header? [no]:
Validate reply data? [no]:
Data pattern [0xABCD]:
Loose, Strict, Record, Timestamp, Verbose[none]:
Sweep range of sizes [n]:
Type escape sequence to abort.
Sending 30, 100-byte ICMP Echos to 10.10.100.1, timeout is 2 seconds:
Packet sent with a source address of 10.10.200.1
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Success rate is 100 percent (30/30), round-trip min/avg/max = 64/124/416 ms
Spoke_Left#
Spoke_Left#show crypto isakmp sa
dst             src             state          conn-id slot status
192.168.3.1     192.168.2.1     QM_IDLE              3    0 ACTIVE
192.168.1.1     192.168.2.1     QM_IDLE              1    0 ACTIVE
192.168.2.1     192.168.3.1     QM_IDLE              2    0 ACTIVE

OSPF

Not covering this is much detail in this lab but OSPF uses the destination address of 224.0.0.5 and is a little bit different in its implementation that EIGRP. OSPF has the concept of Designated Routers (DR) on multiaccess segments. Basically its just needs to set the HUB with a higher DR priority and the spokes are set with 0 meaning they can never become the DR. You can try the OSPF section of this lab to try OSPF [here].

Result

We now have a full mesh that was created dynamically and the traffic between site Left and site Right could be significantly more optimal than tromboning through the HUB!! Also you can see my the standard config of spokes these can be deployed very easily and without ANY addtional config now needing added to the HUB itself.

You can also use wireshark to confirm all traffic has been encrypted and is secure :)

Any feedback/questions on the lab are very welcome

m00nie :D