IPsec quick and dirty

By stretch | Monday, July 14, 2008 at 1:08 a.m. UTC

A reader of last week's post Visualizing tunnels asked for an IPsec example, so here's a rundown continuing from the previous setup. Note that the VTI configuration demonstrated here is different from the older crypto map method used as an example in the IPsec cheat sheet.

ipsec_tunnel.png

The tunnel between R1 and R3 is currently running GRE, the default encapsulation:

R1# show int tun0 | include protocol
Tunnel0 is up, line protocol is up
  Tunnel protocol/transport GRE/IP

A ping from one end of the tunnel's 10.0.0.0/30 subnet to the other verifies end-to-end connectivity.

IKE Configuration

Our first task in converting to an IPsec tunnel is specifying an Internet Key Exchange (IKE) policy. IKE relies on ISAKMP to establish an initial secure channel over which the IPsec tunnel can be negotiated. An IKE policy determines the attributes of the ISAKMP session, including the encryption type and hashing methods.

An empty IKE/ISAKMP policy provides default selections for all attributes. The only attribute we need to manually define in this case is the authentication method, which we'll change from the default of RSA signatures to pre-shared keys (more on this in a bit). We can inspect the completed policy with show crypto isakmp policy:

R1(config)# crypto isakmp policy 10
R1(config-isakmp)# authentication pre-share
R1(config-isakmp)# ^Z
R1# sh crypto isakmp policy

Global IKE policy
Protection suite of priority 10
    encryption algorithm:   DES - Data Encryption Standard (56 bit keys).
    hash algorithm:         Secure Hash Standard
    authentication method:  Pre-Shared Key
    Diffie-Hellman group:   #1 (768 bit)
    lifetime:               86400 seconds, no volume limit
...

Our default policy implements DES encryption with SHA-1 hashing and Diffie-Hellman group 1. Don't worry if these terms are foreign to you. There's quite a bit more detail to this whole process, but for now just remember that encryption is used to scramble and unscramble data, whereas hashing uses a small fixed-length checksum (or HMAC) to provide data integrity. The default tunnel lifetime is 86400 seconds (24 hours).

As mentioned, we'll need to define a pre-shared key (versus implementing stronger but more complex public keying). The key is a string of text used to initialize the IKE tunnel, configured identically on both routers. In our example, the string FooB4r is used; in practice, I would obviously suggest a much stronger key. The IP address which follows the key definition specifies the host for which the key should be used.

R1(config)# crypto isakmp key 0 FooB4r address 172.16.0.6

Make sure to reflect this configuration on the opposite end of the tunnel at R3 (use 172.16.0.1 instead of .6). For a full account of IKE policy and authentication configuration, check the official documentation.

IPsec Configuration

Once our IKE policy has been setup we can move on to defining an IPsec transform set. The transform set defines the parameters of the IPsec security associations which will carry the actual data. Note that although we have defined a single tunnel (interface Tunnel0), there will be two unidirectional IPsec security associations, one in either direction.

Unlike defining an IKE policy, which provides a default for all attributes, we must explicitly state the encryption and hash type we want to use with our transform set. Our example will implement ESP encapsulation with 3DES encryption and SHA-1 authentication. Within transform set configuration, we have the option to select tunnel or transport mode; tunnel mode is the default, and suits our scenario. We can inspect our newly created transform set with show crypto ipsec transform-set:

R1(config)# crypto ipsec transform-set MyTransformSet esp-3des esp-sha-hmac
R1(cfg-crypto-trans)# ^Z
R1# show crypto ipsec transform-set
Transform set MyTransformSet: { esp-3des esp-sha-hmac  }
   will negotiate = { Tunnel,  },

For more information on configuring IPsec transform sets, consult the IOS documentation.

Now that we have our IPsec transform set created, we can reference it from an IPsec profile to be applied to a tunnel interface:

R1(config)# crypto ipsec profile MyProfile
R1(ipsec-profile)# set transform-set MyTransformSet
R1(ipsec-profile)# ^Z
R1# show crypto ipsec profile
IPSEC profile MyProfile
    Security association lifetime: 4608000 kilobytes/3600 seconds
    PFS (Y/N): N
    Transform sets={
            MyTransformSet,
    }

This step admittedly seems superfluous; why can't we simply reference the transform set directly? In more real-world scenarios, the IPsec profile can serve as a wrapper which points to multiple transform sets, and grants the ability to set additional options beyond the scope of this article.

Tunnel Configuration

Our last step is to convert the tunnel interfaces on routers 1 and 3 to IPsec operation. First we change the tunnel mode from GRE to IPsec for IPv4, then apply our IPsec profile:

R1(config)# interface tun0
R1(config-if)# tunnel mode ipsec ipv4
R1(config-if)# tunnel protection ipsec profile MyProfile

If all goes well, we should now have an ISAKMP security association and two unidirectional IPsec security associations between the tunnel endpoints:

R1# show crypto isakmp sa
IPv4 Crypto ISAKMP SA
dst             src             state          conn-id slot status
172.16.0.6      172.16.0.1      QM_IDLE           1002    0 ACTIVE
R1# show crypto ipsec sa

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

protected vrf: (none)
   local  ident (addr/mask/prot/port): (0.0.0.0/0.0.0.0/0/0)
   remote ident (addr/mask/prot/port): (0.0.0.0/0.0.0.0/0/0)
   current_peer 172.16.0.6 port 500
 PERMIT, flags={origin_is_acl,}
#pkts encaps: 5, #pkts encrypt: 5, #pkts digest: 5
#pkts decaps: 5, #pkts decrypt: 5, #pkts verify: 5
#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.: 172.16.0.1, remote crypto endpt.: 172.16.0.6
 path mtu 1500, ip mtu 1500, ip mtu idb FastEthernet0/0
 current outbound spi: 0xB1677585(2976347525)

inbound esp sas:
  spi: 0x5351D51E(1397871902)
    transform: esp-3des esp-sha-hmac ,
    in use settings ={Tunnel, }
    conn id: 3, flow_id: SW:3, crypto map: Tunnel0-head-0
    sa timing: remaining key lifetime (k/sec): (4540862/3379)
    IV size: 8 bytes
    replay detection support: Y
    Status: ACTIVE

inbound ah sas:

inbound pcp sas:

outbound esp sas:
  spi: 0xB1677585(2976347525)
    transform: esp-3des esp-sha-hmac ,
    in use settings ={Tunnel, }
    conn id: 4, flow_id: SW:4, crypto map: Tunnel0-head-0
    sa timing: remaining key lifetime (k/sec): (4540862/3378)
    IV size: 8 bytes
    replay detection support: Y
    Status: ACTIVE

outbound ah sas:

outbound pcp sas:

More information on configuring IPsec across Virtual Tunnel Interfaces (VTIs) is available in the IOS documentation.

Traffic flowing through the tunnel is now encapsulated, encrypted, and authenticated with IPsec. For an example of what the encrypted traffic looks like on the wire, check out this packet capture.

Final Configurations

R1

crypto isakmp policy 10
 authentication pre-share
crypto isakmp key FooB4r address 172.16.0.6
!
crypto ipsec transform-set MyTransformSet esp-3des esp-sha-hmac 
!
crypto ipsec profile MyProfile
 set transform-set MyTransformSet 
!
interface Tunnel0
 ip address 10.0.0.1 255.255.255.252
 tunnel source 172.16.0.1
 tunnel destination 172.16.0.6
 tunnel mode ipsec ipv4
 tunnel protection ipsec profile MyProfile
!
interface FastEthernet0/0
 ip address 172.16.0.1 255.255.255.252

R3

crypto isakmp policy 10
 authentication pre-share
crypto isakmp key FooB4r address 172.16.0.1
!
crypto ipsec transform-set MyTransformSet esp-3des esp-sha-hmac 
!
crypto ipsec profile MyProfile
 set transform-set MyTransformSet 
!
interface Tunnel0
 ip address 10.0.0.2 255.255.255.252
 tunnel source 172.16.0.6
 tunnel destination 172.16.0.1
 tunnel mode ipsec ipv4
 tunnel protection ipsec profile MyProfile
!         
interface FastEthernet0/0
 ip address 172.16.0.6 255.255.255.252

About the Author

Jeremy Stretch is a network engineer living in the Raleigh-Durham, North Carolina area. He is known for his blog and cheat sheets here at Packet Life. You can reach him by email or follow him on Twitter.

Posted in Security

Comments


Marko (guest)
July 14, 2008 at 3:23 p.m. UTC

There appears to be a minor error in the part where you apply the transform set to the ipsec profile on R1. It is probably an unfortunate copypasta, since it is not present in the configurations at the end.

Interesting post (and the blog as a whole) though.


stretch
July 14, 2008 at 4:00 p.m. UTC

@Marko: Thanks for the catch! Should be fixed now. I try to catch mistakes like that, but after reading over my own words so many times it all starts to blur together. =)


Paul (guest)
July 14, 2008 at 4:14 p.m. UTC

