Using IPsec Tunnel Mode for Site-Site Encryption

It has taken a long time, but I have finally managed to get IPsec working. This is how I did it.

IPsec Tunnel Mode

IPsec Tunnel Mode is typically used for site-to-site connections, whereas transport mode is typically used for client/server connections.

My IPv6 ULA prefix is fdd7:5938:e2e6::/48. My ULA prefix on my home network is fdd7:5938:e2e6:1::/64, vps3 is fdd7:5938:e2e6:6c8d::/64, and vps4 will be fdd7:5938:e2e6:8e71::/64.

ULA prefixes are supposed to be unique, and to avoid collisions sixxs have created a database so you can search to see if someone else is using the random prefix you just generated. My prefix is in that database because although it is unlikely my ULA network will merge with someone else's, it isn't an impossible scenario.

I tried to update my contact/WHOIS details for my ULA prefix with sixxs, but have not yet received a response and it is still listing my old details. It is of no real concern, though, because the database is really for what ULA prefixes are in use (to avoid collisions with network merges), not for which ones are in use and by whom.

If you have ever plugged in a router to a network and there has suddenly been two routers advertising "I'm your default gateway, 192.168.0.1!" you have probably experienced issues. The ULA address space is large: an entire IPv6 /8. With each self-allocated random prefix being a /48, that is 248-8 = 240 = 1,099,511,627,776 /48's, or 1 trillion, 99 billion, 511 million, 627 thousand, 7 hundred and seventy six Unique Local Address prefixes, each with 65,536 networks, with each network having up to 264 IP addresses (18 quintillion, 446 quadrillion, 744 trillion, 73 billion, 709 million, 551 thousand, 6 hundred and sixteen).

Put another way, if your ULA prefix is randomly generated and you merge networks with someone else using a random ULA prefix, the odds of an address collision is improbable. Merge with a network that isn't using a random ULA prefix, however, and the odds of address collisions with a subsequent network merging where that network manager also didn't use a random ULA prefix are much more likely than improbable.

My ULA /64's use my ULA prefix with the last 4 hex characters of the main network card's MAC address on that machine/router appended. The reason my home network is 1 is because that is how it stuck after my original setup.

fdd7:5938:e2e6:3::/64 is reserved for site-to-site links (every server having a single IP in the same /64), with fdd7:5938:e2e6:3::1 for my home server and fdd7:5938:e2e6:3::6c8d for vps3.

My new VPS, vps4, is going to use the prefix fdd7:5938:e2e6:8e71::/64 and IP fdd7:5938:e2e6:3::8e71.

The naming convention I used for 6in4 tunnels over cjdns are going to be used for IPsec connections. Unlike my 6in4 tunnels, however, IPsec doesn't create interfaces (it did historically).

For the IPsec connection between my home server and VPS4, I am going to call it ula-net-vps4. On vps4, I am going to call it ula-net-home, alligning the suffix (home/vps4) with the hostname at the other end of the link (i.e. home.johncook.co.uk & vps4.johncook.co.uk).

ula-net-home

  • Local IP: 185.133.75.14
  • Remote IP: Dynamic
  • Local IPv6 Subnet: fdd7:5938:e2e6:3::8e71/128, fdd7:5938:e2e6:8e71::/64
  • Remote IPv6 Subnet: fdd7:5938:e2e6:1::/64, fdd7:5938:e2e6:1::/64

ula-net-vps4

  • Local IP: Dynamic
  • Remote IP: 185.133.75.14
  • Local IPv6 Subnet: fdd7:5938:e2e6:3::1/128, fdd7:5938:e2e6:1::/64
  • Remote IPv6 Subnet: fdd7:5938:e2e6:8e71::/64, fdd7:5938:e2e6:8e71::/64

Removing the Confusion

IPsec is a subject that I have not yet been able to get my head around. I believe my confusion on the subject is because it mashes everything together.

