Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


VPN everywhere: IPsec without L2TP with strongSwan (even in OpenVZ)
New on LowEndTalk? Please Register and read our Community Rules.

All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.

VPN everywhere: IPsec without L2TP with strongSwan (even in OpenVZ)

ValdikSSValdikSS Member
edited February 2015 in Tutorials

yep, pretty strong swan
yep, pretty strong swan

If you ever looked for VPN which works on desktop, mobile devices and routers without installing additional software or reflashing router, you probably had a choice between PPTP and L2TP+IPsec. With some security and NAT traversal issues, PPTP is not a good choice for today, and L2TP only introduces additional overhead and can transmit L2 packets, which is almost always unnecessary.

Strange that you hardly find any decent IPsec without L2TP in transport mode configuration manual on the internet, taking into account that IPsec is a very flexible and mature protocol stack you can configure as you want. I'm writing this article to remedy this deficiency.

Diving into IPsec

Generally speaking, it's not quite accurate to call IPsec the VPN. IPsec was not developed as a solution for virtual private networks, but to sign and encrypt IP data between two endpoints. It works as a special layer over IP which works different with different configuration. Unlike usual VPN, which creates new network interface (network segment) where all the traffic is routed, IPsec just encrypts data over external server and client network interfaces. It's magic!

Modern IPsec uses the following things:

  • Authentication Header (AH). Protocol with sender authentication and data integrity. Not only data is signed, but the packet headers, too, except some mutable fields like ToS or TTL.
  • Encapsulating Security Payload (ESP). Protocol with sender authentication, data integrity and confidentiality.
  • Security Association (SA). Security attributes of the connection.
  • Internet Key Exchange (IKE and IKEv2). IPsec connection configuration protocol.

Both AH and ESP are transport protocols with their own protocol numbers in IP header. In own modern world with NAT over NAT everywhere, we are bound to use something more usual. IPsec supports UDP encapsulation of ESP packets which works good with NAT. AH doesn't work with NAT.

There are two modes of IPsec:

  • Transport mode. Signs IP headers and data (for AH) or signs and encrypts data (ESP). Does not hide destination IP. This mode is used for L2TP+IPsec.
  • Tunnel mode. Signs (AH) and also encrypts (ESP) the whole packet.

IKE protocol allows you to authenticate roadwarrior with X.509 certificates, Pre-Shared Key or using Extensible Authentication Protocol (EAP). Two factor authentication is also supported.

Every modern desktop OS (Windows VIsta/7/8/8.1, OS X, Linux), mobile devices (Android, iOS, Windows Phone, Blackberry) and some routers support IPsec in tunnel mode with ESP, which is configured using IKE protocol, that's why we will configure this stack.

By the way, it's IPsec but Cisco IPSec.

IPsec in Linux

The IPsec (AH/ESP, SA) works in the kernel mode, we just need to install and setup usespace IKE daemon for client configuration. Although several available, there are only two which are in active development: strongSwan and libreswan. I can't say anything for the second one because I didn't use it, but the first one is awesome. Also, that's the only daemon with it's own userspace IPsec library so you can use it in OpenVZ with old kernel versions (which, by the way, comes with broken IPsec routing).

Some notes on IPsec in OpenVZ

OpenVZ fully supports IPsec and it's suitable for L2TP+IPsec, but there are some general issues with the routing to non-local interfaces. These issues could be resolved by adding firewall rules on the host, but that's the main problem as none of the VPS providers would allow you to do that. You should use strongSwan userspace IPsec library called libipsec. To use it, one should build strongSwan with --enable-kernel-libipsec configuration option.
Bug links: 1, 2, 3, 4

We need strongSwan >= 5.0.0. I would recommend using 5.2.0+ because of new control utility swanctl. It's much more convenient than old ipsec. It is used almost only for information or statistics so it's not a big deal if you use ipsec.

Life with swanctl
swanctl

Life without swanctl
no swanctl

