4.6. Securing Virtual Private Networks (VPNs)

In Red Hat Enterprise Linux 7, a Virtual Private Network (VPN) can be configured using the IPsec tunneling protocol which is supported by the Libreswan application. Libreswan is a fork of the Openswan application and examples in documentation should be interchangeable. The NetworkManager IPsec plug-in is called NetworkManager-libreswan. Users of GNOME Shell should install the NetworkManager-libreswan-gnome package, which has NetworkManager-libreswan as a dependency. Note that the NetworkManager-libreswan-gnome package is only available from the Optional channel. See Enabling Supplementary and Optional Repositories.
Libreswan is an open-source, user-space IPsec implementation available in Red Hat Enterprise Linux 7. It uses the Internet Key Exchange (IKE) protocol. IKE version 1 and 2 are implemented as a user-level daemon. Manual key establishment is also possible through ip xfrm commands, however this is not recommended. Libreswan interfaces with the Linux kernel using netlink to transfer the encryption keys. Packet encryption and decryption happen in the Linux kernel.
Libreswan uses the Network Security Services (NSS) cryptographic library, which is required for Federal Information Processing Standard (FIPS) security compliance.

Important

IKE/IPsec, implemented by Libreswan, is the only VPN technology recommended for use in Red Hat Enterprise Linux 7. Do not use any other VPN technology without understanding the risks of doing so.

4.6.1. IPsec VPN Using Libreswan

To install Libreswan, issue the following command as root:
~]# yum install libreswan
To check that Libreswan is installed, issue the following command:
~]$ yum info libreswan
After a new installation of Libreswan the NSS database should be initialized as part of the install process. However, should you need to start a new database, first remove the old database as follows:
~]# rm /etc/ipsec.d/*db
Then, to initialize a new NSS database, issue the following command as root:
~]# ipsec initnss
Initializing NSS database
See 'man pluto' if you want to protect the NSS database with a password
If you do not want to use a password for NSS, just press Enter twice when prompted for the password. If you do enter a password then you will have to re-enter it every time Libreswan is started, such as every time the system is booted.
To start the ipsec daemon provided by Libreswan, issue the following command as root:
~]# systemctl start ipsec
To confirm that the daemon is now running:
~]$ systemctl status ipsec
ipsec.service - Internet Key Exchange (IKE) Protocol Daemon for IPsec
   Loaded: loaded (/usr/lib/systemd/system/ipsec.service; disabled)
   Active: active (running) since Wed 2013-08-21 12:14:12 CEST; 18s ago
To ensure that Libreswan will start when the system starts, issue the following command as root:
~]# systemctl enable ipsec
Configure any intermediate as well as host-based firewalls to permit the ipsec service. See Chapter 5, Using Firewalls for information on firewalls and allowing specific services to pass through. Libreswan requires the firewall to allow the following packets:
  • UDP port 500 for the Internet Key Exchange (IKE) protocol
  • UDP port 4500 for IKE NAT-Traversal
  • Protocol 50 for Encapsulated Security Payload (ESP) IPsec packets
  • Protocol 51 for Authenticated Header (AH) IPsec packets (uncommon)
We present three examples of using Libreswan to set up an IPsec VPN. The first example is for connecting two hosts together so that they may communicate securely. The second example is connecting two sites together to form one network. The third example is supporting remote users, known as road warriors in this context.

4.6.2. VPN Configurations Using Libreswan

Libreswan does not use the terms source or destination. Instead, it uses the terms left and right to refer to end points (the hosts). This allows the same configuration to be used on both end points in most cases, although most administrators use left for the local host and right for the remote host.
There are three commonly used methods for authentication of endpoints:
  • Pre-Shared Keys (PSK) is the simplest authentication method. PSK's should consist of random characters and have a length of at least 20 characters.
  • Raw RSA keys are commonly used for static host-to-host or subnet-to-subnet IPsec configurations. The hosts are manually configured with each other's public RSA key. This method does not scale well when dozens or more hosts all need to setup IPsec tunnels to each other.
  • X.509 certificates are commonly used for large scale deployments where there are many hosts that need to connect to a common IPsec gateway. A central certificate authority (CA) is used to sign RSA certificates for hosts or users. This central CA is responsible for relaying trust, including the revocations of individual hosts or users.