Take as an example the connection between my home server's postfix and vps3's postfix. They are secured using SSL between the two applications. The ULA IPs are reachable through a point-to-point tunnel. That tunnel uses cjdns IPs as endpoints at both ends, and it previously used public IPv6 IPs as endpoints—I can comprehend the difference because the point-to-point connection is separate from the cjdns connection.

IPsec, on the other hand, bundles certificates, point-to-point connections, and site-to-site tunnels together. There is not actually a decent video tutorial that covers absolutely everything I want to achieve, however the following videos did help.

Thumbnail of YouTube video: IPsec - CompTIA Network+ N10-005: 5.2

Video: IPsec - CompTIA Network+ N10-005: 5.2

Play Video Embedded Watch Video on YouTube Google Privacy Policy Google Cookies
Thumbnail of YouTube video: Understanding AH vs ESP and ISKAKMP vs IPSec in VPN tunnels

Video: Understanding AH vs ESP and ISKAKMP vs IPSec in VPN tunnels

Play Video Embedded Watch Video on YouTube Google Privacy Policy Google Cookies
Thumbnail of YouTube video: Cuidado Digital: IPSec Strongswan PPTP no Debian Squeeze pt-br

Video: Cuidado Digital: IPSec Strongswan PPTP no Debian Squeeze pt-br

Play Video Embedded Watch Video on YouTube Google Privacy Policy Google Cookies

Yes, that third video is in Brazilian Portuguese. It is, however, the closest video to what I wanted to do (albeit using IPv4 on both LANs rather than IPv6).

Certificates

Generating the keys and certificates is going to be more in depth than it needs to be as I am merging the process I discussed in several articles on Let's Encrypt into this article, including using eliptic curve keys rather than RSA keys.

The headings have been aligned based on this, with the next level 2 heading being the installation and coniguration of IPsec.

Certificate Authority

There are two options:

  1. Create my own certificate authority.
  2. Use an existing trusted certificate authority.

I started writing this article over one and a half years ago (February 2015) when I was setting up vps3. In the end I decided setting up IPsec was too much hassle and that the only way to get my new VPS up and running before vps2 stopped working was to continue to use cjdns instead of IPsec.

This time, however, I am not discontinuing my use of my "old" VPS—vps3 will continue to be used. The one deadline I was up against, however, was the Chromium team deciding that as of they would disable NPN support in Chrome and Chromium. That meant if I wanted to continue using HTTP/2 then I would need Ubuntu Xenial, and I wouldn't be upgrading vps3 until vps4 could take over while the upgrade takes place.

This article has taken such a long time to write things have changed. VPS3 will be terminated at as its main usage has been transitioned to vps5 (same provider, same plan, Ubuntu Xenial). VPS4 is going to continue to be used so that things like e-mail, DNS, and Web sites can remain up if I reboot a VPS.

Anyway, I am going to be using Let's Encrypt as the certificate authority. If my understanding of strongSwan's configuration options are correct, then I can configure each tunnel separately so that a connection from home must have the IP address of home.johncook.co.uk and be using a certificate issued by Let's Encrypt.

Very Basic Understanding

IPsec in ESP tunnel mode creates a tunnel between two IP addresses. It does this in two stages:

  1. Setup a IKE connection (Security Association or SA).
  2. Setup an ESP connection (Child Security Association, or Child SA).

Before I realised there was an issue with the ESP ciphers I was telling my home server to use, I thought an 'IPsec connection' was established between my two servers. I was wrong.

What I really had was an established IKEv2 SA. Because the configuration had a problem with my chosen ESP ciphers, no ESP Child SA could be setup, resulting in the errors no acceptable proposal found and failed to establish CHILD_SA, keeping IKE_SA.

It took me 2½ days to figure out what was really happening, and I believe this issue (or something equally difficult to work out) is what stopped me from trying to get IPsec working when I setup vps3.

If an IKE SA cannot be established, then the problem is with the first stage. This could be due to unsupported ciphers in ike=, a problem with the certificate (intermediates also need to be available locally), a problem with the private key, or a problem with permissions (e.g. apparmor getting in the way of things).

If an IKEv2 SA is established, but an ESP Child SA can not be, then it has nothing to do with certificates, the private key, or certificate/key file permissions.