We should need some modules which could be missing in your repository:

  • xauth-noauth. Fake XAUTH authenticator which allows any username and password. Useful for iPhone and iPad which can't use IPsec without XAUTH (so-called Cisco IPSec).
  • vici. Internal interface for swanctl.
  • libipsec. Userspace IPsec for OpenVZ and other containers.

If your distro doesn't have these modules and you don't need to run strongSwan in OpenVZ containter, you're OK with ipsec utility and don't care about login/password on iPhone and iPad, you can use stock build. It's a shame that Debian doesn't supply these modules so I made a patch you can use to rebuild it with all the needed modules.

It's time to configure everything

We would set up IKEv2 connection for Windows, Linux, Blackberry; IKEv1+XAUTH for iOS, OS X and Android, and IKEv2+EAP-TLS for Windows Phone using X.509 keys only. PSK is for girls!
strongSwan developers offer their own solution for key generation — "ipsec pki". I find it inconvenient and hard to use as it's just a wrapper on openssl with a bit different syntax so I forked OpenVPN's Easy-RSA. You can generate one keychain for both IPsec and OpenVPN with it!
http://github.com/ValdikSS/easy-rsa-ipsec
Easy-RSA is very easy to use so maintaining PKI is a pleasure with it.

We should initialize PKI, generate CA and server/client keys. It's important for server key to have a name of servers' FQDN (full domain name)!

$ 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…

Now the keys are generated. I've added "nopass" paramter and the keys are generated without password. You can add the password anytime later.

Now we should copy our generated keys to the strongSwan keys directory.

# 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/

Now, we should add our private key to /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

This is how strongSwan configuration file should look like

# 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=200s

    fragmentation=yes

    ike=aes256gcm16-aes256gcm12-aes128gcm16-aes128gcm12-aesxcbc-sha256-sha1-modp4096-modp2048-modp1024,aes256-aes128-sha256-sha1-modp4096-modp2048-modp1024!

    esp=aes128gcm12-aes128gcm16-aes256gcm12-aes256gcm16-modp4096-modp2048-modp1024,aes128-aes256-sha1-sha256-modp4096-modp2048-modp1024!

    # left - local (server) side
    left=%any
    leftauth=pubkey
    leftcert=uk1.pvpn.pw.crt
    leftsendcert=always
    leftsubnet=0.0.0.0/0,2000::/3

    # 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 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, configuration is split into different sections. config setup section has two commented lines: strictcrlpolicy = yes would require actual certificate revocation list for authentication, uniqueids = no allows multiple concurrent connections using the same certificate.
Next sections are for connections. %default section stores default configuration which other connections can inherit. The following parameters are set:

  • dpdaction=clear turns on Dead Peer Detection feature and configures it to forget client if timeout exceeded.
  • dpddelay=35s — timeout before DPD
  • dpdtimeout=200s — timeout for DPD
  • fragmentation=yes enables fragmentation. Helps with some broken ISPs.
  • ike — list of IKE ciphersuites (for the control connection)
  • esp — list of ESP ciphersuites (for the data connection)
  • left and right — listen all interfaces and accept all clients
  • leftauth/rightauth=pubkey — X.509 key authentication
  • leftsubnet — subnets to route on client side. All the IPv4 and IPv6 internet. Remove IPv6 subnet if you don't use it.
  • rightsourceip — IP pool for clients. Remove IPv6 subnet if you don't use it.
  • rightdns — DNS IP address

Let's take a look on IKE and ESP ciphersuites. We should include all the popular algorithms to make sure our VPN would work on all the devices. The first ones are AEAD ciphers (ciphers which don't need additional authentication algorithm) with descending Diffie-Hellman group. That's the fastest ciphers available in IPsec. Then goes AES in CBC mode. It's not allowed to connect with disabled Perfect Forward Secrecy.

If your strongSwan installation missing xauth-noauth module, you can change it to just xauth and add user client with password clientpass in /etc/ipsec.secrets

