IPSec VPN using FreeBSD
Because I couldn’t find any ready-to-go guides on using a IPSec tunnel on FreeBSD, and the online handbook gives unnecessary information*, I decided to share this guide with you, as a kickstart to get you up and running. Then you can refine things afterwards for your specific situation.
I took two FreeBSD 6.2 machines, and updated to the latest sources using cvs. Read on here for an example tutorial on that process. Both machines have 2 nic’s, and function as a network gateway. We will connect these machines together using an IPSec tunnel. It’s important that the external nic’s are not behind a NAT, as that will complicate things even more.
Add this line to /etc/rc.conf to allow for ip routing:
gateway_enable=”YES”
First thing is to compile IPSec support in your FreeBSD kernel. I got a stock FreeBSD 6.2 machine, and recompiled the kernel adding these options:
options IPSEC
options IPSEC_ESP
options IPSEC_DEBUG
If you don’t know how to recompile your kernel, have a look at this page. You should also be able to use the FAST_IPSEC option instead of these, but I have no experience with this option.
Now we will define which destination networks will need encryption. Create a file called /etc/ipsec.conf on BOX1 with these contents:
flush;
spdflush;
spdadd 192.168.1.0/24 172.16.1.0/24 any -P out ipsec esp/tunnel/A.A.A.A-B.B.B.B/require;
spdadd 172.16.1.0/24 192.168.1.0/24 any -P in ipsec esp/tunnel/B.B.B.B-A.A.A.A/require;
4 lines in total, the 2 spdadd lines break here because of the layout. Ofcourse you should change these network addresses to match yours, and change A.A.A.A and B.B.B.B to the external ip addresses as shown in the diagram. On BOX2 create the same file, but then with the ‘in’ and ‘out’ keywords reversed.
Add this to your /etc/rc.conf to enable these policy rules to loaded on boot:
ipsec_enable=”YES”
ipsec_file=”/etc/ipsec.conf”
Next you need a keying daemon, such as racoon. To install racoon, install ‘ipsec-tools’ from ports. Go to the /usr/ports/security/ipsec-tools directory, and type ‘make install clean’. This will compile and install the ipsec-tools from source. Add the following to /etc/rc.conf to start racoon on boot:
racoon_enable=”YES”
We’ll create a pre-shared key to communicate.. On BOX1 create a file like /usr/local/etc/racoon/psk.txt with the contents:
B.B.B.B password
You should change ‘password’ to something less easy to guess, and on BOX2 create a file with the contents:
A.A.A.A password
Then for the most complex configuration, here’s racoon’s configuration file, with me it’s called /usr/local/etc/racoon/racoon.conf, and I put a symlink to it in /etc, so racoon would find it out of the box. There are a lot of options and settings I don’t know, but ‘man racoon.conf’ is your friend. Here’s the file for BOX1:
path include “/usr/local/etc/racoon”;
path pre_shared_key “/usr/local/etc/racoon/psk.txt”;
#log debug;
padding
{
maximum_length 20; # maximum padding length.
randomize off; # enable randomize length.
strict_check off; # enable strict check.
exclusive_tail off; # extract last one octet.
}
# if no listen directive is specified, racoon will listen on all
# available interface addresses.
listen
{
isakmp A.A.A.A [500];
}
# Specify various default timers.
timer
{
# These value can be changed per remote node.
counter 5; # maximum trying count to send.
interval 20 sec; # maximum interval to resend.
persend 1; # the number of packets per send.
# maximum time to wait for completing each phase.
phase1 30 sec;
phase2 15 sec;
}
remote B.B.B.B
{
exchange_mode main,aggressive;
doi ipsec_doi;
#situation identity_only;
my_identifier address;
nonce_size 16;
lifetime time 86400 seconds;
initial_contact on;
#proposal_check obey; # obey, strict or claim
proposal_check obey;
proposal {
encryption_algorithm 3des;
hash_algorithm md5;
authentication_method pre_shared_key ;
dh_group 2;
}
}
sainfo anonymous
{
pfs_group 2;
encryption_algorithm 3des;
authentication_algorithm hmac_md5;
compression_algorithm deflate ;
}
That’s it, on BOX2 you can create the same file, but then reverse A.A.A.A and B.B.B.B.
What happens is that if you want to connect to a remote host, according to the SPD policy you created in ipsec.conf, the kernel knows this data should be encrypted and transported across the tunnel. It knows to which endpoint it should connect, and asks racoon to set up the encryption and authentication. Racoon connects to the right ‘remote’ entry, and sets up a phase 1 connection (IKE). If that succeeds, it sets up a phase 2 connection. These two phases both have a seperate section in your racoon.conf, and they have to match in order for the connection to be successful.
The final step is to add a route to the machine, to enable traffic to the remote network to reach it. You should add a static route to the remote network, using your internal NIC as gateway. Add the following lines to /etc/rc.conf on BOX1:
static_routes=”vpn”
route_vpn=”-net 172.16.1.0/24 192.168.1.1″
And the following on BOX2:
static_routes=”vpn”
route_vpn=”-net 192.168.1.0/24 172.16.1.1″
After a reboot (when all rc.conf values are applied), you should be up and running! You can ping a host on the remote network, and keep an eye on /var/log/security to see what racoon’s doing.
* The handbook talks about creating gif tunnels, which is not necessary, and adds overhead and complexity according to the ipsec-tools-developer mailing list.






[...] Along the way I have gotten to know IPSec
Angelo’s blog » IPSec VPN tunnel using FreeBSD | February 13, 2007 | 6:13 pm[...] Along the way I have gotten to know IPSec a little bit better, and I have written a guide to help people (like myself) to get up and running quickly, at least with a FreeBSD-FreeBSD tunnel: Read the guide here [...]
hello there. i want to ask you something. is ipsec
hello there. i want to ask you something. is ipsec vpn for freebsd allowed multiple client (which have direct connection) from outside? when i read the handbook, seems like ipsec vpn for bsd is for network to network and not single computer into network. because i don’t see any configuration that did like that.
i said because i compare with linux ipsec vpn that can be connected by multiple client, and can assigned multiple ip to every client connected and have configuration with username and password. correct me if i wrong. thank you
i hope angelo can reply me. thank you
Cybersans, I guess it's possible, but I have no experience
Cybersans, I guess it’s possible, but I have no experience with it, I guess you’ll have to google yourself.. Try searching for ‘freebsd ipsec transport mode’ or something. Transport mode is usually used for host to host, as opposed to tunnel mode, which is usually used for lan 2 lan.
Master! If I have one NIC on my boxes... can I
Master!
If I have one NIC on my boxes… can I use alias on them? and if not could you please explain how to do that?
Thanks
Hamed