Friday, August 5, 2011

Configuring IPSEC VPN between Linux and Cisco

In this blogtorial we are going to talk about how to configure a IPSEC VPN between a linux machine (CentOS) and a Cisco router. I  had to do this because we installed a Cisco router at a customer site with a DHCP ip Comcast connection. So in-order to get into the Cisco router to do management I created a ipsec vpn tunnel back to one of my Linux machines. I know I could have done dyndns or something else but it was more fun this way :)

Here is my topology and I will post relevant configuration from the Cisco router and the Linux machine. So let's get started.

First, let's get racoon configured on the Linux machine.

Log/sudo into your linux machine and type vi /etc/racoon/racoon.conf

Below is the full config from my racoon.conf. Copy and replace your racoon.conf and change anywhere you see to your Linux machine's public facing ip and save the file by typing :wq!

path include "/etc/racoon";
path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";
path script "/etc/racoon/scripts";
log debug2;
     #ip address of the linux machine or the ip i need to be listening in on
     isakmp [500]; 
remote anonymous {
        exchange_mode aggressive,main;
        generate_policy on;
        passive on;
        my_identifier address;
        dpd_delay 25;
        dpd_retry 3;
        proposal {
                encryption_algorithm 3des;
                hash_algorithm sha1;
                authentication_method pre_shared_key;
                dh_group 2;

sainfo anonymous
        pfs_group modp1024;
        encryption_algorithm 3des;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate;
        lifetime time 3600 sec;

Now we need to edit the /etc/racoon/psk.txt since we will be using pre-shared key for our IPSEC vpn. However, there are ways to do this 'certificates' also. 

To edit the psk.txt type vi /etc/racoon/psk.txt 

Below is the full config from my psk.txt. is the hostname of the Cisco router and verysecretpassword is the pre-shared key. Edit this file to your needs for example if you want to use some other key replace verysecretpassword with whatever you want. Once you are done modifying type :wq! to save the file.   verysecretpassword

Now start the racoon service by typing service racoon start or service racoon restart or /usr/sbin/racoon

Let's now move on to the Cisco router configurations. Again replace the with the Linux machine's public ip that it's listening in on. 

hostname blabla
ip domain name ** this needs to match what you have in your psk.txt this is why i have in my psk.txt **

crypto isakmp policy 1
 encr 3des
 authentication pre-share
 group 2
 lifetime 3600
crypto isakmp key verysecretpassword address ** change 'verysecretpassword' to match your key in psk.txt and modify to your Linux machines ip that it's listening in on **
crypto isakmp keepalive 25 3 periodic ** dead peer detection read more about this @ cisco's vast knowledge base **
crypto isakmp profile 1
   keyring default
   self-identity fqdn
   match identity host ** modify to your Linux machines ip that it's listening in on **
   keepalive 25 retry 3
   initiate mode aggressive
crypto ipsec transform-set MyTransformSet esp-3des esp-sha-hmac 
crypto map MyMap local-address FastEthernet0/1 ** replace FastEthernet0/1 with your Cisco router public facing interface **
crypto map MyMap isakmp-profile 1
crypto map MyMap 10 ipsec-isakmp 
 set peer ** modify to your Linux machines ip that it's listening in on **
 set transform-set MyTransformSet 
 set pfs group2
 set isakmp-profile 1
 match address 100

Create a loopback interface.

interface Loopback0
 ip address
 no ip route-cache cef
 no ip route-cache
 no ip mroute-cache

Create an access list to match the loopback address since this is what we will be encrypting. 

access-list 100 permit ip host any

Now apply the crypto map to the public facing interface on the Cisco router. For example mine was Fast0/1 which connected to the Comcast modem. 

interface FastEthernet0/1
 ip address dhcp
 ip directed-broadcast
 ip nat outside
 no ip virtual-reassembly
 duplex auto
 speed auto
 crypto map MyMap

I also created a ip sla on the cisco to keep the ipsec connection alive though you can configure dead peer detection in the crypto profile. 

ip sla monitor 10
 type echo protocol ipIcmpEcho source-interface Loopback0
 timeout 2000
 threshold 500
 frequency 25
ip sla monitor schedule 10 life forever start-time now

Here are a few show commands.

blabla#show crypto ipsec sa           

interface: FastEthernet0/1
    Crypto map tag: MyMap, local addr

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

     local crypto endpt.:, remote crypto endpt.:
     path mtu 1500, ip mtu 1500, ip mtu idb FastEthernet0/1
     current outbound spi: 0x5A0E39E(94430110)

     inbound esp sas:
      spi: 0xdfddE529B(3081654939)
        transform: esp-3des esp-sha-hmac ,
        in use settings ={Tunnel, }
        conn id: 2004, flow_id: SW:4, crypto map: MyMap
        sa timing: remaining key lifetime (k/sec): (4418289/2714)
        IV size: 8 bytes
        replay detection support: Y
        Status: ACTIVE

     inbound ah sas:

     inbound pcp sas:

     outbound esp sas:
      spi: 0x5dfE(94430110)
        transform: esp-3des esp-sha-hmac ,
        in use settings ={Tunnel, }
        conn id: 2006, flow_id: SW:6, crypto map: MyMap
        sa timing: remaining key lifetime (k/sec): (4418288/2714)
        IV size: 8 bytes
        replay detection support: Y
        Status: ACTIVE

     outbound ah sas:

     outbound pcp sas:

Now from the Linux machine I can ping (loopback address of the Cisco router). So no matter what random public ip I get from Comcast I can now ssh into the Cisco router using 

[root@tumbler ~]# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:33:33:33:8F:24  
          inet addr:  Bcast:  Mask:
          RX packets:985619514 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1030658389 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:139088230248 (129.5 GiB)  TX bytes:180201760706 (167.8 GiB)
          Interrupt:129 Memory:f8000000-f8012800 

[root@ithitman]# ping
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=255 time=35.1 ms
64 bytes from icmp_seq=2 ttl=255 time=30.6 ms
64 bytes from icmp_seq=3 ttl=255 time=33.4 ms

Few commands from linux to verify connectivity. 

[root@tumbler ~]# setkey -DP[any][any] any
        in prio def ipsec
        created: Aug  5 12:17:36 2011  lastused: Aug  5 12:36:32 2011
        lifetime: 3600(s) validtime: 0(s)
        spid=1456 seq=7 pid=12188
        refcnt=3[any][any] any
        out prio def ipsec
        created: Aug  5 12:17:36 2011  lastused: Aug  5 12:36:32 2011
        lifetime: 3600(s) validtime: 0(s)
        spid=1473 seq=5 pid=12188
        refcnt=5[any][any] any
        fwd prio def ipsec
        created: Aug  5 12:17:36 2011  lastused:                     
        lifetime: 3600(s) validtime: 0(s)
        spid=1466 seq=3 pid=12188

If the vpn does not work try tail -f /var/log/messages or restarting racoon on the Linux machine or pinging the from the cisco router with loopback0 as the source (using extended ping). Make sure iptables on the Linux side is allowing the appropriate traffic. Make sure pre-shared key matches and the domain name of the cisco (hostname + domain name) adds up to what you have in our /etc/racoon/psk.txt

Also post comments and I may be able to help. 

Many more articles to come so stay tuned!! If you like my posts please subscribe!!


  1. Your style is so unique compared to other folks I've read stuff from. Thank you for posting when you have the opportunity, Guess I'll just bookmark this site.

    Also visit my site ... cyberghost vpn

  2. may i know what are the model number of
    comcast router and cisco router ??

  3. The cisco model was a 3640 but I cannot remember the comcast modem.

  4. My SLA syntax on my IOS is slightly different than yours so I skipped over that part.

    Everything looked okay but nothing was happening. Debug gave very little to go on, just the following:

    select crypto engine: ce_engine[2] does not accept the capabilities
    No peer struct to get peer description

    The connection came up only after I generated some 'interesting traffic' by pinging the linux host from the Cisco source ip Of course!

    I went back and sorted out my sla syntax (shown below) and now everything works.

    ip sla 10
    icmp-echo source-ip
    timeout 2000
    threshold 500
    frequency 45
    ip sla schedule 10 life forever start-time now

    Great tutorial. Thanks!

  5. Hi Arwin,

    I done the config as you described, but my pings are working only in one way. If I try to ping from LAN behind Cisco router to the LAN behind Linux, ping works. But, from LAN behind Linux to the LAN behind Cisco it doesn't work.
    Have you any suggestions?