client1 : XAUTH "clientpass"

Now you have three connections: ikev2-pubkey with IKEv2, ikev1-fakexauth with IKEv1 and fake login/password authentication, and ikev2-eap-tls IKEv2+EAP-TLS for Windows Phone.

swanctl -L should show something like this is for a correctly configured daemon

$ 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 different IPsec implementations and bugs in it, it's not possible to guess clients' MTU on the server side. For example, Android IPsec client sets MTU to 1500, strongSwan client uses 1400 and Cisco sets it to 1300. To fix this, we could modify TCP MSS value to prevent TCP packets data go over 1360 bytes for IPv4 and 1340 bytes for IPv6. We'll get 1400 bytes packets that way.

# 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

That's all, we finished with the server side. Don't forget to configure NAT!

Client configuration

Overall, steps are as follows: import p12 certificate to the keychain, create new IPsec PKI / IPsec XAUTH RSA or IKEv2 connection depending on the device, specify client certificate and server address. It is important to use exact domain name which you used for server key. It's not possible to connect to another domain or by IP address.

Windows

Windows 7, 8, 8.1

Adding the certificate
Creating the connection
Connecting

Windows Vista

IKE with Windows Vista

OS X and iOS

OS X and iOS configuration

Android

You can use either native Android IPsec client (IKE) or strongSwan client (IKEv2). I find strongSwan client more stable and faster.

Conclusion

In my humble opinion, IPsec is a great stack of protocols and could be used as a OpenVPN alternative. I have no idea why lots of VPN services still use L2TP+IPsec as strongSwan provides all the needed providing things (RADIUS authentication, accounting, a bunch of plugins). I use it in my own service and it works great. As i already said, IPsec is very flexible and you can use crazy EAP authenticators like EAP-SIM or EAP-AKA for authentication using your cellphone SIM card.
If you're in fear of NSA, please read Don't stop using IPsec just yet