Many thanks for this example. I only sent the comment on Friday – that is good service! :) One quick question: What firewall rules would be required to permit this access? Permit esp and isakmp? I have also seen "non500-isakmp" within ACLs – how does this fit into the picture? Is it always needed? Is this type of connection stateful unlike GRE? Thanks again.


stretch
July 14, 2008 at 6:06 p.m. UTC

ESP and AH are IP protocols 50 and 51, respectively, and ISAKMP traverses UDP port 500. AFAIK, non500-isakmp is used to match ISAKMP running on a non-default port for NAT traversal. And yes, unlike default GRE (without keepalives), the IPsec tunnel is stateful; a failure anywhere in the network preventing reachability between the two tunnel endpoints will cause the tunnel interfaces to go down.


Nemako (guest)
July 16, 2008 at 12:05 p.m. UTC

Hi stretch and thanks a lot for your very good article. Very useful.

Just a note, in some topology like point-to-point VPN, it could be very interesting to use some "ip unnumbered" address on the int tun 0. You can save a /30 and re-use the address of the physical interface on the tunnel one.


drkfiber (guest)
July 17, 2008 at 11:30 p.m. UTC

One thing we have noticed when rolling out tunnels like this is that you might have to adjust the mss (maximum segment size) in the tunnel, it broke some of our apps. As well as to adjust the mss on the egress interface of the tunnel. (ip tcp adjust-mss 1452) Not sure if this is unique to us, but it improved the performance of our VPN links quite a bit.


Ryan Finneran (guest)
January 19, 2009 at 7:33 a.m. UTC

The reason you must adjust the mss is because you are adding overhead for each protocol. For example, adding GRE to an existing IPSec VPN adds a 24 byte header. IPSec in transport mode adds a 30-53 byte header depending on the encryption and hash being used. Tunnel mode it is 50-73 bytes. So, depending on the path MTU from source to destination, you adjust the mss to ensure when all the headers are put on, the size of the datagram doesn't exceed the PMTU. Typically, you just add the ip tcp adjust-mss 14xx to the ingress interface for user traffic.


julien (guest)
April 23, 2009 at 1:15 p.m. UTC

Hi,
Why is it not necessary to apply an isakmp profile to the ipsec profile with the set isakmp-profile command?
thanks !


luismg
December 2, 2009 at 11:08 p.m. UTC

WOW tunnel gre with ipsec in one page, very nice article, this is what I learn in ISCW book.


Andrey (guest)
October 27, 2011 at 2:52 p.m. UTC

Hi,
I am making a test lab using your example. Found one strange thing - when I try to ping from R1 10.0.0.2 it doesn't work. I can see packets comming on ipsec interface of R3, decrypted, no errors. But nothing coming back like R3 doesn't bother to answer. I am using your exact config, cut & paste to GNS3.

I am using Cisco IOS Software, 7200 Software (C7200-ADVIPSERVICESK9-M), Version 12.2(33)SRD4, RELEASE SOFTWARE (fc2)

Any ideas?


ant (guest)
September 4, 2013 at 2:05 p.m. UTC

Hi,

Great article!!
Can you tell how the key used for encrypting the esp payload (through des - 3des etc) derives from the authentication isakmp key (FooB4r)??

BR
ant


Tushar Barke (guest)
March 20, 2014 at 6:43 p.m. UTC

Very valuable information on site-to-site VPN. Thanks Jeremy for such a wonderful article!


Muhammad Younas (guest)
April 11, 2014 at 10:41 a.m. UTC

Nice article. Thanks.


Yash (guest)
December 15, 2014 at 9:41 p.m. UTC

Hi Jeremy,

Thanks for the post. However, I had a question. What will be the source IP with which you will see the traffic coming through the tunnel? Will the packets have original source IP or will it be the IP of the tunnel end-points?


Karan (guest)
April 27, 2015 at 1:27 p.m. UTC

Hi Jeremy

I have query on how does packet flow in IPSEC configuration. Lets say packet enters routers LAN interface and exits out via WAN.Router is configured with proxy ACL and crypto map on its WAN interface. Just want to know on order of operation on how router determines if packets needs encapsulation or how does packet flow occurs from routers LAN to WAN interface and when does crypto engine kicks in.

Thanks Karan


Suresh (guest)
February 17, 2016 at 7:08 p.m. UTC

Hi,

Is it necessary to add the following line to the tunnel interface? tunnel mode ipsec ipv4

I see that it works without it and seen other tutorials not using this. Please explain.


chriscowboyfann
August 3, 2016 at 7:08 a.m. UTC

to remember the 5 attributes. Think "Hagle" like in negotiations H=Hashing A= Authentication G= Diffie Hellman Group Policy L= Lifetime of Key E=Encryption

Comments have closed for this article due to its age.