Skip to content

IKEv2 with Let’s Encrypt- robust IPsec vpn solution for Windows, Android, Linux, macOS and iOS clients

IKEv2 with Let’s Encrypt- robust IPsec vpn solution for Windows, Android, Linux, macOS and iOS clients published on No Comments on IKEv2 with Let’s Encrypt- robust IPsec vpn solution for Windows, Android, Linux, macOS and iOS clients

Hello 🙂

In this post I will describe how to prepare solid vpn gateway which works flawlessly with many different clients.

I choose the solution based on modern IKEv2 protocol created with Microsoft and Cisco together. In a big simplification – IKEv2 (Internet Key Exchange version 2) is responsible to set up a security association (SA) in the IPsec protocol suite.

Advantages of IKEv2 over IKEv1 protocol:

  • it tolerates interruptions, latency etc. on network connection. For example, if the connection is temporarily lost, or if a user moves a client computer from one network to another, IKEv2 automatically restores the VPN after the network connection is reestablished — in transparent way to the user.
  • EAP authentication – we can authenticate simply, by username and password
  • better dead peer/tunnel detection
  • consume less bandwidth

IKEv2 has built in client in Windows 7 and newer and on macOS and iOS systems.
For Android there is a StrongSwan client app which is working very well. In Linux we can simply use Strongswan which is one of IPsec implementation for Linux.

In setup below I will use certificate for server obtained from Let’s Encrypt. It is needed because Windows clients will not work with self signed certificate without adding our CA as trusted. My goal is that we don’t have to provide anything other then user name and password 🙂

I will skip the part describing an obtaining a certificate from Let’s Encrypt. It is well documented in internet.
For server/gateway side I used Strongswan which provides support for IKEv2.

Server configuration

For setup server side we have to:
Install Strongswan:
(I’m installing it on OpenSUSE)

or if you using Debian based Linux distribution

I already have a certificate Let’s Encrypt for my domain. The typical catalog structure with the certificates from Let’s Encrypt looks as follows:

To use it in Strongswan it is necessary to create links to certificates and keys:

W need to provide Let’s Encrypt intermediate certificate:

This is very important step, I was spent a lot of hours to discover that Windows works properly only if we are providing intermediate certificate. Other CA certs in /etc/ipsec.d/cacerts/ , especially self-signed may also causing problems

Now we can edit /etc/ipsec.conf
My configuration looks as follows:

After that we have to add private key (/etc/ipsec.d/private/privkey.pem) and define usernames and passwords for vpn clients.

This is the whole Strongswan configuration. To apply configuration Strongswan must be restarted:

If don’t have configured NAT/masquerade your clients will not have internet.

If you want allow your clients access to the internet, you have to enable nat/masquerade

In some cases there is a problem with mtu/mss which can cause for example problem with opening some web pages. Strongswan documentation recommends reduce the MSS for packets transmitded through tunnel. Strongswan documentation
To reduce the mss, add a rule to iptables:

From my observations, reducing mss to 1200 ensures trouble-free operation on all clients

Clients configuration

In most clients it is trivial.


iPhone – iOS

Very simple configuration, analogous to iOS/iPhone

Unfortunately, manual configuration is slightly complicated. But then it works very well.
In newer releases of Linux distribution there is a gui plugin for network manager which provide easy configuration of vpn connection. But I haven’t tried it.

Strongswan configuration: /etc/ipsec.conf

password for user1 i stored in /etc/ipsec.secret:

We have to had intermediate and CA root certyficate in /etc/ipsec.d/cacerts:

root CA certificate is available to copy from  DST Root CA X3
I had to copy it to a file in such way (with adding “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–“:

In the default configuration, strongswan does not set the dns addresses provided by the server. This behavior can be changed by editing /etc/strongswan.d/charon/resolv.conf. I uncommented line with “file = /etc/resolv.conf”

Restart Strongswan:

And connection should be start:

We can check connection status:

And disconnect connection:

[Update 21.12.2018]

Carsten who reads this post shared with me some observations with configuring IKEv2 connections on Windows clients.

In more sophisticated scenario, than described here when we don’t want to set vpn connection as default gateway for clients (redirect all trafic to vpn tunnel), but we want use vpn connection only for some specified remote networks then Windows client is a problem.
Windows has no support for traffic selector provided by strongSwan.
Carsten writes:

  • The VPN LAN should be different to the remote LAN.
  • Therefore in Windows “Use default gateway on remote network” must be set.
  • Therefore “leftsubnet=” is necessary, because all traffic of the client goes through the VPN (which is not nice).
  • Without “Use default gateway on remote network” Windows only sets a route for the VPN LAN, which is useless. It should be possible to set a route to the remote LAN by using the PowerShell. I haven’t tried that yet.

This problem is also described here

Thanks Carsten for sharing your observations.

Linux box as an IPv6 router with SLAAC and DHCPv6-PD

Linux box as an IPv6 router with SLAAC and DHCPv6-PD published on 2 Comments on Linux box as an IPv6 router with SLAAC and DHCPv6-PD

Some time ago I replaced my Mikrotik router with linux box which is working as a router for my home network and as a server for some services.
I had to spend some time to set up IPv6 on linux in such way, that everything was working automatically and without need to configuring anything in statically way. This post will be only about IPv6 part of router configurations.
I omit IPv4 part and configurations of network interfaces, because it is well documented in internet.

My router is running on linux openSUSE leap 42.2. The configurations are the same for other distros but file paths of config files may be different.
eth0 – wan interface of the router
eth1 – lan interface of the router
To make the router working, I had to:

  • change some sysctls to obtain IPv6 address on wan interface of my router by Stateless autoconfiguration (SLAAC).
  • I used wide-dhcpv6-client client to obtain IPv6 adresses pool (DHCPv6-PD) to redistribute addresses from pool on my devices in home network.
  • Redistributing addresses is done by dnsmasq.

First step – sysctls:
Part of my /etc/sysctl.conf confgured to obtain IPv6 address from Stateless autoconfiguration (SLAAC) on wan interface – eth0:

After reboot I can see that my wan interface has public IPv6 address:

Second step – wide-dhcpv6-client:
Configuration of wide-dhcpv6-client which will be obtaining IPv6 address pool (DHCPv6-PD) for lan interface (eth1)

Unfortunately package of wide-dhcpv6-client does not provide configuration file for systemd. To start up wide-dhcpv6-client by systemd I created wide-dhcpv6.service entry:

Enable it on system startup:

After reboot I can see that my lan interface (eth1) has assignment IPv6 address with prefix:

Last step – dnsmasq:
Part of configuration of dnsmasq (/etc/dnsmasq.conf) to redistributing IPv6 addresses in home network. Dnsmasq will also work as dns cache. :

Enable dnsmasq on system startup:

After reboot, devices in home network should be able to use internet by IPv6 🙂

But now, devices in home network are avaible from outside. Each of device has own public IPv6 address which is awailable from outside (internet).
We have to secure it, by allowing only for connections which are initialized from our internal network. It can be done by ip6tables.

It’s all, described configuration works flawlessly for me for days 🙂

Securing ssh by iptables rules

Securing ssh by iptables rules published on 3 Comments on Securing ssh by iptables rules

I secured my ssh server in simple way – with iptables rules which will be blocking attackers. I setup my iptables in such way, that it is allowing only one tcp syn packet to ssh port per minute from one ip address. With aditional configuration of sshd daemon the rules will allowing for once login attempt per hour.
iptables rules:

After we reaches this one new connection per hour, the hashlimit-htable-expire rule starts to counting 60 minutes (3600000ms). In this time you can not connect again to ssh.

MaxAuthTries in /etc/ssh/sshd_config – this is important, with this, sshd will be closing ssh connections after authentication failure, thus attacker will have to create new ssh connection (and tcp connection) to try again. This fact (new syn packet) will by noticed by iptables.

If you use only public key authentication, you can set MaxAuthTries to 1 because this is first authentication method provided by OpenSSH server, also ssh clients firstly tries authenticate through public key. Other authentication methods are on further places.

debug1: Authentications that can continue: publickey,password,keyboard-interactive
debug1: Next authentication method: publickey

With MaxAuthTries set to 1 only fist authentication method will work –  usually publickey.

You can check the blocked addresses:

This rules very limited strength of attacks on my ssh.

Please test this first with another server access!

NanoPi NEO as remote SDR server for RTL2832u

NanoPi NEO as remote SDR server for RTL2832u published on No Comments on NanoPi NEO as remote SDR server for RTL2832u

Today I will show how to make remote SDR radio server for RTL2832u dongle with very small and cheap device such as NanoPi NEO.

The main purpose of this is that I want place the NanoPI with RTL dongle and antenna attached to it on remote location – on high building 250 meters far away from my home. I have wireless bridge connecting my home with this place.

Notice: Wireless have to be able to send about 16Mb/s of tcp trafic from NanoPi to PC. 

On NanoPi I installed Armian Linux. After that I was set up rtl_tcp server:
900001 – this is lowest sample-rate which can be used, I used lowest because my wireless bridge wasn’t able to pass more traffic.

The next step was to setup and start gqrx on my home computer:
Notice: Input rate must be the same as set on rtl_tcp server. – this is IP address of my NanoPi.

And now, we can hear everything around us 🙂