VPN Anywhere: IPsec without L2TP with strongSwan
strong enough swan
If you have ever looked for a VPN that will work on desktops, mobile devices and routers without installing additional software and flashing the router, you probably chose between PPTP and L2TP + IPsec. The PPTP protocol has problems with security and passage through firewalls and NAT, so in 2015 it should not be used, and the use of L2TP is unnecessary, because L2 VPN, in my opinion, is almost never needed for regular remote access.
Surprisingly, it is not so easy to find information on the Internet about configuring something other than L2TP + IPsec in transport mode, given that this is an extensive protocol stack that can be configured literally as you like, so I will try to eliminate such an imperfection of the world.
A small introduction to the world of IPsec
Generally speaking, it is not entirely correct to call IPsec VPN. IPsec is not designed to build "virtual private networks", but is designed to encrypt or protect against the substitution of data transmitted over IP. This is a special layer on top of IP, which, depending on the mode and settings, works differently. Unlike the usual VPN, which creates a new interface in the system, to which you, as often happens, assign an IP subnet from a range of private addresses (i.e. create a new network segment) and through which traffic is encrypted IPsec simply encrypts traffic magically between the “external” server and client interfaces.In modern IPsec, the following are used:
- Authentication Header (AH) - A protocol that provides sender authentication and data integrity. Signs not only the packet data, but also all headers, except variable fields (ToS, TTL, check sum).
- Encapsulating Security Payload (ESP) - a protocol that provides authentication, integrity and confidentiality
- Security Association (SA) - parameter with channel encryption settings
- Internet Key Exchange (IKE and IKEv2) - protocol for the exchange of parameters, settings and negotiation SA
AH and ESP are transport protocols encapsulated directly in IP that have their own values for the Protocol field in the IP header. In the modern world, where NAT is behind NAT for NAT with NAT, something more familiar should be used, so encapsulation of ESP packets in UDP is now widely used. AH does not support operation through NAT.
IPsec itself supports two modes:
- Transport mode . Signs the headers and data (if AH) or signs and encrypts the data (if ESP) of the packet. Does not hide the IP address of the packet receiver if it is routed. This mode is used for the L2TP + IPsec bundle.
- Tunnel mode . Signs (if AH) and still encrypts (if ESP) the entire packet .
IKE allows client authentication using X.509 certificates, Pre-Shared Key, and Extensible Authentication Protocol (EAP). Two-step authentication is supported.
All modern desktop OS (Windows Vista / 7/8 / 8.1, OS X, Linux), mobile devices (Android, iOS, Windows Phone, Blackberry) and some routers support VPN using IPsec ESP in tunnel mode and configure it via the Internet protocol Key Exchange (IKE) version 1 or 2, which means we will configure IPsec this way.
By the way, write IPsec correctly, but Cisco IP S ec.
IPsec on Linux
IPsec itself (AH / ESP, SA) works in the kernel, so we need an IKE daemon to transfer settings to connecting clients. There are a lot of them, but there are only two full-fledged and active at the moment: strongSwan and libreswan . I didn’t use the second one, I can’t say anything about it, but the first one is beautiful and amazing, in addition, it is the only daemon that has its own userspace IPsec implementation, so it can be used in OpenVZ containers with an old kernel like dinosaurs 2.6.32 with broken IPsec routing support.A bit about IPsec in OpenVZ
OpenVZ has IPsec support, and it’s quite suitable for running L2TP + IPsec, but there is something clearly wrong with routing to non-local interfaces. This can probably be fixed by adding a couple of rules to the host machine, but this is quite problematic if you do not have access to it, as happens in the vast majority of cases. Therefore, for OpenVZ, you must use userspace IPsec, which can be compiled with the --enable-kernel-libipsec parameter. Bug
mentions:
lists.strongswan.org/pipermail/users/2014-February/005822.html
bugzilla.redhat.com/show_bug.cgi? id = 1081804
forum.openvz.org/index.php?t=tree&goto=39937
lowendtalk.com/discussion/33226/need-someone-to-test-ipsec-on-their-boxes
mentions:
lists.strongswan.org/pipermail/users/2014-February/005822.html
bugzilla.redhat.com/show_bug.cgi? id = 1081804
forum.openvz.org/index.php?t=tree&goto=39937
lowendtalk.com/discussion/33226/need-someone-to-test-ipsec-on-their-boxes
We need strongSwan version minimum 5.0.0. I recommend using version no lower than 5.2.0, as it was in this version that the “swanctl” utility appeared, which is much more convenient than the old “ipsec”. The utility will be required, by and large, only to display some information or statistics, it is not required for configuration and you can do only ipsec, but only it will be used in the article.
Hidden text
Life with swanctl:
Life without swanctl:
Life without swanctl:
We may need some modules, which may not be in the standard package:
- xauth-noauth - fake authenticator, allows you to enter any login and password. Required for iPhone and iPad with key authentication only, as there is no way to disable authentication by login and password.
- vici - an interface for swanctl.
- libipsec - for userspace IPsec (for OpenVZ and possibly other containers).
If you are not confused by the need to enter a username and password on the iPhone, you do not need swanctl and you are not going to run it all in an OpenVZ container, then you do not need to reassemble anything.
Unfortunately, strongSwan maintainers in Debian did not pack any of this (as of February 2015), so I made a patch that you can use.
Let's move on to setting up
We will configure the connection through IKEv2 (Windows, Linux, Blackberry), IKEv1 + XAUTH (iOS, OS X, Android) and IKEv2 + EAP-TLS (Windows Phone). We use keys, no PSK!StrongSwan developers suggest that we use the ipsec pki command to generate keys, but it is just as inconvenient as regular openssl, so I adapted Easy-RSA v3 from OpenVPN to generate both OpenVPN and IPsec-compatible keys. With it you can use one keychain for two protocols!
github.com/ValdikSS/easy-rsa-ipsec
Easy-RSA is extremely simple, it is a pleasure to maintain a PKI infrastructure with it!
So, we initialize PKI and create CA, server and client keys. It is important that the name of the server key matches the FQDN (domain, simply put) of your server!
$ git clone https://github.com/ValdikSS/easy-rsa-ipsec.git
$ cd easy-rsa-ipsec/easyrsa3
$ ./easyrsa init-pki
init-pki complete; you may now create a CA or requests.
$ ./easyrsa build-ca nopass
Generating a 2048 bit RSA private key
…
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:IPsec CA
…
$ ./easyrsa build-server-full uk1.pvpn.pw nopass
Generating a 2048 bit RSA private key
…
Write out database with 1 new entries
Data Base Updated
$ ./easyrsa build-client-full client1 nopass
Generating a 2048 bit RSA private key
…
Write out database with 1 new entries
Data Base Updated
$ ./easyrsa export-p12 client1 nopass
Successful export of p12 file. Your exported file is at the following
location…
Keys generated. I added a parameter
nopass
at every step so that the keys were not password protected (it can be set later at any time). Now we need to copy them to the necessary directories inside
/etc/ipsec.d/
so that strongSwan finds them:# cp pki/ca.crt /etc/ipsec.d/cacerts/
# cp pki/issued/uk1.pvpn.pw.crt /etc/ipsec.d/certs/
# cp pki/private/uk1.pvpn.pw.key /etc/ipsec.d/private/
Let's move on to setting strongSwan!
First of all, we indicate our private key in
/etc/ipsec.secrets
# This file holds shared secrets or RSA private keys for authentication.
# RSA private key for this host, authenticating it to any other host
# which knows the public part.
# this file is managed with debconf and will contain the automatically created private key
include /var/lib/strongswan/ipsec.secrets.inc
: RSA uk1.pvpn.pw.key
Editing the configuration file
/etc/ipsec.conf
# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup
# strictcrlpolicy=yes
# uniqueids = no
include /var/lib/strongswan/ipsec.conf.inc
conn %default
dpdaction=clear
dpddelay=35s
dpdtimeout=300s
fragmentation=yes
rekey=no
ike=aes256gcm16-aes256gcm12-aes128gcm16-aes128gcm12-sha256-sha1-modp2048-modp4096-modp1024,aes256-aes128-sha256-sha1-modp2048-modp4096-modp1024,3des-sha1-modp1024!
esp=aes128gcm12-aes128gcm16-aes256gcm12-aes256gcm16-modp2048-modp4096-modp1024,aes128-aes256-sha1-sha256-modp2048-modp4096-modp1024,aes128-sha1-modp2048,aes128-sha1-modp1024,3des-sha1-modp1024,aes128-aes256-sha1-sha256,aes128-sha1,3des-sha1!
# left - local (server) side
left=%any
leftauth=pubkey
leftcert=uk1.pvpn.pw.crt
leftsendcert=always
leftsubnet=0.0.0.0/0,::/0
# right - remote (client) side
right=%any
rightauth=pubkey
rightsourceip=192.168.103.0/24,2002:25f7:7489:3::/112
rightdns=8.8.8.8,2001:4860:4860::8888
conn ikev2-pubkey
keyexchange=ikev2
auto=add
conn ikev2-pubkey-osx
also="ikev2-pubkey"
leftid=uk1.pvpn.pw
conn ikev1-fakexauth
keyexchange=ikev1
rightauth2=xauth-noauth
auto=add
conn ikev2-eap-tls
also="ikev2-pubkey"
rightauth=eap-tls
eap_identity=%identity
As you can see, the configuration file consists of several sections. There are
config setup
two commented parameters in the section : it strictcrlpolicy = yes
will require an unexpired review sheet for client authentication, and uniqueids = no
allows multiple clients to connect with one certificate at a time. Next are sections with descriptions of connections. The section with the name
%default
describes the default connection from which other connections will be inherited. The following parameters are set here:dpdaction=clear
turns on the Dead Peer Detection (DPD) mechanism and indicates that you need to forget about the client if it has not responded longer than the timeoutdpddelay=35s
- delay before turning on DPDdpdtimeout=300s
- timeout for DPDfragmentation=yes
- Enabling internal packet fragmentation. Allows you to use IPsec with providers whose IP packet fragmentation is broken (hi, mobile MTS!)rekey=no
- turn off the initiation of key changes on the server side. Windows does not like it.ike
- a list of ciphersuites for use with IKE (i.e. during the installation of an encrypted connection to transfer configuration parameters, including keys for installing SA)esp
- list of ciphersuites for traffic encryptionleft
andright
- case all interfaces and accept all clientsleftid
- indicate our FQDN. Needed for broken IKEv2 in OS X El Capitanleftauth/rightauth=pubkey
- we use authentication by keysleftsubnet
- subnets that we send to the client for routing (all IPv4 and IPv6 Internet). Remove IPv6 if not using it.rightsourceip
- pool of IP addresses from which we issue the address to the client. Remove IPv6 if not using it.rightdns
- IP addresses of DNS servers
Let's deal with ciphersuites in ike and esp. Encryption methods are listed here in descending order of priority, and there are so many of them because some of them may not be available on some devices, for example, mobile ones. The first step is the so-called AEAD algorithms , i.e. ciphers that do not require a separate authentication algorithm , with a diminishing Diffie-Hellman group to implement Perfect Forward Secrecy (PFS). These are the fastest ciphers that are available in IPsec. Although this is an AEAD mode, ike should have hash algorithms for the handshake process. Then comes the familiar AES-CBC with Diffie-Hellman bands. Clients that do not support PFS, we will not allow to connect.
If you do not have a module
xauth-noauth
to connectikev1-fakexauth
, then you can replace it simply with xauth
and create a user in /etc/ipsec.secrets
, for example, with the username and password client1:client1 : XAUTH "client1"
Now we have three connections:
ikev2-pubkey
for IKEv2, ikev1-fakexauth
for IKEv1 with fake login and password verification, and ikev2-eap-tls
- IKEv2 + EAP-TLS for Windows Phone. Restart strongSwan. If everything is correct, you will see the following output from the swanctl -L command
$ swanctl -L
ikev2-pubkey: IKEv2
local: %any
remote: %any
local public key authentication:
id: CN=uk1.pvpn.pw
certs: CN=uk1.pvpn.pw
remote public key authentication:
ikev2-pubkey: TUNNEL
local: 0.0.0.0/0 2000::/3
remote: dynamic
ikev1-fakexauth: IKEv1
local: %any
remote: %any
local public key authentication:
id: CN=uk1.pvpn.pw
certs: CN=uk1.pvpn.pw
remote public key authentication:
remote XAuth authentication:
ikev1-fakexauth: TUNNEL
local: 0.0.0.0/0 2000::/3
remote: dynamic
ikev2-eap-tls: IKEv2
local: %any
remote: %any
local public key authentication:
id: CN=uk1.pvpn.pw
certs: CN=uk1.pvpn.pw
remote EAP authentication:
ikev2-eap-tls: TUNNEL
local: 0.0.0.0/0 2000::/3
remote: dynamic
MTU issues
Due to the peculiarities and errors in the implementation of different IPsec clients, the MTU inside the tunnel cannot be guessed in advance, and MTU 1500 is installed on Android in general, which is why large packets are not transmitted and nothing works at all. To mitigate this drawback, it is enough to change the TCP MSS parameter at the time of establishing a TCP connection on the server side. We will use the value 1360 for IPv4 and 1340 for IPv6 so that the packet size does not exceed 1400 bytes inside the tunnel:# iptables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir in --syn -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
# iptables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir out --syn -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
# ip6tables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir in --syn -m tcpmss --mss 1341:1536 -j TCPMSS --set-mss 1340
# ip6tables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir out --syn -m tcpmss --mss 1341:1536 -j TCPMSS --set-mss 1340
This completes the server setup. Remember to configure NAT if you need it!
Customer setup
The algorithm for configuring clients in general is to import certificates from a * .p12 file, create a new connection with the IPsec PKI, IPsec XAUTH RSA or IKEv2 type (depending on the device), specify the client certificate and server address.Attention! It is necessary to enter exactly the server address that you entered when creating the server key. Connecting to a different domain or simply by IP-address, if the certificate was generated on the domain, will not work!
Windows
Windows 7, 8, 8.1 (IKEv2)Installing Certificates
Creating a Connection
Connecting
Windows Vista (IKE)
IKE on Windows Vista
OS X and iOS
Setting up a connection on iOS and OS XAndroid
You can use both the Android IPsec client and connect using the IKE protocol, and the strongSwan client and use IKEv2. StrongSwan client works more stable and reliably reconnects in case of loss of connection.Import the certificate either through the file manager or using the “Install from SD card” item in the “Security” section. Go to the VPN settings, create a new connection with the type “IPSec Xauth RSA”, in the “Server address” field, enter the server address itself, in the “IPSec user certificate” and “IPSec CA certificate” field, specify the certificate “client1”. Click on the connection, enter any username and password and try to connect.
Conclusion
IPsec, in my opinion, is a great alternative to OpenVPN, which many administrators love. Why most VPN providers still use L2TP + IPsec is a mystery to me, because strongSwan provides all the necessary functionality for this kind of serialis (full Radius support, lots of plugins). I have been using strongSwan on my service for about half a year in closed testing mode and it left an extremely positive impression on itself.IPsec, as I said, is very flexible and supports a lot of authenticators, so you can even do crazy things like SIM card authentication on a mobile device and storing public keys in an IPSECKEY domain record protected by DNSSEC.
If you are afraid to use IPsec because of the NSA documents that Edward Snowden published, please read the Don't stop using IPsec just yet article to dispel doubts.