4.6.3. Host-To-Host VPN Using Libreswan

To configure Libreswan to create a host-to-host IPsec VPN, between two hosts referred to as left and right, enter the following commands as root on both of the hosts (left and right) to create new raw RSA key pairs:
~]# ipsec newhostkey --configdir /etc/ipsec.d \
--output /etc/ipsec.d/www.example.com.secrets
Generated RSA key pair using the NSS database
This generates an RSA key pair for the host. The process of generating RSA keys can take many minutes, especially on virtual machines with low entropy.
To view the public key, issue the following command as root on either of the hosts. For example, to view the public key on the left host, run:
~]# ipsec showhostkey --left
ipsec showhostkey loading secrets from "/etc/ipsec.secrets"
ipsec showhostkey loading secrets from "/etc/ipsec.d/www.example.com.secrets"
ipsec showhostkey loaded private key for keyid: PPK_RSA:AQOjAKLlL
	# rsakey AQOjAKLlL
	leftrsasigkey=0sAQOjAKLlL4a7YBv [...]
You will need this key to add to the configuration file as explained below.
The secret part is stored in /etc/ipsec.d/*.db files, also called the NSS database.
To make a configuration file for this host-to-host tunnel, the lines leftrsasigkey= and rightrsasigkey= from above, are added to a custom configuration file placed in the /etc/ipsec.d/ directory.
Using an editor running as root, create a file with a suitable name in the following format:
/etc/ipsec.d/my_host-to-host.conf
Edit the file as follows:
conn mytunnel
    leftid=@west.example.com
    left=192.1.2.23
    leftrsasigkey=0sAQOrlo+hOafUZDlCQmXFrje/oZm [...] W2n417C/4urYHQkCvuIQ==
    rightid=@east.example.com
    right=192.1.2.45
    rightrsasigkey=0sAQO3fwC6nSSGgt64DWiYZzuHbc4 [...] D/v8t5YTQ==
    authby=rsasig
    # load and initiate automatically
    auto=start
You can use the identical configuration file on both left and right hosts. They will auto-detect if they are left or right. If one of the hosts is a mobile host, which implies the IP address is not known in advance, then on the mobile host use %defaultroute as its IP address. This will pick up the dynamic IP address automatically. On the static host that accepts connections from incoming mobile hosts, specify the mobile host using %any for its IP address.
Ensure the leftrsasigkey value is obtained from the left host and the rightrsasigkey value is obtained from the right host.
Restart ipsec to ensure it reads the new configuration:
~]# systemctl restart ipsec
When using the auto=start option, the IPsec tunnel should be established within a few seconds. You can manually load and start the tunnel by entering the following commands as root:
~]# ipsec auto --add mytunnel
~]# ipsec auto --up mytunnel

4.6.3.1. Verify Host-To-Host VPN Using Libreswan

The IKE negotiation takes place on UDP port 500 and when a NAT is detected on UDP port 4500. IPsec packets show up as Encapsulated Security Payload (ESP) packets. The ESP protocol has no ports. When the VPN connection needs to pass through a NAT router, the ESP packets are encapsulated in UDP packets on port 4500.
To verify that packets are being sent through the VPN tunnel, issue a command as root in the following format:
~]# tcpdump -n -i interface esp or udp port 500 or udp port 4500
00:32:32.632165 IP 192.1.2.45 > 192.1.2.23: ESP(spi=0x63ad7e17,seq=0x1a), length 132
00:32:32.632592 IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x4841b647,seq=0x1a), length 132
00:32:32.632592 IP 192.0.2.254 > 192.0.1.254: ICMP echo reply, id 2489, seq 7, length 64
00:32:33.632221 IP 192.1.2.45 > 192.1.2.23: ESP(spi=0x63ad7e17,seq=0x1b), length 132
00:32:33.632731 IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x4841b647,seq=0x1b), length 132
00:32:33.632731 IP 192.0.2.254 > 192.0.1.254: ICMP echo reply, id 2489, seq 8, length 64
00:32:34.632183 IP 192.1.2.45 > 192.1.2.23: ESP(spi=0x63ad7e17,seq=0x1c), length 132
00:32:34.632607 IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x4841b647,seq=0x1c), length 132
00:32:34.632607 IP 192.0.2.254 > 192.0.1.254: ICMP echo reply, id 2489, seq 9, length 64
00:32:35.632233 IP 192.1.2.45 > 192.1.2.23: ESP(spi=0x63ad7e17,seq=0x1d), length 132
00:32:35.632685 IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x4841b647,seq=0x1d), length 132
00:32:35.632685 IP 192.0.2.254 > 192.0.1.254: ICMP echo reply, id 2489, seq 10, length 64
Where interface is the interface known to carry the traffic. To end the capture with tcpdump, press Ctrl+C.

Note

The tcpdump commands interacts a little unexpectedly with IPsec. It only sees the outgoing encrypted packet, not the outgoing plaintext packet. It does see the encrypted incoming packet, as well as the decrypted incoming packet. If possible, run tcpdump on a router between the two machines and not on one of the endpoints itself. When using the Virtual Tunnel Interface (VTI), the physical interface shows ESP packets, while the VTI interface shows the cleartext traffic.

4.6.4. Site-to-Site VPN Using Libreswan

In order for Libreswan to create a site-to-site IPsec VPN, joining together two networks, an IPsec tunnel is created between two hosts, endpoints, which are configured to permit traffic from one or more subnets to pass through. They can therefore be thought of as gateways to the remote portion of the network. The configuration of the site-to-site VPN only differs from the host-to-host VPN in that one or more networks or subnets must be specified in the configuration file.
To configure Libreswan to create a site-to-site IPsec VPN, first configure a host-to-host IPsec VPN as described in Section 4.6.3, “Host-To-Host VPN Using Libreswan” and then copy or move the file to a file with a suitable name, such as /etc/ipsec.d/my_site-to-site.conf. Using an editor running as root, edit the custom configuration file /etc/ipsec.d/my_site-to-site.conf as follows:
conn mysubnet
     also=mytunnel
     leftsubnet=192.0.1.0/24
     rightsubnet=192.0.2.0/24

conn mysubnet6
     also=mytunnel
     connaddrfamily=ipv6
     leftsubnet=2001:db8:0:1::/64
     rightsubnet=2001:db8:0:2::/64

conn mytunnel
    auto=start
    leftid=@west.example.com
    left=192.1.2.23
    leftrsasigkey=0sAQOrlo+hOafUZDlCQmXFrje/oZm [...] W2n417C/4urYHQkCvuIQ==
    rightid=@east.example.com
    right=192.1.2.45
    rightrsasigkey=0sAQO3fwC6nSSGgt64DWiYZzuHbc4 [...] D/v8t5YTQ==
    authby=rsasig
To bring the tunnels up, restart Libreswan or manually load and initiate all the connections using the following commands as root:
~]# ipsec auto --add mysubnet
~]# ipsec auto --add mysubnet6
~]# ipsec auto --add mytunnel
~]# ipsec auto --up mysubnet
104 "mysubnet" #1: STATE_MAIN_I1: initiate
003 "mysubnet" #1: received Vendor ID payload [Dead Peer Detection]
003 "mytunnel" #1: received Vendor ID payload [FRAGMENTATION]
106 "mysubnet" #1: STATE_MAIN_I2: sent MI2, expecting MR2
108 "mysubnet" #1: STATE_MAIN_I3: sent MI3, expecting MR3
003 "mysubnet" #1: received Vendor ID payload [CAN-IKEv2]
004 "mysubnet" #1: STATE_MAIN_I4: ISAKMP SA established {auth=OAKLEY_RSA_SIG cipher=aes_128 prf=oakley_sha group=modp2048}
117 "mysubnet" #2: STATE_QUICK_I1: initiate
004 "mysubnet" #2: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP=>0x9414a615 <0x1a8eb4ef xfrm=AES_128-HMAC_SHA1 NATOA=none NATD=none DPD=none}
~]# ipsec auto --up mysubnet6
003 "mytunnel" #1: received Vendor ID payload [FRAGMENTATION]
117 "mysubnet" #2: STATE_QUICK_I1: initiate
004 "mysubnet" #2: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP=>0x06fe2099 <0x75eaa862 xfrm=AES_128-HMAC_SHA1 NATOA=none NATD=none DPD=none}
~]# ipsec auto --up mytunnel
104 "mytunnel" #1: STATE_MAIN_I1: initiate
003 "mytunnel" #1: received Vendor ID payload [Dead Peer Detection]
003 "mytunnel" #1: received Vendor ID payload [FRAGMENTATION]
106 "mytunnel" #1: STATE_MAIN_I2: sent MI2, expecting MR2
108 "mytunnel" #1: STATE_MAIN_I3: sent MI3, expecting MR3
003 "mytunnel" #1: received Vendor ID payload [CAN-IKEv2]
004 "mytunnel" #1: STATE_MAIN_I4: ISAKMP SA established {auth=OAKLEY_RSA_SIG cipher=aes_128 prf=oakley_sha group=modp2048}
117 "mytunnel" #2: STATE_QUICK_I1: initiate
004 "mytunnel" #2: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP=>0x9414a615 >0x1a8eb4ef xfrm=AES_128-HMAC_SHA1 NATOA=none NATD=none DPD=none}

4.6.4.1. Verify Site-to-Site VPN Using Libreswan

Verifying that packets are being sent through the VPN tunnel is the same procedure as explained in Section 4.6.3.1, “Verify Host-To-Host VPN Using Libreswan”.

4.6.5. Site-to-Site Single Tunnel VPN Using Libreswan

Often, when a site-to-site tunnel is built, the gateways need to communicate with each other using their internal IP addresses instead of their public IP addresses. This can be accomplished using a single tunnel. If the left host, with host name west, has internal IP address 192.0.1.254 and the right host, with host name east, has internal IP address 192.0.2.254, the following configuration using a single tunnel can be used:
conn mysubnet
    leftid=@west.example.com
    leftrsasigkey=0sAQOrlo+hOafUZDlCQmXFrje/oZm [...] W2n417C/4urYHQkCvuIQ==
    left=192.1.2.23
    leftsourceip=192.0.1.254
    leftsubnet=192.0.1.0/24
    rightid=@east.example.com
    rightrsasigkey=0sAQO3fwC6nSSGgt64DWiYZzuHbc4 [...] D/v8t5YTQ==
    right=192.1.2.45
    rightsourceip=192.0.2.254
    rightsubnet=192.0.2.0/24
    auto=start
    authby=rsasig

4.6.6. Subnet Extrusion Using Libreswan

IPsec is often deployed in a hub-and-spoke architecture. Each leaf node has an IP range that is part of a larger range. Leaves communicate with each other through the hub. This is called subnet extrusion. In the example below, we configure the head office with 10.0.0.0/8 and two branches that use a smaller /24 subnet.
At the head office:
conn branch1
    left=1.2.3.4
    leftid=@headoffice
    leftsubnet=0.0.0.0/0
    leftrsasigkey=0sA[...]
    #
    right=5.6.7.8
    rightid=@branch1
    rightsubnet=10.0.1.0/24
    rightrsasigkey=0sAXXXX[...]
    #
    auto=start
    authby=rsasig

conn branch2
    left=1.2.3.4
    leftid=@headoffice
    leftsubnet=0.0.0.0/0
    leftrsasigkey=0sA[...]
    #
    right=10.11.12.13
    rightid=@branch2
    rightsubnet=10.0.2.0/24
    rightrsasigkey=0sAYYYY[...]
    #
    auto=start
    authby=rsasig
At the branch1 office, we use the same connection. Additionally, we use a pass-through connection to exclude our local LAN traffic from being sent through the tunnel:
conn branch1
    left=1.2.3.4
    leftid=@headoffice
    leftsubnet=0.0.0.0/0
    leftrsasigkey=0sA[...]
    #
    right=10.11.12.13
    rightid=@branch2
    rightsubnet=10.0.1.0/24
    rightrsasigkey=0sAYYYY[...]
    #
    auto=start
    authby=rsasig

conn passthrough
    left=1.2.3.4
    right=0.0.0.0
    leftsubnet=10.0.1.0/24
    rightsubnet=10.0.1.0/24
    authby=never
    type=passthrough
    auto=route

4.6.7. Road Warrior Application Using Libreswan

Road Warriors are traveling users with mobile clients with a dynamically assigned IP address, such as laptops. These are authenticated using certificates. To avoid needing to use the old IKEv1 XAUTH protocol, IKEv2 is used in the following example:
On the server:
conn roadwarriors
    ikev2=insist
    fragmentation=yes
    left=1.2.3.4
    # if access to the LAN is given, enable this, otherwise use 0.0.0.0/0
    # leftsubnet=10.10.0.0/16
    leftsubnet=0.0.0.0/0
    leftcert=gw.example.com
    leftid=%fromcert
    leftxauthserver=yes
    leftmodecfgserver=yes
    right=%any
    # trust our own Certificate Agency
    rightca=%same
    # pick an IP address pool to assign to remote users
    # 100.64.0.0/16 prevents RFC1918 clashes when remote users are behind NAT
    rightaddresspool=100.64.13.100-100.64.13.254
    # if you want remote clients to use an internal DNS server
    modecfgdns1=1.2.3.4
    rightxauthclient=yes
    rightmodecfgclient=yes
    authby=rsasig
    # optionally, run the client X.509 ID through pam to allow/deny client
    # pam-authorize=yes
    # load connection, don't initiate
    auto=add
    # kill vanished roadwarriors
    dpddelay=30
    dpdtimeout=120
    dpdaction=%clear
On the mobile client, the Road Warrior's device, we need to use a slight variation of the above configuration:
conn to-vpn-server
    ikev2=insist
    # pick up our dynamic IP
    left=%defaultroute
    leftsubnet=0.0.0.0/0
    leftcert=myname.example.com
    leftid=%fromcert
    leftmodecfgclient=yes
    # right can also be a DNS hostname
    right=1.2.3.4
    # if access to the remote LAN is required, enable this, otherwise use 0.0.0.0/0
    # rightsubnet=10.10.0.0/16
    rightsubnet=0.0.0.0/0
    # trust our own Certificate Agency
    rightca=%same
    authby=rsasig
    # allow narrowing to the server’s suggested assigned IP and remote subnet
    narrowing=yes
    # Initiate connection
    auto=start

4.6.8. Road Warrior Application Using Libreswan and XAUTH with X.509

Libreswan offers a method to natively assign IP address and DNS information to roaming VPN clients as the connection is established by using the XAUTH IPsec extension. XAUTH can be deployed using PSK or X.509 certificates. Deploying using X.509 is more secure. Client certificates can be revoked by a certificate revocation list or by Online Certificate Status Protocol (OCSP). With X.509 certificates, individual clients cannot impersonate the server. With a PSK, also called Group Password, this is theoretically possible.
XAUTH requires the VPN client to additionally identify itself with a user name and password. For One time Passwords (OTP), such as Google Authenticator or RSA SecureID tokens, the one-time token is appended to the user password.
There are three possible back ends for XAUTH:
xauthby=pam
This uses the configuration in /etc/pam.d/pluto to authenticate the user. Pam can be configured to use various back ends by itself. It can use the system account user-password scheme, an LDAP directory, a RADIUS server or a custom password authentication module.
xauthby=file
This uses the configuration file /etc/ipsec.d/passwd (not to be confused with /etc/ipsec.d/nsspassword). The format of this file is similar to the Apache .htpasswd file and the Apache htpasswd command can be used to create entries in this file. However, after the user name and password, a third column is required with the connection name of the IPsec connection used, for example when using a conn remoteusers to offer VPN to remove users, a password file entry should look as follows:
user1:$apr1$MIwQ3DHb$1I69LzTnZhnCT2DPQmAOK.:remoteusers
NOTE: when using the htpasswd command, the connection name has to be manually added after the user:password part on each line.
xauthby=alwaysok
The server will always pretend the XAUTH user and password combination was correct. The client still has to specify a user name and a password, although the server ignores these. This should only be used when users are already identified by X.509 certificates, or when testing the VPN without needing an XAUTH back end.
An example configuration with X.509 certificates:
conn xauth-rsa
    ikev2=never
    auto=add
    authby=rsasig
    pfs=no
    rekey=no
    left=ServerIP
    leftcert=vpn.example.com
    #leftid=%fromcert
    leftid=vpn.example.com
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    rightaddresspool=10.234.123.2-10.234.123.254
    right=%any
    rightrsasigkey=%cert
    modecfgdns1=1.2.3.4
    modecfgdns2=8.8.8.8
    modecfgdomain=example.com
    modecfgbanner="Authorized Access is allowed"
    leftxauthserver=yes
    rightxauthclient=yes
    leftmodecfgserver=yes
    rightmodecfgclient=yes
    modecfgpull=yes
    xauthby=pam
    dpddelay=30
    dpdtimeout=120
    dpdaction=clear
    ike_frag=yes
    # for walled-garden on xauth failure
    # xauthfail=soft
    #leftupdown=/custom/_updown
When xauthfail is set to soft, instead of hard, authentication failures are ignored, and the VPN is setup as if the user authenticated properly. A custom updown script can be used to check for the environment variable XAUTH_FAILED. Such users can then be redirected, for example, using iptables DNAT, to a walled garden where they can contact the administrator or renew a paid subscription to the service.
VPN clients use the modecfgdomain value and the DNS entries to redirect queries for the specified domain to these specified nameservers. This allows roaming users to access internal-only resources using the internal DNS names.
If leftsubnet is not 0.0.0.0/0, split tunneling configuration requests are sent automatically to the client. For example, when using leftsubnet=10.0.0.0/8, the VPN client would only send traffic for 10.0.0.0/8 through the VPN.

4.6.9. Additional Resources

The following sources of information provide additional resources regarding Libreswan and the ipsec daemon.

4.6.9.1. Installed Documentation

  • ipsec(8) man page — Describes command options for ipsec.
  • ipsec.conf(5) man page — Contains information on configuring ipsec.
  • ipsec.secrets(5) man page — Describes the format of the ipsec.secrets file.
  • ipsec_auto(8) man page — Describes the use of the auto command line client for manipulating Libreswan IPsec connections established using automatic exchanges of keys.
  • ipsec_rsasigkey(8) man page — Describes the tool used to generate RSA signature keys.
  • /usr/share/doc/libreswan-version/README.nss — Describes the commands for using raw RSA keys and certificates with the NSS crypto library used with the Libreswan pluto daemon.

4.6.9.2. Online Documentation

https://libreswan.org
The website of the upstream project.
http://www.mozilla.org/projects/security/pki/nss/
Network Security Services (NSS) project.