In both cases it could be a firewall issue, although assuming something is a firewall issue when it is not can result in an infuriating couple of days trying to work out why no ICMPv6 packets are reaching your firewall rules.

Certificate Generation

As with all Let's Encrypt certificates, I will be doing it all from my laptop.

In the original version of this article I generated a 256-bit ECDSA key, which is roughly equivalent to 3,072-bit RSA. SSL Labs currently gives a key exchange rating of 90% for 2048-4095 bit RSA (or equivalent strength) keys and DH parameters, and 100% for 4096+ bit RSA (or equivalent strength).

I already use 4096-bit RSA keys for my Web servers, and 4096-bit DH parameters for them too, so I will be generating a 384-bit ECDSA key this time.

Key Generation

On my laptop:

sudo su
cd /etc/ssl
mkdir vps4.johncook.co.uk
chmod 775 vps4.johncook.co.uk
chgrp thejc vps4.johncook.co.uk
exit
cd /etc/ssl/vps4.johncook.co.uk
openssl ecparam -out vps4_johncook_co_uk.key1 -name secp384r1 -genkey

CSR Generation

openssl req -new -sha256 -key /etc/ssl/vps4.johncook.co.uk/vps4_johncook_co_uk.key1 -subj "/C=GB/ST=Hertfordshire/L=Watford/O=John Cook/CN=vps4.johncook.co.uk/emailAddress=hostmaster@johncook.co.uk" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:vps4.johncook.co.uk\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth,clientAuth\nsubjectKeyIdentifier=hash\n")) -text

Check the CSR looks correct, and then output in DER format to a file:

openssl req -new -sha256 -key /etc/ssl/vps4.johncook.co.uk/vps4_johncook_co_uk.key1 -subj "/C=GB/ST=Hertfordshire/L=Watford/O=John Cook/CN=vps4.johncook.co.uk/emailAddress=hostmaster@johncook.co.uk" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:vps4.johncook.co.uk\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth,clientAuth\nsubjectKeyIdentifier=hash\n")) -out vps4_johncook_co_uk.csr -outform DER

With the private key and CSR, the next thing I need to do is setup a Web server on VPS4 so that Let's Encrypt can verify ownership.

Installing and Configuring NGINX

On vps4, add the nginx repository PGP key and then add the nginx repositories and update them.

wget -O - 'http://nginx.org/keys/nginx_signing.key' | sudo apt-key add -
sudo nano /etc/apt/sources.list
## NGINX
deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx
sudo apt-get update && sudo apt-get dist-upgrade

A new kernel image was installed. After rebooting and re-establishing an SSH session, time to install nginx:

sudo apt-get install nginx

Configuring NGINX

By default, NGINX listens on all IP addresses. I am OK with that as I am going to be refusing connections to the default_server that aren't to /.well-known/acme-challenge/.

I am, however, going to include the IP address, as well as some commented out lines for port 443 for when I enable TLS. This is because NGINX might ignore default_server if a virtual host uses something more specific (i.e. 185.133.75.14:80 would be more specific than 0.0.0.0:80), and there is no reliable way of knowing which virtual server NGINX will use as the default.

The commented out lines for port 443 will also need to be uncommented when I set up TLS, as will the line that includes my 'default' SSL configuration. This is so that the server won't serve the wrong Web site on an unconfigured TLS-enabled vhost.

sudo nano /etc/nginx/sites-enabled/default_server.conf
server {
	listen 80 default_server;
#	listen 443 ssl http2 default_server;
	listen 185.133.75.14:80 default_server;
#	listen 185.133.75.14:443 ssl http2 default_server;
	server_name _ "";
#	include /etc/nginx/includes/web.johncook.co.uk-ssl;

	location ~ (/.well-known/acme-challenge/) {
		return 307 http://sip.johncook.co.uk$request_uri;
	}

	location / {
		return 444;
	}
}
sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf-orig
sudo service nginx restart

Install lynx and check the server is working on localhost:

sudo apt-get install lynx
lynx http://127.0.0.1
Looking up 127.0.0.1
Making HTTP connection to 127.0.0.1
Sending HTTP request.
HTTP request sent; waiting for response.
Alert!: Unexpected network read error; connection aborted.
Can't Access `http://127.0.0.1/'
Alert!: Unable to access document.

lynx: Can't access startfile
lynx http://127.0.0.1/.well-known/acme-challenge/nonexistant

The redirect worked, so time to open up the firewall.

sudo nano /etc/network/iptables.save

Uncomment the following line:

### Web ###
# Permit HTTP(S) connections to primary IP
-A in-new -d 185.133.75.14 -p tcp -m multiport --dports 80,443 -j ACCEPT
sudo nano /etc/network/ip6tables.save

Uncomment the following line:

### Let's Encrypt ###
-A in-new -d 2a06:8ec0:1:ec::2da9 -p tcp -m multiport --dports 80 -j ACCEPT

Reload iptables.save and ip6tables.save:

sudo iptables-restore < /etc/network/iptables.save
sudo ip6tables-restore < /etc/network/ip6tables.save

Back on my laptop, check that http://vps4.johncook.co.uk/ returns a connection error or empty response error, and http://vps4.johncook.co.uk/.well-known/acme-challenge/nonexistant returns a 404.

NGINX is now minimally set up.

Side note: The reason I refer to 'nonexistant' is so when checking logs in future I can include/exclude lines that match. If I were to actually create an URL that includes that word, I would spell it correctly. Some search engines will completely ignore the fact those URLs aren't actually hyperlinks and try crawling them anyway.

Create Folder Structure and Transfer Private Key

Create a folder on vps4 to store the key and certificate:

cd /etc/ssl
sudo mkdir vps4.johncook.co.uk
sudo chown thejc:sudo vps4.johncook.co.uk
sudo chmod 755 vps4.johncook.co.uk

From my laptop, transfer across the private key:

cd /etc/ssl/vps4.johncook.co.uk
scp vps4_johncook_co_uk.key1 thejc@vps4:/etc/ssl/vps4.johncook.co.uk/
sudo chmod 400 vps4_johncook_co_uk.key1

And then back on vps4 change the permissions of the private key, and convert it to DER format:

cd /etc/ssl/vps4.johncook.co.uk
openssl ec -in vps4_johncook_co_uk.key1 -inform PEM -outform DER -out vps4_johncook_co_uk.key1
sudo chmod 400 vps4_johncook_co_uk.key1
sudo chown root:thejc vps4_johncook_co_uk.key1

Certificate Creation

On my laptop:

cd ~/lets-encrypt-data
sudo mkdir vps4_johncook_co_uk
sudo chown root:thejc vps4_johncook_co_uk
sudo chmod 670 vps4_johncook_co_uk
cd csr
ln -s /etc/ssl/vps4.johncook.co.uk/vps4_johncook_co_uk.csr vps4_johncook_co_uk.csr

Use letsencrypt-auto to request a certificate. The following will also be how the certificate is renewed.

sshfs -o idmap=user -o allow_root thejc@home:/home/www/var/www/acme-challenge /mnt/acme-challenge/
cd ~/lets-encrypt-data/
/opt/letsencrypt/letsencrypt-auto -c ~/lets-encrypt-data/config/letsencrypt.conf auth -a webroot -w /mnt/acme-challenge/ --csr ~/lets-encrypt-data/csr/vps4_johncook_co_uk.csr
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /home/thejc/lets-encrypt-data/0009_chain.pem. Your cert will expire
   on 2016-08-05. To obtain a new version of the certificate in the
   future, simply run Let's Encrypt again.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

cp 0009_* vps4_johncook_co_uk/
cd vps4_johncook_co_uk/
cp 0009_chain.pem vps4_johncook_co_uk.chained.pem
scp vps4_johncook_co_uk.chained.pem thejc@vps4:/etc/ssl/vps4.johncook.co.uk/
sudo umount /mnt/acme-challenge/

Another Certificate for Home Server

At this point I need to repeat the entire process again, this time generating a certificate for home.johncook.co.uk.

