Before we begin the actual “tutorial” part of this post, I think we should review what Site-to-Site VPN really is. For those completely unfamiliar with the VPN - or Virtual Private Networks - I recommend reading through my previous article about setting up an OpenVPN server on Linux where I also explain the basics of this technology.

The Techopedia has the following description of “Site-to-Site VPN”:

Site-to-site VPN typically creates a direct, unshared and secure connection between two end points. Site-to-site VPN can be intranet based or extranet based. Intranet-based site-to-site VPN is created between an organization’s propriety networks, while extranet-based site-to-site VPN is used for connecting with external partner networks or an intranet.The connection in a site-to-site VPN is generally enabled through a VPN gateway device.

This connection, just as the regular VPN, has to be secure and encrypted on both ends. Here’s a brief explanation of how this works in theory (credits: Palo Alto Networks):

The IP Security (IPSec) set of protocols is used to set up a secure tunnel for the VPN traffic, and the information in the TCP/IP packet is secured (and encrypted if the tunnel type is ESP). The IP packet (header and payload) is embedded in another IP payload, and a new header is applied and then sent through the IPSec tunnel. The source IP address in the new header is that of the local VPN peer and the destination IP address is that of the VPN peer on the far end of the tunnel. When the packet reaches the remote VPN peer (the firewall at the far end of the tunnel), the outer header is removed and the original packet is sent to its destination.

The Two Sites

Here’s the setup:

In this example, we are going to be linking together to sites: Network-A and Network-B. Both sites are connected to the Internet through their IOS routers; both have “some” servers and “some” hosts represented by Host-A/B and Server-A/B on the diagram below:

Here’s a brief overview of the network configuration in place:

Network-A Network-B
Router (LAN) 172.18.0.1 10.0.0.1
Router (WAN) 1.1.1.1 2.2.2.2
Host Computer 172.18.0.100 10.0.0.100
Server 172.18.0.10 10.0.0.10
Subnet 172.18.0.0/24 10.0.0.0/24

Ok, having all that written down we can move on to the VPN configuration itself.

Setting up the routers

Let’s begin by logging into our router through SSH or terminal:

router-a>enable
router-a#configure terminal
router-a(config)#

ISAKMP (Phase 1)

First step is to configure an ISAKMP Phase 1 policy. ISAKMP is the protocol that specifies the mechanics of the key exchange used by IKE, which in turn establishes the shared security policy and authenticated keys.

IKE exists only to establish SAs (Security Association) for IPsec. Before it can do this, IKE must negotiate an SA (an ISAKMP SA) relationship with the peer.

router-a(config)#  crypto isakmp policy 1
router-a(config-isakmp)# encr 3des
router-a(config-isakmp)# hash md5
router-a(config-isakmp)# authentication pre-share
router-a(config-isakmp)# group 2
router-a(config-isakmp)# lifetime 86400

The above commands define the following (in listed order):- 3DES - The encryption method to be used for Phase 1;- MD5 - The hashing algorithm;- Pre-share - Use Pre-shared key as the authentication method;- Group 2 - Diffie-Hellman group to be used;- 86400 – Session key lifetime (in seconds).

Next, we are going to define a pre-shared key for authentication with our peer (router-b). This is a “password” which the routers are going to use to “recognize” each other. We can set up that key to “sshguru” by running the following command:

router-a(config)# crypto isakmp key sshguru address 2.2.2.2

Please note we’ve used 2.2.2.2 as the address here as we’re already specifying what should be the public address of the peer. This is to further secure this key from getting leaked or spoofed.

From now on, every time router-a attempts to establish a VPN tunnel with router-b (or 2.2.2.2), this pre-shared key will be used.

IPsec (Phase 2)

To configure IPSec (phase 2), we need to setup the following in order:- an extended ACL- IPSec transform set- Crypto Map

Setting up an extended Access Control List (ACL)

An ACL controls the traffic allowed to pass through a given interface. In this example, we will allow all traffic going from 172.18.0.0 network (network-a) to 10.0.0.0 network (network-b) through the VPN tunnel.

router-a(config)# ip access-list extended VPN-ACL
router-a(config-ext-nacl)# permit ip 172.18.0.0 0.0.0.255 10.0.0.0 0.0.0.255

Let’s break down the above commands:- the first one created an extended ACL called “VPN-ACL”- the second one added a rule to the “VPN-ACL”, which allows all traffic from network-a to reach network-b; note: the 0.0.0.255 bit is a wildcard mask

Creating the IPsec Tranform Set

A transform set is a combination of individual IPSec transforms (hashing, encryption etc.) designed to enact a specific security policy for traffic. We need to set it up so the VPN traffic won’t be readable during a man-in-the-middle attack.

router-a(config)# crypto ipsec transform-set TSet esp-3des esp-md5-hmac

As you can see, in this example we’re setting up the transform set TSet and configure it to include ESP-3DES encryption and MD5 hashing algorithms.

Defining a Crypto Map

The crypto map is basically a rule which tells the router which transform set (TSet) and which ACL (VPN-ACL) to use while connecting with a defined peer (router-b under an IP 2.2.2.2). We can set such rule by issuing:

router-a(config)# crypto map Crypt 10 ipsec-isakmp
router-a(config-crypto-map)# set peer 2.2.2.2
router-a(config-crypto-map)# set transform-set TSet
router-a(config-crypto-map)# match address VPN-ACL

Once we’ve done this, we can apply a the crypto map (Crypt in this case) to the outgoing interface on the router:

router-a(config)# interface FastEthernet0/1
router-a(config- if)# crypto map Crypt

Please note there can be only a single crypto map applied to an interface. If you plan to have a multi-site VPN setup or independent site-to-site VPN tunnels, ensure you have enough outgoing interfaces or design your network with virtual tunnel interfaces (VTIs) in mind.

The other end of the tunnel

At this point your VPN tunnel is ready for use (more or less). Nearly the same configuration has to be applied on the other end of the tunnel (router-b) with only a couple of changes:

  • phase 1 configuration
router-b(config)# crypto isakmp key sshguru address 1.1.1.1
  • ACL rule
router-b(config)# ip access-list extended VPN-ACL
router-b(config-ext-nacl)# permit ip 10.0.0.0 0.0.0.255 172.18.0.0 0.0.0.255
  • crypto map definition:
router-a(config)# crypto map Crypt 10 ipsec-isakmp
router-a(config-crypto-map)# set peer 1.1.1.1
router-a(config-crypto-map)# set transform-set TSet
router-a(config-crypto-map)# match address VPN-ACL

(not) NATting

Network Address Translation (NAT) is probably enabled in your network so the hosts can reach the Internet. When configuring a Site-to-Site VPN tunnel, it is critical to configure the router not to perform NAT (deny NAT) on packets destined to the remote VPN network.

The below is an example set of commands which you can use. Please do keep in mind however that NAT configuration in your network(s) might be much more complicated than that and might require some additional tweaking:

network-a

router-a(config)# ip nat inside source list 100 interface fastethernet0/1 overload
router-a(config)# access-list 100 deny ip 172.18.0.0 0.0.0.255 10.0.0.0 0.0.0.255
router-a(config)# access-list 100 permit ip 172.18.0.0 0.0.0.255 any

network-b

router-b(config)# ip nat inside source list 100 interface fastethernet0/1 overload
router-b(config)# access-list 100 deny ip 172.18.0.0 0.0.0.255 10.0.0.0 0.0.0.255
router-b(config)# access-list 100 permit ip 172.18.0.0 0.0.0.255 any

Activating the tunnel

Ok, as we have everything ready now, it is time to finally open up the tunnel. This has to be done from a router (not from a host or server) and really is just a ping from one site to the other. Afterwards the VPN tunnel will be available for all the hosts in both networks.

router-a# ping 10.0.0.1 source 172.18.0.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.0.1, timeout is 2 seconds:
Packet sent with a source address of 172.18.0.1
.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 44/47/48 ms

First few packets will always get dropped as it takes a couple of second for the tunnel to authenticate & initialize.

For the lazy admins…

As I know how painfully tedious copying the commands from blog posts is, I’m including here a complete copy&paste config which you only need to adjust slightly (IP addresses) before use. You might also want to change the NAT rules at the very end or remove them completely if they’d not fit into your NAT configuration. Feel free to copy, edit and apply it to routers in your lab(s) or network(s).

Copy&Paste Configuration (network-a)

en
conf term
crypto isakmp policy 1
encr 3des
hash md5
authentication pre-share
group 2
lifetime 86400
exit
crypto isakmp key sshguru address 2.2.2.2
ip access-list extended VPN-ACL
permit ip 172.18.0.0 0.0.0.255 10.0.0.0 0.0.0.255
exit
crypto ipsec transform-set TSet esp-3des esp-md5-hmac
crypto map Crypt 10 ipsec-isakmp
set peer 2.2.2.2
set transform-set TSet
match address VPN-ACL
exit
interface FastEthernet0/1
crypto map Crypt
exit
ip nat inside source list 100 interface FastEthernet0/1 overload
access-list 100 deny ip 172.12.0.0 0.0.0.255 10.0.0.0 0.0.0.255
access-list 100 permit ip 172.12.0.0 0.0.0.255 any

Copy&Paste Configuration (network-b)

en
conf term
crypto isakmp policy 1
encr 3des
hash md5
authentication pre-share
group 2
lifetime 86400
exit
crypto isakmp key sshguru address 1.1.1.1
ip access-list extended VPN-ACL
permit ip 10.0.0.0 0.0.0.255 172.18.0.0 0.0.0.255
exit
crypto ipsec transform-set TSet esp-3des esp-md5-hmac
crypto map Crypt 10 ipsec-isakmp
set peer 1.1.1.1
set transform-set TSet
match address VPN-ACL
exit
interface FastEthernet0/1
crypto map Crypt
exit
ip nat inside source list 100 interface FastEthernet0/1 overload
access-list 100 deny ip 10.0.0.0 0.0.0.255 172.18.0.0 0.0.0.255
access-list 100 permit ip 10.10.0.0 0.0.0.255 any