This is the first out of a series of 3 posts I’m about to make. These posts will cover setting up an Site-2-Site IPSec VPN tunnel, GRE tunneling and iBGP. This post will cover setting up an Site-2-Site IPSec VPN tunnel between a Cisco 2600 Series router and a Debian box running ipsec-tools and racoon.
As I’ve mentioned before I’ve wanted to create a VPN setup between my home and my VPS’es. Not because it’s necessary but just because it’s possible and I learn something from it.
A couple of weeks ago I finally started this project, reading documentation and try to get it working. I started off creating a suitable test-setup here at my house. I booted one of my Cisco 2651XM’s with a IOS 12.4 image and gave it a clean configuration. 1 ethernet port connected to my home-network so I had a way in and the other connected to a dedicated server which I provided with a fresh Debian install just for this exercise.
With this test-setup I had clean configs, no software or other things that might interrupt this exercise and if I somehow created a big mess it wouldn’t interfere with my production setup.
So with all things ready it’s time to start configuring everything. Before I start pasting and explaining my configs let me remind you of one thing. Everything i did is a way of doing it. It’s not the right way, it’s not the wrong way, it’s just the way I did it and there are numerous other ways of accomplishing the same result.
There are a couple of ways setting up an IPSec tunnel. You can use pre-shared-keys or PSK in short. Or you can use certificates. I used pre-shared-keys so I won’t go into using certificates as I’m sure there are plenty of websites covering that subject.
The other thing that’s useful to know, which is also a great help when you’re debugging IPSec, is that when setting up a IPSec tunnel it performs several steps creating the tunnel. Before your tunnel is up and running it performs a couple of checks and negotiations and when both sides agree your tunnel will come up. These steps for creating the tunnel are IKE phase 1 and IKE phase 2. IKE is short for Internet Key Exchange.
During phase 1 it will compare the policies on both sides checking if they agree on encryption, hash-algorithm, etc. and it will check if the PSK matches on both sides. If both sides have identical policies and PSK’s then they will proceed into the next step, IKE phase 2. If for some reason things don’t match up on both ends it will end in phase 1 and you’re probably need to debug to see what’s going wrong.
Next up is IKE phase 2. When phase 1 is successfully completed, phase 2 is started. Phase 2 negotiates the IPSec security associations and generates the required key material for IPSec. You can specify one or more transform-sets but they have to match on both sides for IPSec to work. If phase 2 is also completed without errors your tunnel will be operational and you can securely transfer data from and to both hosts in this setup.
Next I will show the necessary configuration for the cisco router as well as the configuration for the linux machine. I will try to explain these configurations as much as possible so you can understand which part is for which IKE phase and why it’s necessary.
The Cisco Side
I’ll start off with the Configuration for the cisco router, I assume you know how to configure a cisco router yourself because I will not be including those parts of the configuration. Only the necessary parts are shown.
Also i’ve used 3DES encryption for the sake of example, 3DES is not the most secure encryption around, you should use SHA256 of SHA512 instead:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| crypto isakmp policy 1
encr 3des
authentication pre-share
group 2
lifetime 3600
crypto isakmp key YOURKEY address 10.20.30.42 no-xauth
!
!
crypto ipsec transform-set hostb-transform esp-3des esp-sha-hmac
mode transport
!
crypto map hostb-cryptomap 1 ipsec-isakmp
set peer 10.20.30.42
set transform-set hostb-transform
set pfs group2
match address hostb-list
!
interface FastEthernet0/1
ip address 10.20.30.40 255.255.255.0
duplex auto
speed auto
crypto map hostb-cryptomap
!
ip access-list extended hostb-list
permit ip host 10.20.30.40 host 10.20.30.42
! |
I’ll walk through this configuration step by step explaining every part.
First up is our isakmp policy which you’ll find on lines 1 through 5. These lines specify your policy used in the IKE phase 1 part which I’ve mentioned above. Since it’s logical to assume you might want to create more IPSec tunnels than just 1 you can create more policies than 1. Because not all remote ends might use the same policy. I’ve created this isakmp policy with priority 1 which is the highest priority. The bigger the number, the lower the priority.
Within this policy we specify a couple of things. First of all on line 2 we say we want to use 3des encryption in our communications with the remote host. On line 3 we specify we want to authenticate using a pre-shared-key. On line 4 we say we want to use diffie-hellman group 2 which is a way of exchanging the PSK securely over an insecure medium and group 2 says it will be using 1024-bit encryption. On line 5 we specify a lifetime of 1 hour.
Line 6 specifies the pre-shared-key for the specified remote host in this case 10.20.30.42 be sure to replace YOURKEY with your own and more secure pre-shared-key. A way of generating a secure key is executing the following command on a *nix machine which will create a 32 character hex-string:
dd if=/dev/random bs=1 count=32 2>/dev/null | xxd -ps
Line 9 and 10 are specifying IKE phase 2. Line 9 creates an IPSec transform-set called hostb-transform (this can be any string you like) and i chose to use esp-3des and esp-sha-hmac for this transform-set. Line 10 is an important one, you can setup an IPSec tunnel in 2 modes: tunnel-mode or transport-mode. In transport mode only the payload is encrypted, in tunnel-mode the ip-header will also be encrypted. At first I didn’t specify any here. It took me a day figuring out why my IPSec tunnel wouldn’t work.
Next up are lines 12 – 16 defining the crypto map. A crypto map is needed for several reasons. Amongst others it’s used to specify which traffic should be protected by IPSec, which transform sets are to be used with the protected traffic and defining the peers. One could say the crypto map is the glue between different aspects of setting up an IPSec link.
First on line 12 we define the crypto map itself with in my case the name “hostb-cryptomap” a sequence number of 1 and we specify it should be an IPSec with ISAKMP crypto. You could also use IPSec with manual keying but that’s outside the scope of this post.
On line 13 we define our peer, which in my case is the Debian box with ip 10.20.30.42.
On line 14 we tell the crypto map to use the transform set we created on lines 9 and 10.
Line 15 could probably be left out but it never hurts to specify it once more. It tells it still wants to use a 1024 bit Diffie-Hellman encryption only this time it applies to phase 2 instead of phase 1. You could use Diffie-Hellman group 2 in phase 1 and group 5 in phase 2 if you deem it’s necessary. For now we keep things simple and use group 2 in both phases.
Line 16 is the last line in our crypto map definition and specifies the access list it should use to determine which traffic should be encrypted using IPSec. I’ll explain the ACL in a couple of moments.
The next block in the configuration is binding the crypto map to a network interface. In my case this is FastEthernet0/1. Everything is straight forward in this setup the only thing you should add to your network interface is what I’ve specified on line 22. Line 22 binds the crypto map we’ve just created to this interface and when traffic from and to our defined peer passes through it knows it should be encrypted. If you forget this part your IPSec tunnel won’t establish.
And the last step on the Cisco side of this setup is the ACL which is specified on lines 24 and 25. On line 24 you create an extended access-list with the name “hostb-list” which we’ve said we want to use in the crypto map. And on line 25 we define we want to allow traffic from the Cisco (10.20.30.40) towards the Debian box (10.20.30.42) and because this ACL is connected to the crypto map the traffic is encrypted using IPSec.
This concludes the Cisco side of this setup and now we’re going to setup ipsec-tools and racoon on the Debian box so the 2 machines can connect and setup IPSec.
The Linux Side
I also assume you know your way around a linux machine and how to install and configure one. For IPSec to work you need to install racoon and ipsec-tools and of course you need network connectivity. But that speaks for itself doesn’t it?
Note: I’ve used Debian as Linux OS of choice and the paths to config files I name might be different on your OS.
There are 3 files we are going to edit on this machine to setup our IPSec tunnel.
/etc/ipsec-tools.conf
1 2 3 4 5 6 7 8 9 10
| #!/usr/sbin/setkey -f
flush;
spdflush;
spdadd 10.20.30.42 10.20.30.40 any -P out ipsec
esp/transport//require;
spdadd 10.20.30.40 10.20.30.42 any -P in ipsec
esp/transport//require; |
I’ve stripped te file from comments so it’s a bit smaller to paste here and explain what it does. This file gets parsed by the program setkey which is in charge of the Security Associations and Security Policies.
The first line in this config is to specify which interpreter is used to parse the file and as I’ve said setkey is being used for this.
Lines 3 and 4 respectively flush the Security Association Database and the Security Policy Database (SAD and SPD in short). This is to make sure when you change things in this file and setkey parses this file again the possible existing SA’s and SP’s will be flushed.
The next lines 6,7 and 9,10 roughly do the same thing as the crypto map and the ACL on the Cisco side are doing. On line 6 you’re adding an entry into the SPD telling that any traffic originating from 10.20.30.42 (the debian box) towards 10.20.30.40 (the cisco) should be encrypted by IPSec. Line 7 requires it should be using the ESP protocol, that it’s an IPSec link which operates in transport mode (in tunnel-mode you should specify tunnel instead of transport). The space between the next 2 slashes is omitted because it’s not necessary in transport mode. In tunnel mode you should specify the source and destination as x.x.x.x-y.y.y.y. And with require you require the IPSec tunnel to be up before traffic is allowed towards the destination host.
Lines 9 and 10 do the same thing as lines 6 and 7 only this time for traffic originating from 10.20.30.40 (the cisco) towards 10.20.30.42 (the debian box).
/etc/racoon/racoon.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";
remote 10.20.30.40 {
exchange_mode main;
lifetime time 1 hour;
proposal {
encryption_algorithm 3des;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group 2;
}
}
sainfo anonymous
{
pfs_group 2;
lifetime time 1 hour;
encryption_algorithm 3des;
authentication_algorithm hmac_sha1;
compression_algorithm deflate;
} |
Now that we’ve created our security policies specifying what traffic should be encrypted, it’s time to create the config for racoon, the daemon which actually provides the IPSec link.
Above you see the contents from racoon.conf which has also been stripped of it’s comments. The first 2 lines are basic setup for racoon. As with cisco, when using PSK authentication, the PSK needs to be stored somewhere. On line 1 one can specify in which file the PSK’s are stored. In this case: /etc/racoon/psk.txt we’ll get to this file later on.
If you would be using certificate based authentication, which we aren’t in this example, you need to specify the path were certificates are being stored. This is what line 2 does.
Next up is the IKE phase 1 configuration like we did on the cisco. Starting on line 4 where we specify the ip-address of the remote host which in this case is 10.20.30.40 (the cisco).
Line 5 sets the exchange_mode which is used when starting the buildup of an IPSec tunnel. Usually main or aggressive is used. When using main mode like in this example there are 3 two-way exchanges between the initiator and receiver to establish, verify and secure communications. With aggressive mode there are fewer exchanges and almost all information is squeezed into one packet. Aggressive mode is a bit faster setting up the tunnel it is also less secure than main mode. Because when using aggressive mode both sides have exchanged information before there’s a secure channel and therefore it’s possible to sniff the line and discover who formed the new Security Association. In this example we’ll be using main mode as the exchange mode.
If you’re interested in the specifics of these exchange modes you can search for “ipsec exchange mode” on the internet. It is outside the scope of this post to go deeper into this subject.
Next, on line 6, we specify the lifetime of the IKE SA. An SA should not last indefinitely, in this example we give the IKE SA a lifetime of 1 hour which starts running the moment the SA is established. One minute before expiring the system renegotiates the SA and new key material is exchanged. Because the system does this before the SA has expired the user won’t notice a thing and is able to continue his work and communications with the remote side without interruptions.
Lines 7 through 12 specify the phase 1 policy like we did with the “crypto isakmp policy 1″ on the cisco. Everything defined in these lines is the same on the cisco because the has to be a matching policy.
Lines 15 through 22 define the phase 2 part of the IPSec setup. First we keep maintaining a Perfect Forward Secrecy Group 2 (remember the Diffie-Hellman comments earlier in this story?) on line 17. Next we also set a lifetime for the phase 2 SA on line 18 like we did a couple of moments ago for phase 1.
Line 19 and 20 will look a bit similar to the transform set we’ve created on the cisco. This is also what these lines represent. Needless to say they need to be the same on both sides. You’ll probably noticed that on the cisco we specified esp-3des and esp-sha-hmac and now in racoon we only specify 3des and sha-hmac. Well you’ve noticed correctly but if you look at ipsec-tools.conf we specified that communications require esp and when you match those up you’ve got esp-3des and esp-sha-hmac.
Last thing in this file is the compression_algorithm on line 21. Racoon requires this line to be present even if you’re not using compression. As far as I know “deflate” is also the only option possible at this moment, so just put it in there and forget about it.
/etc/racoon/psk.txt
the last step we haven’t completed, but mentioned before, is the PSK. So fire up your favorite text-editor one more time (my favorite is vim
) and edit this file.
Since we have only one IPSec tunnel setup this file needs one line containing the ip of the remote host and the PSK so for this example it should contain:
Finished!
If you’ve followed my instructions correctly you should be finished now. Try pinging the cisco (10.20.30.40) from the Debian box for example. It should start responding within a couple of seconds because it needs to setup the tunnel first. Also the ping times are a little higher than a direct link without IPSec because traffic has to be encrypted. In my case (I’ve used a crosscable between the cisco and debian box) my pingtimes were 2ms slower than without IPSec.
You should check if your IPSec link really got up by tailing /var/log/daemon.log on your debian box and check if you see messages from racoon passing by. This is also a very useful file if things don’t work, it tells you what might be wrong and on which IKE phase things are failing.
The same can be accomplished on the cisco by using one or more of these commands:
# enable IKE debugging
debug crypto isakmp
# enable IPSec debugging
debug crypto ipsec
# disable all debugging
no debug all
And last but not least to check if your traffic really gets encrypted fire up a tshark session on debian box monitoring the network interface you used to setup the IPSec link.
Of course you need to install tshark and replace eth0 by the network interface you used. If you’ll open up a ping to the remote host you should see ESP packets passing by.
I hope this was a useful howto and gave you a little more understanding in the world of IPSec. I know it worked for me, first figuring out and setting up the IPSec link but also whilst writing this post i got a greater understanding in how things work and why certain things are needed.
Please leave a comment if this has helped you or if you found mistakes or just because the fun of it
Kind regards and see you in part 2,
Lammert