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

    bugzilla.redhat.com/show_bug.cgi? id = 1081804

    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:

    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!
    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

    Keys generated. I added a parameter nopassat 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
    	# left - local (server) side
    	# right - remote (client) side
    conn ikev2-pubkey
    conn ikev2-pubkey-osx
    conn ikev1-fakexauth
    conn ikev2-eap-tls

    As you can see, the configuration file consists of several sections. There are config setuptwo commented parameters in the section : it strictcrlpolicy = yeswill require an unexpired review sheet for client authentication, and uniqueids = noallows multiple clients to connect with one certificate at a time.
    Next are sections with descriptions of connections. The section with the name %defaultdescribes 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 timeout
    • dpddelay=35s - delay before turning on DPD
    • dpdtimeout=300s - timeout for DPD
    • fragmentation=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 encryption
    • leftand right- case all interfaces and accept all clients
    • leftid- indicate our FQDN. Needed for broken IKEv2 in OS X El Capitan
    • leftauth/rightauth=pubkey - we use authentication by keys
    • leftsubnet- 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-noauthto connectikev1-fakexauth, then you can replace it simply with xauthand create a user in /etc/ipsec.secrets, for example, with the username and password client1:
    client1 : XAUTH "client1"

    Now we have three connections: ikev2-pubkeyfor IKEv2, ikev1-fakexauthfor 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: 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: 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: 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 7, 8, 8.1 (IKEv2)
    Installing Certificates
    Creating a Connection

    Windows Vista (IKE)
    IKE on Windows Vista

    OS X and iOS

    Setting up a connection on iOS and OS X


    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.


    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.

    Also popular now: