Hack 68 Set Up IPsec Under FreeBSD

figs/moderate.gif figs/hack68.gif

Use FreeBSD's built-in IPsec support to secure your traffic.

Using IPsec with IKE under FreeBSD requires enabling IPsec in the kernel and installing a user-land program, racoon, to handle the IKE negotiations.

You'll need to make sure that your kernel has been compiled with the following options:

options         IPSEC               #IP security

options         IPSEC_ESP           #IP security (crypto; define w/ IPSEC)

options         IPSEC_DEBUG         #debug for IP security

If it hasn't, you'll need to define them and then rebuild and install the kernel. After you've done that, reboot to verify that it works.

racoon can be installed using the network section of the ports tree, or it can be downloaded from ftp://ftp.kame.net/pub/kame/misc/. Install raccoon per the instructions provided with the distribution.

On the client, you should first configure racoon. You will need to modify this example racoon.conf to suit your needs:

path include "/usr/local/etc/racoon" ;

path pre_shared_key "/usr/local/etc/racoon/psk.txt" ;

remote anonymous


        exchange_mode aggressive,main;

        my_identifier user_fqdn "user1@domain.com";

        lifetime time 1 hour;

        initial_contact on;

        proposal {

                encryption_algorithm 3des;

                hash_algorithm sha1;

                authentication_method pre_shared_key ;

                dh_group 2 ;



sainfo anonymous


        pfs_group 1;

        lifetime time 30 min;

        encryption_algorithm 3des ;

        authentication_algorithm hmac_sha1;

        compression_algorithm deflate ;


In your firewall configuration, be sure you allow IKE connections to your machine (UDP port 500). racoon needs to be configured to start at boot time. Save the following script in /usr/local/etc/rc.d/racoon.sh:


# This script will start racoon in FreeBSD

case "$1" in


# start racoon

   echo -n 'starting racoon'




# Delete the MAC address from the ARP table

   echo 'stopping racoon'

   killall racoon



# Standard usage statement

   echo "Usage: `basename $0` {start|stop}" >&2



exit 0

Make sure the file is executable by performing this command:

# chmod 755 /usr/local/etc/rc.d/racoon.sh

The /usr/local/etc/racoon/psk.txt file contains your credentials. This file must be readable only by root. If the permissions are not set correctly, racoon will not function. For a shared-secret IPsec connection, the file contains your identification (in this case your email address) and the secret. For instance, you can set up a psk.txt as the following:

user1@domain.com     supersecret

Finally, you must set up the security policy, using the setkey utility to add entries to the kernel SPD. Create the following client.spd that can be loaded by setkey. For this setup, the station IP is and the gateway is

# spdadd any -P out ipsec \ 

esp/tunnel/ ; 

# spdadd any -P in ipsec \ 

esp/tunnel/ ;

The first entry creates a security policy that sends all traffic to the VPN endpoint. The second entry creates a security policy that allows all traffic back from the VPN endpoint. Note that in this configuration the client is unable to talk to any hosts on the local subnet, except for the VPN gateway. In a wireless network where the client is a prime target for attack, this is probably a good thing for your workstation.

Load the SPD by running:

# setkey -f client.spd

The gateway racoon.conf is the same as the file for the client side. This allows any client to connect. The psk.txt file must contain all the identification and shared secrets of all clients who may connect. For instance:

user1@domain.com      supersecret

user2@domain.com      evenmoresecret

user3@domain.com      notsosecret

Again, make sure psk.txt is readable only by root. Start racoon and make sure there are no errors. Finally, set up a gateway.spd that creates an SPD for each client. The following example assumes your clients are at[4-6]:

# spdadd any -P out ipsec \ 

esp/tunnel/ ; 

# spdadd any -P in ipsec \ 

esp/tunnel/ ; 

# spdadd any -P in ipsec \ 

esp/tunnel/ ; 

# spdadd any -P out \

ipsec esp/tunnel/ ; 

# spdadd any -P in ipsec \ 

esp/tunnel/ ; 

# spdadd any -P out ipsec \ 

esp/tunnel/ ; 

Load the SPD by issuing setkey -f gateway.spd. Verify the SPD entries using the spddump command in setkey. At this point, you should be able to ping a client from the gateway. It may take a packet or two for the VPN negotiation to complete, but the connection should be solid after that. If you are unable to ping, examine your syslog output for errors and warnings.