IPsec with Libreswan
Libreswan is a free software implementation of the most widely supported and standardized VPN protocol, IPsec.
On Android, the arrangement in this particular tutorial is called “IPsec XAUTH PSK.” On iOS, it is called simply “IPsec.”
IPsec uses fixed port numbers and is therefore easily blocked by censors. Nevertheless, there may be situations where ease-of-use is your top priority. Many client devices support IPsec without the installation of additional software.
This article shows you how to create an IPsec server on CentOS 8. Note that CentOS 8 goes end-of-life on December 31, 2021. For this reason, we include appendices discussing Debian/Ubuntu.
In the examples, your workstation is at IP address xx.xx.xx.xx
, and the server is at IP address yy.yy.yy.yy
. Wherever you see these values in the examples, you will need to change them to match your actual IP addresses. If you do not know your workstation’s IP address, you can determine it by opening a browser and visiting IPchicken.com.
We also give instructions for a sample mobile client. Mobile devices are easily tracked and strongly linked to an individual. Again, we assume in this scenario that ease-of-use is your main concern and that you are in a country where IPsec is not blocked.
1. Server
1.1. Install and Configure Firewall
We begin by installing a firewall and configuring it to accept IPsec. We also masquerade outgoing IP addresses. Issue the commands that follow:
yum update -y
yum install firewalld -y
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --add-service=ipsec
firewall-cmd --add-masquerade
firewall-cmd --runtime-to-permanent
For better security, restrict port 22 access to trusted IP addresses only. For example, if you always log in from IP address xx.xx.xx.xx
, make that the only IP address that will be trusted for SSH access:
firewall-cmd --zone=trusted --add-service=ssh
firewall-cmd --zone=trusted --add-source=xx.xx.xx.xx/32
firewall-cmd --zone=public --remove-service=ssh
firewall-cmd --zone=public --remove-service=cockpit
firewall-cmd --runtime-to-permanent
1.2. Allow Forwarding
Now enable packet forwarding in the Linux kernel. Create a new configuration file in /usr/lib/sysctl.d
:
vi /usr/lib/sysctl.d/40-ipv4-forward.conf
Insert a single line:
net.ipv4.ip_forward=1
Save the file. Make this change effective immediately.:
sysctl -p /usr/lib/sysctl.d/40-ipv4-forward.conf
1.3. Install Package
Install Libreswan from the repository:
yum install libreswan -y
1.4. Set Up Preshared Key
Edit the IPsec secrets file:
vi /etc/ipsec.d/psk.secrets
Insert a line with your preshared key. We will use as an example a preshared key of ArnieBooksCello
:
%any: PSK "ArnieBooksCello"
Save the file.
1.5. Set Up Usernames and Passwords
Suppose we have three users, alice
, bob
, and carol
. Their passwords are Apple123
, Bravo456
, and Caper789
respectively.
Compute the SHA512 hash of the first password:
openssl passwd -6 Apple123
The result is displayed as $6$/X60NLa1wFgWDYIC$PYsPW.lsCALxSgRi0NmKcLVJPY.tPZwRZIs9OoYy3o/KimObc9GKkVfkpzhaA/jxM15eW.F6AcFqYdElsuJoO.
.
Compute the SHA512 hash of the second password:
openssl passwd -6 Bravo456
The result is displayed as $6$U7Z3b.871AFnz6M8$lUB18T5gwQS/yPxjPqeNbUNCWpDsCHxmRNZy6dURpEc6cteX8NwBSB4HboNMTer/a642XadEv.T3ses8c33Y3/
.
Compute the SHA512 hash of the third password:
openssl passwd -6 Caper789
The result is displayed as $6$hbiPDOhJPoEBpAN2$IsKhAZvKLMuuICDafbkW5STmsBhC7HuWNZwmJ/l2z7CzcQbZNoie5i0ye5Lpusz43JEbhQR9.jR6In1yWyw1N0
.
Create a password file:
vi /etc/ipsec.d/passwd
Insert usernames and passwords like this:
alice:$6$/X60NLa1wFgWDYIC$PYsPW.lsCALxSgRi0NmKcLVJPY.tPZwRZIs9OoYy3o/KimObc9GKkVfkpzhaA/jxM15eW.F6AcFqYdElsuJoO.:xauth-psk bob:$6$U7Z3b.871AFnz6M8$lUB18T5gwQS/yPxjPqeNbUNCWpDsCHxmRNZy6dURpEc6cteX8NwBSB4HboNMTer/a642XadEv.T3ses8c33Y3/:xauth-psk carol:$6$hbiPDOhJPoEBpAN2$IsKhAZvKLMuuICDafbkW5STmsBhC7HuWNZwmJ/l2z7CzcQbZNoie5i0ye5Lpusz43JEbhQR9.jR6In1yWyw1N0:xauth-psk
Save the file.
1.6. Configure Libreswan
Create a new file for IPsec connections with a preshared key:
vi /etc/ipsec.d/ipsec.conf
Insert lines specifying a configuration like this:
config setup protostack=netkey virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12 uniqueids=no conn xauth-psk authby=secret pfs=no auto=add rekey=no left=%defaultroute leftsubnet=0.0.0.0/0 rightaddresspool=10.0.8.64-10.0.8.127 right=%any cisco-unity=yes modecfgdns=8.8.8.8 leftxauthserver=yes rightxauthclient=yes leftmodecfgserver=yes rightmodecfgclient=yes modecfgpull=yes xauthby=file ike-frag=yes ikev2=no ike=aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024 esp=aes256-sha2_512,aes256-sha1,aes256-sha2_256,3des-sha1
Save the file.
1.7. Start Libreswan
Start Libreswan after every reboot, and also start it now:
systemctl enable ipsec
systemctl start ipsec
1.8. Check Libreswan
Check that Libreswan is active and running:
systemctl status ipsec
2. Android Client
The place where you add a VPN in Android varies from release to release. It may be under Settings > Network & Internet > Advanced > VPN or it may be under Settings > Connections > More networks > VPN.
Add a new VPN:
- Name is whatever you want, e.g.
yy.yy.yy.yy
- Type is IPsec XAUTH PSK
- Server address in our example is
yy.yy.yy.yy
- IPsec identifier is blank
- IPsec pre-shared key is
ArnieBooksCello
in our example - Username is
alice
- Password is
Apple123
Click Save. Select the VPN, and click Connect.
3. iOS Client
Go to Settings > General > VPN.
Add a new VPN configurration:
- Type is IPsec
- Description is whatever you want, e.g.
yy.yy.yy.yy
- Server in our example is
yy.yy.yy.yy
- Account is
alice
- Password is
Apple123
- Use Certificate is off
- Group Name is blank
- Secret is
ArnieBooksCello
in our example
Click Done. Select the VPN, and toggle it to the ON position.
4. Get Help and Report Issues
Examine the logs with:
grep pluto /var/log/secure
For your client device in general, seek support through the normal channels for that device.
For Libreswan, support arrangements are listed in the Libreswan wiki.
Appendix A. Notes for Debian/Ubuntu
Appendix A.1. Nftables Firewall for Debian/Ubuntu
A firewall for IPsec may be built with nftables
as follows, with xx.xx.xx.xx
representing your workstation’s IP address.
Install nftables
:
apt install nftables -y
systemctl enable nftables
systemctl start nftables
Set up the basic rules:
nft add rule inet filter input ct state related,established counter accept
nft add rule inet filter input iif lo counter accept
nft add rule inet filter input ip protocol icmp icmp type echo-request counter accept
nft add rule inet filter input ip6 nexthdr icmpv6 icmpv6 type echo-request counter accept
Open port 22
for SSH. If you can restrict the port 22
rule so that only certain source IP addresses are whitelisted for SSH access, then so much the better.
nft add rule inet filter input t***** dport 22 ip saddr xx.xx.xx.xx/32 counter accept
Open ports 500/udp
and 4500/udp
and protocols 50
and 51
for IPsec:
nft add rule inet filter input udp dport 500 counter accept
nft add rule inet filter input udp dport 4500 counter accept
nft add rule inet filter input ip protocol ah counter accept
nft add rule inet filter input ip protocol esp counter accept
Drop all unexpected input:
nft add rule inet filter input counter drop
Masquerade outgoing IP addresses:
nft add table nat
nft add chain nat prerouting { type nat hook prerouting priority 0 \; }
nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
nft add rule nat postrouting ip saddr 10.0.8.64/26 masquerade
Save all these rules so that they persist across reboots:
nft list ruleset > /etc/nftables.conf
Appendix A.2. Allow Forwarding on Debian/Ubuntu
On Debian/Ubuntu you create your sysctl
configuration file in /etc/sysctl.d
:
vi /etc/sysctl.d/40-ipv4-forward.conf
Insert a single line:
net.ipv4.ip_forward=1
Save the file. Make this change effective immediately.:
sysctl -p /etc/sysctl.d/40-ipv4-forward.conf
Appendix A.3. MODP1024 on Debian/Ubuntu
Libreswan version 3.30 (February 13, 2020) disabled support for DH2/modp1024 at compile time. Ubuntu 20.04 was the last release to include Libreswan 3.29; Debian 10 “buster” included Libreswan 3.27.
The problem is that some Windows and Android devices still require modp1024 to work.
On Ubuntu 20.10+ and Debian 11+ your choices are therefore:
- Compile Libreswan 3.29 from source; or
- Compile a more recent Libreswan from source defining
USE_DH2
at compile time
A sample compile procedure for Libreswan on Debian/Ubuntu is as follows.
Install the prerequisites for the compile:
apt update && apt upgrade -y
apt install -y libnss3-dev libnspr4-dev pkg-config libpam-dev libcap-ng-dev libcap-ng-utils libselinux-dev libcurl3-nss-dev flex bison gcc make libldns-dev libunbound-dev libnss3-tools libevent-dev xmlto libsystemd-dev
Visit https://download.libreswan.org to determine which release you want to use. We will use release 4.4 as our example. Download the source tarball.
wget https://download.libreswan.org/libreswan-4.4.tar.gz
Extract the tarball:
tar -xf libreswan-4.4.tar.gz
Change into the top-level directory for the source:
cd libreswan-4.4
Build Libreswan with USE_DH2
defined:
make CFLAGS="-DUSE_DH2"
Install Libreswan:
make install
If you are going to use the certificate utility certutil
, then initialize the Network Security Services (NSS) database:
ipsec initnss
The NSS database is created in /var/lib/ipsec/nss
.
Configure your server’s firewall as described in appendix A.1 above to accept protocol 50
, protocol 51
, input 500/udp
and 4500/udp
, and also to masquerade the IP address on outbound packets.
Allow forwarding in the Linux kernel as in described in appendix A.2 above.
Set up your parameter files in the /etc/ipsec.d
directory, as explained in the sections for CentOS 8, except that in /etc/ipsec.d/ipsec.conf
the parameter ike-frag=yes
has now been replaced by fragmentation=yes
:
- Set up your secrets file as described in section 1.4 above, for example in
/etc/ipsec.d/psk.secrets
- Set up your password file as described in section 1.5 above, for example
/etc/ipsec.d/passwd
- Set up your secretsConfiguration file as described in section 1.6 above, for example in
/etc/ipsec.d/ipsec.conf
Once you’ve set everything up, start Libreswan:
systemctl start ipsec
Appendix A.4. Libreswan Log on Debian/Ubuntu
On Debian/Ubuntu, examine the logs with:
grep pluto /var/log/auth.log
Updated 2021-06-17