Document made with KompoZer

*** HOWTO build tunnels with libreswan ***

Libreswan is a free implementation of IPsec & IKE for Linux. IPsec is the Internet Protocol Security and uses strong cryptography to provide both authentication and encryption services. These services allow you to build secure tunnels through untrusted networks. Everything passing through the untrusted net is encrypted by the ipsec gateway machine and decrypted by the gateway at the other end of the tunnel. The resulting tunnel is a virtual private network or VPN.

Two excellent websites are:



Both give step-by-step instructions to configure libreswan, but the second site gives better instructions for a roadwarrior.

I will summarize what I did below to setup a LAN to LAN tunnel, and a roadwarrior tunnel.

Getting Started

Install libreswan and verify:

# yum install libreswan

# rpm -qa *swan*


This installs some configuration files:

# ll -R /etc/ipsec*

-rw------- 1 root root 708 Sep 27 14:50 /etc/ipsec.conf

-rw------- 1 root root 31 Sep 27 14:50 /etc/ipsec.secrets


total 100

-rw------- 1 root root 65536 Oct 27 15:19 cert8.db

-rw------- 1 root root 16384 Oct 27 15:19 key3.db

drwx------. 2 root root 4096 Oct 9 10:58 policies/

-rw------- 1 root root 16384 Sep 17 19:18 secmod.db


total 20

-rw------- 1 root root 229 Sep 27 14:50 block

-rw------- 1 root root 431 Sep 27 14:50 clear

-rw------- 1 root root 351 Sep 27 14:50 clear-or-private

-rw------- 1 root root 246 Sep 27 14:50 private

-rw------- 1 root root 506 Sep 27 14:50 private-or-clear

Libreswan uses an NSS database to access the public/private keys. This consists of the three *.db files listed above. It is simple to manually (re)create them:

# ipsec initnss

and when prompted for a password, simply hit ENTER, else that password will be required every time ipsec is started subsequently.

I use RSASIG public/private keys exclusively for authentication because that's the most secure method (and I don't understand certificates, which are an alternative).

There are four steps to success:

1) Create a unique key on each machine.

2) Create a  <conn>.conf  file on each participating machine.

3) Adjust the router's firewall.

4) Start ipsec.

To create a unique public/private key for this machine:

# ipsec newhostkey --configdir /etc/ipsec.d \
  --output /etc/ipsec.d/thismachine.secrets

Verify that the new key can be retrieved

# ipsec showhostkey --left

LAN to LAN tunnel

Create a configuration file for each tunnel in /etc/ipsec.d/, paying careful attention to indenting. Each line below conn MUST have leading white space; the rsakey line is a single long line; comments follow a # character, eg,

# cat /etc/ipsec.d/datix-dino.conf

conn datix-dino





leftnexthop=%defaultroute # correct in many situations





rightnexthop=%defaultroute # correct in many situations


The above config file will connect the leftsubnet= at datium to the rightsubnet= at octopus, allowing any references to the opposite subnet to transit the encrypted tunnel.

An identical or symmetric copy of this file must be installed on octopus. The left and right designators may be swapped, or left as is; libreswan will figure out who's right and who's left.

Roadwarrior Configuration

The above example links two similar LAN's via a tunnel. For a "roadwarrior", ie, a laptop that may call in from anywhere, has no local subnet to offer, but merely wants full access to the main LAN, the config file is different, and asymmetric:

On datium, the main LAN gateway, we have:

# cat road.conf

conn road













The corresponding file on datasus, the laptop, is:

# cat /net/datasus/etc/ipsec.d/road.conf

conn road












One notable difference is the 'auto=start' line. This will immediately start the tunnel when ipsec is started on the laptop, eg,

systemctl start ipsec

When ipsec is started, progress should be monitored via

tail -f /var/log/secure

The thing to look for is a line like this:

Mar 9 15:46:50 datium pluto[16260]: "road"[1] #17:
STATE_MAIN_R3: sent MR3, ISAKMP SA established {auth=RSA_SIG
cipher=aes_256 integ=sha group=MODP2048}

which says that SA is established for the "road" connection.

Router firewall & iptables

Port 500/UDP must be passed thru by the router to the gateway machine so that the setup authentication can succeed. The iptables rules on the gateway machine must not NAT packets for the remote network. In general, the gateway machine doesn't need to do any NAT'ing at all, but if it does, destinations at the remote network must be excluded.

When these configurations are complete, restart the ipsec service at both ends

systemctl enable ipsec

systemctl start ipsec

Then start the tunnel (from one end)

ipsec auto --up datix-dino

DNS requirements

Assume DNS and named are working correctly on both networks:

datium -

octopus -

For machines on either LAN to resolve names on the other, the DNS tables must be augmented to forward requests to the opposite named server, eg, on datium, edit /etc/named.conf to add a new zone:

zone "dino.lan" {

type forward;

forward only;

forwarders {; };


and edit /etc/resolv.conf (on datium) to search both domains:

domain datix.lan.

search datix.lan dino.lan


With both of these changes, a name, say, dainty, will be expanded to dainty.dino.lan and a lookup will be forwarded to which can resolve it.

Corresponding changes on both datium and octopus are required, for symmetry.

For roadwarrior operation, some edits are necessary.

- the roadwarrior will acquire an /etc/resolv.conf setup that is ignorant of the remote LAN. It should be edited to say:

search datix.lan.


- the named-chroot server on datium must allow DNS requests from whatever IP the roadwarrior happens to be using. Assuming that with any reasonable dynamic IP configuration, the laptop will be assigned an IP from the private range, I have modified datium's /etc/named.conf to allow all such requests, ie,

allow-query {; 192.168/16;; };

With this setup, all DNS lookups will be provided by datium when the roadwarrior tunnel is operating, to the exclusion of whatever services the local connections had provided.