As my home server's Web server is already configured for Let's Encrypt validation, I just need to start from the heading Create Folder Structure and Transfer Private Key.

With that done I now have a 384-bit ECDSA (secp384r1) key and an ECC certificate for both home.johncook.co.uk and vps4.johncook.co.uk.

IPsec Installation

For IPsec I am going to be using strongSwan.

On vps4:

sudo apt-get install strongswan strongswan-plugin-curl

On home:

sudo apt-get install strongswan libstrongswan-standard-plugins libstrongswan-extra-plugins

IPsec Configuration

The closest documentation to what I am attempting to do is ipv6/net2net-ip6-in-ip4-ikev2.

Using that documentation and configuration samples, vps4 is moon, and home is sun.

Configuring IPsec on VPS4

On vps4, configure IPsec:

sudo nano /etc/ipsec.conf
config setup

conn %default
	ikelifetime = 60m
	keylife = 20m
	rekeymargin = 3m
	keyingtries = 1
	keyexchange = ikev2
	mobike = no
	ike = aes256gcm16-prfsha384-ecp384,aes128gcm16-prfsha256-ecp256!
	esp = aes256gcm16-ecp384,aes128gcm16-ecp256!

conn ula-net-home
	left = 185.133.75.14
	leftsubnet = fdd7:5938:e2e6:8e71::/64,fdd7:5938:e2e6:3::8e71/128
	leftcert = /etc/ssl/vps4.johncook.co.uk/vps4_johncook_co_uk.chained.pem
	leftauth = pubkey
	leftid = @vps4.johncook.co.uk
	leftsendcert = always
	leftfirewall = yes
	right = home.johncook.co.uk
	rightsubnet = fdd7:5938:e2e6:1::/64,fdd7:5938:e2e6:3::1/128
	rightauth = pubkey
	rightid = @home.johncook.co.uk
	auto = route
	type = tunnel

Download the Let's Encrypt intermediates and root certificates, and then create symbolic links to them:

sudo mkdir /etc/ssl/LetsEncrypt/
sudo chown thejc:thejc /etc/ssl/LetsEncrypt/
cd /etc/ssl/LetsEncrypt
wget 'https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem'
wget 'https://letsencrypt.org/certs/lets-encrypt-x4-cross-signed.pem'
wget 'https://letsencrypt.org/certs/isrgrootx1.pem'
cd /etc/ipsec.d/cacerts
sudo ln -s /etc/ssl/certs/DST_Root_CA_X3.pem DST_Root_CA_X3.pem
sudo ln -s /etc/ssl/LetsEncrypt/isrgrootx1.pem isrgrootx1.pem
sudo ln -s /etc/ssl/LetsEncrypt/lets-encrypt-x3-cross-signed.pem letencrypt-x3-cross-signed.pem
sudo ln -s /etc/ssl/LetsEncrypt/lets-encrypt-x4-cross-signed.pem letencrypt-x4-cross-signed.pem

Tell strongSwan about the private key:

sudo nano /etc/ipsec.secrets
: ECDSA /etc/ssl/vps4.johncook.co.uk/vps4_johncook_co_uk.key1

Configure apparmor so that the certificates and key can be accessed:

