For a Site-to-site VPN tunnel from a cloud service (for example, Azure) to the local on-premise network, a Libreswan Virtual private network (VPN) router with Internet Protocol Security (IPsec) can be used.
In Red Hat Enterprise Linux 8 (RHEL 8), a virtual private network (VPN) can be configured using the IPsec protocol, which is supported by the Libreswan application. Some information pages about VPN setups:
Setting up a VPN router to GCP is discussed in the page A libreswan configuration that works with Google Cloud VPN (Classic).
Install the Libreswan package by:
dnf install libreswan
There are some Libreswan examples:
If your organization has a firewall device protecting your external (Internet faced) network perimeter, it is necessary to configure that firewall to allow 500 and 4500/UDP ports for the IKE (defined in RFC7296), ESP (defined in RFC4303), and AH (not used) protocols bidirectionally to and from the remote cloud service:
IP UDP Port 500 IP UDP Port 4500 ESP protocol 50
Configuration files are created in the
/etc/ipsec.d/ directory and should be named for each VPN tunnel (here
First create the file
conn azure authby=secret auto=start dpdaction=restart dpddelay=30 dpdtimeout=120 ike=aes256-sha1;modp1024 ikelifetime=3600s pfs=yes esp=aes128-sha1 salifetime=3600s
Some parameters will then take their default values which you should not modify, see
Important defaults are:
encapsulation=auto (forceencaps is obsoleted)
Local VPN gateway public address: 188.8.131.52
Azure VPN gateway public address: 184.108.40.206
Add your specific IP-addresses and subnets after the
conn parameter in the above file
/etc/ipsec.d/azure.conf (the values here are just examples!):
conn azure left=220.127.116.11 # Local VPN gateway public address leftsubnet=10.2.0.0/16 # Local subnet leftsourceip=10.2.0.1 # Local VPN gateway on the local private subnet right=18.104.22.168 # Azure VPN gateway public address rightsubnet=10.0.0.0/16 # Azure subnet ....
leftsourceip is relevant only locally, and the other end need not agree.
This option is used to make the gateway itself use its internal IP, which is part of the leftsubnet, to communicate to the rightsubnet or right.
You may use the output from one of these Linux commands (see Generate a strong pre-shared key):
openssl rand -base64 24 head -c 24 /dev/urandom | base64
Now create the file
/etc/ipsec.d/azure.secrets (the values here are just examples!):
22.214.171.124 126.96.36.199 : PSK "mEEVg4KXSl5nFJk3yDZbSj7wTNN5wxFt"
The PSK value should be enclosed in quotes (”) as shown.
The value %any signifies an IP-address to be filled in (by automatic keying) during negotiation, see the ipsec.secrets manual page:
%any %any : PSK "mEEVg4KXSl5nFJk3yDZbSj7wTNN5wxFt"
Make sure the file is only readable by root:
chmod 0600 /etc/ipsec.d/azure.secrets
Now you may enable, start and check the ipsec service:
systemctl enable ipsec --now systemctl status ipsec
Verify and view the IPsec connections status by:
ipsec verify ipsec status
If there are errors from the status command you should examine the
You can also try this command:
ipsec pluto --config /etc/ipsec.conf --nofork
If the encryption methods are mismatched, look for lines like this one:
no local proposal matches remote proposals 1:IKE:ENCR=AES_CBC_256;INTEG=HMAC_SHA1_96;PRF=HMAC_SHA1;DH=MODP1024 2:IKE:ENCR=AES_CBC_256;INTEG=HMAC_SHA2_256_128;PRF=HMAC_SHA2_256;DH=MODP1024 3:IKE:ENCR=AES_CBC_128;INTEG=HMAC_SHA1_96;PRF=HMAC_SHA1;DH=MODP1024 4:IKE:ENCR=AES_CBC_128;INTEG=HMAC_SHA2_256_128;PRF=HMAC_SHA2_256;DH=MODP1024 5:IKE:ENCR=3DES;INTEG=HMAC_SHA1_96;PRF=HMAC_SHA1;DH=MODP1024 6:IKE:ENCR=3DES;INTEG=HMAC_SHA2_256_128;PRF=HMAC_SHA2_256;DH=MODP1024
In this case replace the above
ike= line by one of the options, for example:
and restart the
Add the local IP subnet (10.2.0.0/16 in the present example) to firewalld_trusted_zone:
firewall-cmd --zone=trusted --add-source=10.2.0.0/16
Make these changes permanent:
List the contents of the firewalld_trusted_zone:
firewall-cmd --zone=trusted --list-all
The Reverse Path Forwarding filtering subsystem related to IP spoofing protection must be turned off on both gateways for IPSEC to work properly, see:
The most simple way to disable the strict check is to set the sysctl net.ipv4.conf.all.rp_filter=2 (loose) as this will override the interface-specific settings. Setting net.ipv4.conf.all.rp_filter=0 (disabled) does not override interface-specific settings so is not recommended.
(See also this LibreSwan FAQ)
Add this in
Now reload sysctl:
For those hosts on the on-premise network that need to send IP traffic to the cloud nodes through the VPN tunnel gateway, you have to add a route command, for example:
ip route add 10.0.0.0/16 via 10.2.0.1
where 10.2.0.1 is the VPN gateway’s local IP address and 10.0.0.0/16 is the IP subnet in the cloud service. This configuration will disappear when the host is rebooted.
To make manual routes persistent across reboots on EL8 hosts, you could add the above command to the
Remember to make it executable:
chmod +x /etc/rc.local
Another method is to determine the interface which the host uses to send traffic to the gateway (10.2.0.1 in the above example). Assume the interface name is eno49.
Configure the routing file for the
ADDRESS0=10.0.0.0 NETMASK0=255.255.0.0 GATEWAY0=10.2.0.1
Then update the NetworkManager:
nmcli device reapply eno49
and check the routes with:
Perhaps it may be necessary to reboot the server.
Optional information about some IPsec commands:
Libreswan uses a local database to keep track of authentication keys and identity certificates, so initialize the key database on each computer:
Check the current CKAID keys:
ipsec showhostkey --list
If no keys exist, generate a CKAID key for each machine (see
ipsec newhostkey ipsec showhostkey --list