IPsec Encryption Between FreeBSD Hosts

With the passing of the evil IP Bill in the UK, security has to be focused on more closely – so I will try to do some more security related posts in the coming weeks…

By encrypting the data between my FreeBSD hosts, nobody can eavesdrop my communication (at least not without my knowledge!).  This article will show how to encrypt all IP data between two static IPs that are FreeBSD hosts.

For the sake of this article, I will assume it is between two FreeBSD 11 hosts as these already have the necessary kernel options set.  (Pre-11 FreeBSD requires a custom kernel with the various IPSEC additions being added first)

  • Host 1 has an IPv4 IP of and an IPv6 IP of 2001:db8::1.
  • Host 2 has an IPv4 IP of and an IPv6 IP of 2001:db8::2.
  • We will use AES-CTR encryption (in the hopes that our CPU has accellerated instructions for it via the aesni kernel module) which requires a 288-bit key to be passed to it.  (this comprises of 256 bits of key, and 32 bytes of nonce)

On both hosts, ensure that the aesni module is loaded by adding to /boot/loader.conf:


You can also load it without rebooting using:

kldload aesni

Next, we can construct our rules.  Create the file /etc/ipsec.conf with these contents:

# flush out existing keys
spdflush ;
flush ;

# configure encryption between and in both directions
add esp 0x6abe98ab
-m transport
-E aes-ctr 0x0d3ccb8132cbc81e625f7381d60492a27841eac320b6e01296a4c99dd9b4be0968fbb70e ;
add esp 0x3075a69c
-m transport
-E aes-ctr 0xf6f780906d22eb00163c99ce12d99c2e246a45ff59bea5799486d5a3492a5d093a582e06 ;

# configure encryption between 2001:db8::1 and 2001:db8::2 in both directions
add 2001:db8::1 2001:db8::2 esp 0x10f71984
-m transport
-E aes-ctr 0x9b0a45098f9c28e3e1150c9cd169af5d304b89ab1be30cefcb6b1adc593955a551f441b2 ;
add 2001:db8::2 2001:db8::1 esp 0x6c11688d
-m transport
-E aes-ctr 0xd55f97a9e946121fc792725272d9e27c2bd5db4606fa7d734ee2a4344d55f3249cd65fcb ;

# force encryption between and in both directions
spdadd any -P in ipsec esp/transport//require ;
spdadd any -P out ipsec esp/transport//require ;
# force encryption between 2001:db8::1 and 2001:db8::2 in both directions
spdadd 2001:db8::1 2001:db8::2 any -P in ipsec esp/transport//require ;
spdadd 2001:db8::2 2001:db8::1 any -P out ipsec esp/transport//require ;

On Host 2 you need to swap the words “in” and “out” in the spdadd lines (just those words, not the lines themselves!)

In the above example you would set your own SPI id (the number after the word “esp”) – this is a 32-bit integer that can be listed in decimal or hex format and should be higher than 100.

You would also set your own AES keys.  You just need 36 bytes of random key data in hex format.  The above keys were generated at random.

You can also see that we are using different keys for each direction.  This isn’t required, and you can use the same key for both directions if you wish.

In the configuration file, the ‘add’ lines configure which encryption parameters will be used for communication – but does not actually activate them.  The ‘spdadd’ lines force encryption between the two IPs.  Notice that you don’t tell it which keys to use, they are acquired from the ‘add’ lines above them.

Now all you need to do is configure your system to apply the ipsec rules on boot.  Add the following lines to the end of your /etc/rc.conf file:


You can activate them immediately with:

service ipsec start

You should be very careful with this especially the first time as you may lock yourself out of your machine(s) !  Always ensure you have a way back in just in case – e.g. console access.

Should you be locked out, and manage to log back in via alternative means you can flush all your ipsec rules with the following command:

service ipsec stop

Remember to do this on both ends!  Also remember that this will remove ALL ipsec rules.

This method sadly can’t be used for entire subnets (other than adding rules for each IP!) so is not always the preferred method… but it’s great for quick single IP endpoints.

1 thought on “IPsec Encryption Between FreeBSD Hosts

  1. Jim S Smith

    Hi Dan.

    I have been perusing your site, and found LOTS of very useful information, especially about TOR-nodes, etc.

    I am preparing to restore all of my sites that have been down a while, due to some hacking that went on – AND the crap service of HostGator! – For your own sanity and others, STAY AWAY FROM HOSTGATOR – and any other service owned by ‘Endurance’ International Group (E.I.G. – Hah ! ! !).


    After examining what miniscule amount of logs I actually had access to, it seemed that my website was one of many that suffered a beating from (D)DoS-es and the poor server-maintenance by HostGator “techs”. – I also started to recognize some of the U.A-strings and IP Addresses – as being VERY similar to some of what was to be found within the infamous “TORSHAMMER” Python script!


    I have been very busy (for MONTHS, that is) compiling what knowledge and information I could find to build a better “firewall” for all of my websites. I have scoured many different sources of security-related info, and eventually started developing and testing out ideas on my “XAMPP-Box” (running good ‘ol Linux!) I am beginning to see how beautiful a language PHP is, once I learned the “ins-and-outs” of it.

    I have also taken an interest in proxies, lately, because I DO believe in the right of privacy while on-line. I just want to make sure that they are humans, NOT bots, who are visiting my websites!

    I very much appreciate the great service you GIVE to the world of computing (and apparently, Amateur Radio too!) – I am also a BIG radio fan, and was a radio operator for my nation’s army for eight years. – Nothing like building and operating your own, though.

    I have a few PHP projects I will probably be releasing to the public as open source very soon. I hope my little bit of help in contributing some of my talents will benefit the People, and the People’s Internet!

    Thank you for such great and useful resources!!!

    – Jim


Leave a Reply

Your email address will not be published. Required fields are marked *