sudo nano /etc/apparmor.d/local/usr.lib.ipsec.charon
	/etc/ssl/LetsEncrypt/** r,
	/etc/ssl/vps4.johncook.co.uk/vps4_johncook_co_uk.key* r,
	/etc/ssl/vps4.johncook.co.uk/vps4_johncook_co_uk.chained.pem	r,
sudo apparmor_parser -r /etc/apparmor.d/usr.lib.ipsec.charon

Reload the configuration and re-read everything:

sudo ipsec reload
sudo ipsec rereadall

Configuring IPsec on Home

On home, configure IPsec:

sudo nano /etc/ipsec.conf
config setup

conn %default
	ikelifetime = 60m
	keylife = 20m
	rekeymargin = 3m
	keyingtries = 1
	keyexchange = ikev2
	mobike = no
	ike = aes256gcm16-prfsha384-ecp384,aes128gcm16-prfsha256-ecp256!
	esp = aes128gcm16-ecp256!
#	esp = aes256gcm16-ecp384,aes128gcm16-ecp256!

conn ula-net-vps4
	left = %any
	leftsubnet = fdd7:5938:e2e6:1::/64,fdd7:5938:e2e6:3::1/128
	leftcert = /etc/ssl/home.johncook.co.uk/home_johncook_co_uk.chained.pem
	leftauth = pubkey
	leftid = @home.johncook.co.uk
	leftsendcert = always
	leftfirewall = yes
	right = 185.133.75.14
	rightsubnet = fdd7:5938:e2e6:8e71::/64,fdd7:5938:e2e6:3::8e71/128
	rightauth = pubkey
	rightid = @vps4.johncook.co.uk
	auto = route
	type = tunnel

The esp setting in the above configuration has the weaker cipher only because Debian Jessie has trouble with aes256gcm16-ecp384. When Debian Stretch comes out (or the kernel gets a bump) I'll try the stronger cipher.

Create symbolic links to the Let's Encrypt intermediates and root certificates:

cd /etc/ipsec.d/cacerts
sudo ln -s /etc/ssl/certs/DST_Root_CA_X3.pem DST_Root_CA_X3.pem
sudo ln -s /etc/ssl/LetsEncrypt/isrgrootx1.pem isrgrootx1.pem
sudo ln -s /etc/ssl/LetsEncrypt/lets-encrypt-x3-cross-signed.pem lets-encrypt-x3-cross-signed.pem
sudo ln -s /etc/ssl/LetsEncrypt/lets-encrypt-x4-cross-signed.pem lets-encrypt-x4-cross-signed.pem

Tell strongSwan about the private key:

sudo nano /etc/ipsec.secrets
: ECDSA /etc/ssl/home.johncook.co.uk/home_johncook_co_uk.key1

Reload the configuration and re-read everything:

sudo ipsec reload
sudo ipsec rereadall

Configure Firewalls

Add the following to the iptables.save/iptables.bak file, and then reload the rules using iptables-restore:

### IPsec ###
#
-A INPUT -m policy --dir in --pol ipsec --mode tunnel -j ACCEPT
-A OUTPUT -m policy --dir out --pol ipsec --mode tunnel -j ACCEPT
# ESP encrypton and authentication
-A INPUT  -p 50 -j ACCEPT
-A OUTPUT -p 50 -j ACCEPT
# uncomment for AH authentication header
# -A INPUT  -p 51 -j ACCEPT
# -A OUTPUT -p 51 -j ACCEPT
# IKE negotiations
-A INPUT  -p udp --sport 500 --dport 500 -j ACCEPT
-A OUTPUT -p udp --sport 500 --dport 500 -j ACCEPT
# NAT-T
-A INPUT -p udp --sport 4500 --dport 4500 -j ACCEPT
-A OUTPUT -p udp --sport 4500 --dport 4500 -j ACCEPT

Based on my understanding of IPsec in ESP tunnel mode, the above firewall rules are needed for the following reasons (OUTPUT rules listed in case of egress filtering).

  • An ipsec policy rule so IPsec traffic (after decryption/before encryption) is accepted in/out. In the above this is a placeholder policy, and doesn't appear to ever get matched.
  • Allow protocol 50 (ESP) traffic in and out. These are the encrypted packets. After decryption (on INPUT) they are injected back into INPUT. An ICMPv6 packet in my setup, for example, would hit the ESP rule and get decrypted. The decapsulated packet (being an IPv6 packet) would then get processed by the ip6tables rules, hitting my ICMPv6 rule. These rules could be tightened (for example, to limit permitted IP addresses).
  • The UDP port 500 (IKE) rules allow the IKEv2 SA to be setup, and for reauthentication to occur. As with the ESP rules, these could be tightened up.
  • The UDP port 4500 (NAT-T) rules allow IPsec packets to pass through (traverse) NAT. This only works with ESP, not AH or ESP+AH, because NAT changes the IP header. I will probably cover this in more detail in a later article if I decide to look at opportunistic IPsec.

Adding IP Addresses

Before being able to test connectivity between servers, I need to add an IP address to an interface on VPS4 that is in one of the left side subnets.

sudo ip addr add fdd7:5938:e2e6:3::8e71 dev eth0
sudo nano /etc/network/interfaces

Add the following to eth0:

up ip addr add fdd7:5938:e2e6:3::8e71/128 dev eth0

ICMPv6 Ping Test

If everything is configured properly, then pinging from either server should result in the IPsec connection coming up. On home:

sudo ipsec down ula-net-vps4
ping6 -c4 fdd7:5938:e2e6:3::8e71
PING fdd7:5938:e2e6:3::8e71(fdd7:5938:e2e6:3::8e71) 56 data bytes
64 bytes from fdd7:5938:e2e6:3::8e71: icmp_seq=2 ttl=64 time=19.3 ms
64 bytes from fdd7:5938:e2e6:3::8e71: icmp_seq=3 ttl=64 time=17.8 ms
64 bytes from fdd7:5938:e2e6:3::8e71: icmp_seq=4 ttl=64 time=16.8 ms

--- fdd7:5938:e2e6:3::8e71 ping statistics ---
4 packets transmitted, 3 received, 25% packet loss, time 3001ms
rtt min/avg/max/mdev = 16.833/17.998/19.306/1.026 ms

Some packet loss is to be expected if the connection wasn't already up, but as long as packet loss isn't 100% the connection is working. You can double check the connection is active by looking at sudo ipsec statusall for lines similar to the following:

ula-net-vps4{2}:  INSTALLED, TUNNEL, ESP SPIs: cbaf4f0f_i cdaca48d_o
ula-net-vps4{2}:  AES_CBC_128/AES_XCBC_96, 312 bytes_i (3 pkts, 143s ago), 312 bytes_o (3 pkts, 143s ago), rekeying in 12 minutes
ula-net-vps4{2}:   fdd7:5938:e2e6:1::/64 fdd7:5938:e2e6:3::1/128 === fdd7:5938:e2e6:8e71::/64 fdd7:5938:e2e6:3::8e71/128

The first line gives the ESP SPIs for ula-net-vps4. The second says what ciphers are being used for the ESP tunnel, and the third line says what subnets are on the left and right sides of that tunnel.

ipsec.conf has the following options for auto=:

  • auto=start automatically brings up the IPsec connection when ipsec/strongswan starts. If the connection goes down it might not reconnect automatically.
  • auto=route automatically brings up the IPsec connection when a packet needs to be routed to the other side of the tunnel. Might take some time to come up resulting in packet loss (connectionless, e.g. ICMP and UDP) and/or latency (connection oriented, e.g. TCP) for quite a few milliseconds/seconds.
  • auto=add automatically loads the connection when ipsec/strongswan starts. You have to manually bring up the connection.
  • auto=ignore causes ipsec/strongswan to ignore the connection. This is equivalent to the connection being commenting out in, or deleted from, the configuration file.

Site-to-Site Only

The reason I am currently only using a site-to-site tunnel is because I am, for the time being, only interested in securing my IPv6 ULA network.

In other words, all traffic between addresses in certain subnets of my ULA prefix are treated as if they are on the same LAN.

VPS3, VPS5, and VPS6

I am not going to be using IPsec on VPS3 because I haven't been able to get it to work in Ubuntu Trusty.

Having now transitioned everything to VPS4 (more articles will likely follow detailing some of the steps), I am transitioning VPS3 to a new DireVPS VPS (VPS5) which I will use IPsec on.

I am also looking at adding a third VPS (VPS6), which will preferably be located somewhere that reduces latency to the US and Canada (preferably located in Canada) but that will require some further research.

While I can do round-robin DNS load balancing using NSD4, I can't do geo-dns (serving different DNS responses based on the client's geo-located IP address) because NSD4 can't do split-horizon DNS. Until I work out how I could do it, there is not point getting a non-UK VPS.