Comments

  • As always, excuse me for my English.

  • IPsec is not as easy as you think.

  • Excellent tutorial. In time: hilarious pics as well.

  • rm_rm_ IPv6 Advocate, Veteran
    edited February 2015

    Still overly complicated and no point to use this instead of Tinc.
    e.g. this is still client-server, not automatic full-mesh.

  • So what is the benefit over using IPSec/L2TP? (which is actually the more mature setup/combo then IPsec alone)
    Doing things different just because...? Either way you are essentially doing the same thing, encrypting packets over a created tunnel... If I understand the method IPsec alone works, then you actually lose the benefit of essentially having your own private layer2 network that your encrypted packets transfer in and instead the encrypted packets are out in the open between the 2 end-points (client/server).

  • 10/10!

  • @rm_ said:
    Still overly complicated and no point to use this instead of Tinc.
    e.g. this is still client-server, not automatic full-mesh.

    Well, yes, you can't establish full-mesh connections. Tinc is great but you can use IPsec on almost every network-enabled device while Tinc is available only for limited platforms.

  • @ItsChrisG said:
    So what is the benefit over using IPSec/L2TP? (which is actually the more mature setup/combo then IPsec alone)
    Doing things different just because...? Either way you are essentially doing the same thing, encrypting packets over a created tunnel... If I understand the method IPsec alone works, then you actually lose the benefit of essentially having your own private layer2 network that your encrypted packets transfer in and instead the encrypted packets are out in the open between the 2 end-points (client/server).

    L2TP+IPsec is just an encrypted L2TP communication. It introduces a lot of overhead because it's working on L2 layer and transmits Ethernet frames, which you need only rarely. IPsec IKE is a native IPsec tunnel which gives you, for example great mobility. I often have a call with SIP on my cellphone over wifi, then I disconnect wifi and connect 3G, and the call is back in only 2-3 seconds.

    It's just another protocol, that's it.

  • @ValdikSS said:

    Could you also include 1) the package to install 2) compile process?

  • I have two windows 8 machines. One is running fine. The other one give me invalid payload error

  • I thought the NSA only spies on pretty young girls?

  • dnwk said: Could you also include 1) the package to install 2) compile process?

    Compile process and packages are different for each distro. In Debian, you can just download source with apt-get source strongswan, apply my patch and dpkg-buildpackage.

  • dnwk said: I have two windows 8 machines. One is running fine. The other one give me invalid payload error

    What is exact error code and message?

  • ValdikSSValdikSS Member
    edited July 2015

    You should add rekey=no to the %default section to make it stable with Windows clients. Windows doesn't like when server initiate rekeying process and the connection stalls.

    Also, you should change esp to aes128gcm12-aes128gcm16-aes256gcm12-aes256gcm16-modp4096-modp2048-modp1024,aes128-aes256-sha1-sha256-modp4096-modp2048-modp1024,aes128-sha1-modp4096,aes128-sha1-modp1024,aes128-sha1! to make Android client connect.

    I can't edit top post.

    Thanked by 2Shot2 muratai
  • To configure IKEv2 on OS X El Capitan, you should add the following:

    leftid=your_domain_name
    
    ike=…,3des-sha1-modp1024!
    esp=…,3des-sha1!
    
  • iOS 9 doesn't work with this config. According to OpenWRT:

    https://wiki.openwrt.org/doc/howto/vpn.ipsec.roadwarrior

    Beginning with iOS 9, IKEv2 connections are natively supported. However, iOS9 only supports the use of certificates or username/password, but not both.

    Any idea how to get this working with certificates only?

  • @Raymii said:
    Any idea how to get this working with certificates only?

    They've updated the doc with a new section at the top for iOS 9. You don't need a mobileconfig file any more.

    https://wiki.strongswan.org/projects/strongswan/wiki/IOS_(Apple)

  • bertanbertan Member
    edited December 2015

    @Raymii

    I finally got Strongswan working with iOS 9.

    https://rnotes.github.io/rn05.html

  • @bertan said:
    Raymii

    I finally got Strongswan working with iOS 9.

    http://strongswan.neocities.org

    Super thanks!

    Thanked by 1netomx
  • andreivandreiv Member
    edited January 2016

    I found this article while searching for IPSec and openvz.
    I have some linux admin experience but this is the first time that I have to install IPSec on a server.
    Here is in short what I have to do. Maybe someone can point me to a good tutorial (if what I want to do is even possible).

    We have a VPS server built on OpenVZ running CentOS 6.7.
    What I would like to do is to use is as a gateway to a company for which we have to work on some projects.

    I have OpenVPN set up on that server and the developers connect to it ok. Everything works. What I need to do now is create a tunnel between the VPS server and the customer's network.
    Could I use openswan for both the tunnel and as vpn server for the developers? And then route traffic from the devs to the customer's network? If this can be done, I would drop OpenVPN entirely.

    Or it would be simpler to keep OpenVPN for the devs and use openswan just to establish a secure tunnel to the customer?

    Any help would be very much appreciated.
    Thank you.

  • @andreiv, you can use openswan or any other IPsec IKE daemon. What's your question?

  • Sorry, I just saw your reply today.
    Ideally, what I would like to do is use strongswan on a VPS we have as both a tunnel and a VPN gateway.
    Our developers would connect to the VPS using IPSec and then get redirected from there to a client gateway through an IPSec gateway.
    Is such a setup possible? Something like in this diagram:

  • dnwkdnwk Member
    edited January 2016

    The link doesn't work

    @bertan said:
    Raymii

    I finally got Strongswan working with iOS 9.

    https://rnotes.github.io/rn05.html

  • @andreiv said:
    Our developers would connect to the VPS using IPSec and then get redirected from there to a client gateway through an IPSec gateway.
    Is such a setup possible?

    Yes, it's possible.

Sign In or Register to comment.