Goto Top

IKEv2 VPN server for Windows and Apple clients on Raspberry Pi



The following tutorial did not claim to be fully comprehensive and a Raspberry should be taken as an example. It works of course on every Linux distribution as well as on OpenWRT. Its a quick framework to show the basic functions of an IPsec IKEv2 VPN server and intentionally limited to the onboard VPN clients in all OSes. The simple reason is they are always included and there is no need to install any additional 3rd party VPN clients as its the case with e.g. Wireguard or OpenVPN.
Therefore it has a close relationship with the forum pfSense / OPNsense Firewall VPN tutorial (see further links at the bottom). More or less every Unix based appliance uses the charon IPsec daemon as a foundation for IPsec.
Using IKEv2 onboard VPN clients on Windows and Apple always requires a server certificate. IKEv2 VPN clients use it to check the authenticity of the target VPN server to prevent being spoofed by a fake server.
It is not within the scope of this tutorial to be a fully basic knowledge tutorial for IPsec and PKI. The usage of a Raspberry Pi with Debian based Linux is only an example. Of course can this setup also be used with "bigger" hardware and different distros as well as with the famous free OpenWRT router firmware (strongswan- swanctl package).
A bit of Linux CLI knowledge and some basic network and PKI knowledge would be helpful to get familiar with the following configuration steps
A Linux machine with SSH access (e.g. PuTTY) is the starting point.

back-to-topVPN server configuration

StrongSwan swanctl is a new portable command line utility for the IKE daemon charon. Its included since 5.2.0 and will replace the old starter syntax on a long term perspective.
To make Linux and here the Raspberry Pi IPsec capable, additional packages need to be installed with the APT package manager. This requires root user access rights (sudo su):
apt install strongswan strongswan-pki charon-systemd libcharon-extra-plugins
Also IPv4 forwarding (routing) needs to be activated and can be done editing the file (nano editor) /etc/sysctl.conf and changing the line
by removing the comment sign "#" at the beginning net.ipv4.ip_forward=1 and reboot the RasPi after the file was saved.
If that step is completed continue with the CA and certificate setup...

back-to-topCA setup and server certificate with StrongSwan PKI

As mentioned above, all the onboard VPN clients did a server certificate check to proof the servers authenticity. Hence it adds more security to the VPN and needs a small PKI infrastructure PKI. A CA is in a figurative sense an authority who issues an identiy card with a stamp (certificate) which can then be checked by the clients.
If there is an existing CA the only requirement is to issue another server certificate with that CA for the new RasPi server.
If no CA is active just follow the next steps to create one.
CA setup using StrongSwan PKI commands:
The last, the file raspica-cert.pem, is the "authority" which needs to be exported into the VPN clients. Details can be found in the local pfSense / OPNsense Firewall VPN tutorial. (see further link section at the bottom)
Setup server certificate:
(Tip: It's useful to edit these commands in a text editor first and customize them to personal needs like filenames, timeframes etc.

back-to-topUsing an existing CA

If an exiting CA is active, the only need is to create a new, additional server certificate and export it together with the CA.
The following example shows it with a working CA on a pfSense/OPNsense firewall in the "Cert Manager" menu:
CA certificate and key export: (Menu "CA")

Server certificate and key export:: (Menu "Certificates")
Server is too exported with the "sun" icon (Mouseover) and the corresponting key with the "key" icon like with the above CA.

The server certificate can be safely erased afterwards from the CA, cause it is only needed on the VPN Server itself.
The exported certificate and key files can be moved to the server with a usb stick or via network copy using SCP tools like (e.g. WinSCP).
They need to be copied into the following server directories:
  • All key files into: /etc/swanctl/private
  • CA certificate into: /etc/swanctl/x509ca
  • Server certificate into: /etc/swanctl/x509
If all these files were created using the above StrongSwan PKI commands, the correct directories can be seen in the specific commands as well.
All these certificates and keys can of course be generated with other tools of own choice, like OpenSSL or XCA as well.
The VPN enddevices (clients) only need the CA certificate to be imported.

back-to-topStrongSwan configuration

The general StrongSwan configuration is placed in the directory /etc/swanctl/conf.d and needs to have a .conf suffix like vpn-server.conf.
This can quickly be done with a simple texteditor like nano. A single command like nano /etc/swanctl/conf.d/vpn-server.conf creates the file and the following configuration can be inserted with simply cut and paste. Never forget to save and exit with <ctrl o> und <ctrl x> (nano) !
It is useful to perhaps replace the example settings used here with individual ones.
  • Replace PSKs with secret ones !
  • Internal example VPN client network: /24
  • Local IP address on eth0 interface: (DNS example:
  • DNS server IPs propagated automatically to clients at dialin: and
  • 2 VPN example users with username/passwd combination user/test123 and user2/user2
  • Usernames/Passwords can not be used twice. (No multiple login with the same credentials, Parameter unique = replace). It can be allowed by simply omitting this parameter.
(Missing "-modpXXXX" in phase 2 cryptos solves a problem with instable connections on Apple IKEv2 clients by recommended disabling of PFS. See here for details!)

When all the certificate and key files are stored in their correct directories the configuration can now be activated with:
swanctl -q
(It happens also automatically after every reboot) The daemon acknowledges this with

back-to-topLoopback interface with second IP

As an option it makes sense to set a second IP on the server loopback interface lo. With the second IP its possible to ping the server from active VPN clients to verify the connection. It can also serve as an keepalive IP or can be used for forwarding. (Later section)
The highest VPN pool address will do this.
ip addr add dev lo adds it temporarly. (Check with ip a). To make it permanent the IP should be added in /etc/network/interfaces:
.# The loopback network interface
auto lo
iface lo inet loopback
iface lo inet static

Further troubleshooting can be done by observing the live log with swanctl -T. (Stop with <ctrl c>) or ip xfrm state.
With every configuration change, a new swanctl -q is mandatory to activate the changes !
With these steps the server is ready and next is the VPN client setup...

back-to-topWindows and Apple VPN client configuration

Usually Windows, Apple and all smartphones/tablets have 2 onboard VPN clients. One based on the L2TP VPN protocoll and on for native IPsec in Tunnel Mode with IKEv2. Here we deal with the latter one.
One caveat is the Microsoft VPN client, which uses weak ciphers in the default settings. When a higher security is required, tweaking with Powershell or a Registry setup is mandatory here. Apple uses stronger default security in their clients (AES256,SHA256,DH14) and is not affected. Btw. often the reason why Windows can connect but not Apple due to a higher cipher request which fail in the VPN client negotiation.
In a Windows setup that support the default, out-of-the-box settings without changes, SHA1 Hashing and DH Group 2 support need to be activated. It can be seen in the above StrongSwan configuration unter (proposals = ...).

Take note that ALL clients need to have the CA root certificate imported first !
The import into the trusted root certificates folder can be done under Windows with a simple doubleclick or via the certificate manager. Mac OS a doubleclick and set the certificate to always trust.
On mobile devices the easiest way is to send it via email attachment or USB and doubleclick it. More details can be found for Apple in the firewall tutorial.

back-to-topWindows VPN client

⚠️ 21H2 requires patch here !

The Windows client setup via GUI is pretty easy and can be seen here:
Make sure to use the FQDN as hostname if it was used in the generated server certificate for the server! ("--dn "" --san") (FQDN is send as ID and must match the "local ID" settings in the Strongswan config and server certificate (SAN)!

Type IKEv2, Username/Password. Automatic deployment of username/passwd can be set with the checkmark in the VPN adapter attributes:

Also if the VPN client should use the tunnel for his default gateway (Gateway Redirect) or should only reach the remote networks (Split Tunneling).

back-to-topWindows client: Increasing VPN security settings

The following topic is only for users who need to increase their Windows VPN client security.
If the defaults are sufficient this step can be ignored.

The easiest option is to tweak the specific VPN connection with a Powershell command:
Set-VpnConnectionIPsecConfiguration -ConnectionName "RasPi" -AuthenticationTransformConstants None -CipherTransformConstants AES256 -EncryptionMethod AES256 -IntegrityCheckMethod SHA256 -DHGroup Group14 -PfsGroup None -PassThru -AllUserConnection
Note that the parameter -ConnectionName "RasPi" needs to match exactly the VPN connection name ! (Here the firewall turorial has more information for the VPN customization via Powershell).

Another alternative to gain higher VPN security is the Windows Registry:
  • 1.) Edit Registry with regedit or use GPO: HKLM\SYSTEM\CurrentControlSet\Services\RasMan\Parameters\
  • 2.) Create a new DWORD value: NegotiateDH2048_AES256
  • 3.) DWORD value to 1 or 2
Table of DWORD values:
Please note:
If the Windows Registry has this VPN setting (DWORD), Windows will always use these stronger ciphers ! Hence it could effect existing VPN connections which perhaps use weaker or default ciphers !
The Powershell option is more flexible here, cause it can individually be configured on a per connection basis.

back-to-topApple VPN client

Apple uses strong ciphers by default. Here just the login credentials and the certificate DN or --san name (remote ID) are needed for access:

back-to-topMobile enddevices

As mentioned before, certificate and key files can be send by email attachment or USB. In case a larger amount of Apple mobile devices need to be configured the Apple Configurator 2 eases this step with a simple template which can be created and distributed automatically.

back-to-topJumphost setup with vserver and VPN router

One exampe of a practical live setup is a jumphost design for DS-Lite customer connections. Due to DS-Lite there is no possibility to realize IPv4 connection from remote. All those connections stuck and are blocked at the provider CGN gateway. IPv6 is of course not effected DS-Lite is related to IPv4 only !
As a workaround a home IPsec VPN router like the popular AVM FritzBox, can establish a VPN connection with IPv4 to a public jumphost (vserver with StrongSwan) to connect the local LAN network. From the "other side" the server is conntacted via IPv4 from the VPN clients. The server acts more or less like a relay station to access the local LAN network from remote and avoid DS-Lite obstacles.

That way DS-Lite users can get rid of the CGN limitations or unsafe and dangerous public VPN companies.
Just to make sure: This design is ONLY useful for private home connections based on DS-Lite ! All (normal) connections with a public IPv4 on the WAN/xDSL router port can of course use the simple design above.

back-to-topStrongSwan Jumphost configuration

The Strongswan configuration needs to be modified for this setup by adding the FritzBox connection. (For the FritzBox settings special thanks to @colinardo !)
  • Replace PSKs with safe ones !
  • Replace vServer IP <server_hoster_ip> and FQDN <server_FQDN> with personal IP and FQDN values
  • In case the AVM FritzBox uses a different local LAN as it needs to be changed under "remote_ts = x.y.z.h"

back-to-topFritzBox VPN configuration file

The corresponding FritzBox VPN configuration file looks like this. Its a simple text file editable with e.g. Notepad++ and can be loaded into the FritzBox over the GUI. (Internet -> Freigabe -> VPN)
  • Replace <server_hoster_ip> with the live vServer IP or FQDN
(For details regarding FritzBox IPsec crypto profiles see HERE)

back-to-topClient VPN and NAT

If VPN clients are active in the above jumphost design they can work on all remote VPN networks but lose their Internet connection. Windows shows this with the taskbar globe symbol while the VPN is active.
This is obvious, cause clients use their pool RFC 1918 private IP address ( to access the Internet via the vServer interface. RFC 1918 are non routed networks hence providers will drop that traffic instantly which results in a connection loss to all Internet targets.
The solution is quite simple in masquerading all VPN client traffic to the Internet on the vServer except the VPN tunneltraffic. Due to the fact that modern distros only use nftables to control the system firewall an nft ruleset is shown here.
A simple ruleset at the end of the etc/nftables.conf file achieves this.
The variable VPN_NETS defines here the remote reachable LAN addresses and can be extended by a wider subnet mask or by adding further comma separated network addresses. Interface eth0 must be changed into the used one shown by ip a command.
A systemctl restart nftables restarts the vServer firewall with the new rule and VPN clients have Internet access afterwards. Active ruleset can be checked with nft list ruleset.

back-to-topPort Forwarding

A VPN should always be the first choice for accessing a home network or its content. But for example operating an own, private Cloud with Nextcloud or providing content from a local webserver to the public can be a worthwhile reason to use port forwarding on top.
The following picture shows this scenario with the above jumphost setup as the foundation.
The blue dotted line symbolizes this direct webserver access as an example.
There are 2 options for a technical solution:
  • Port forwarding with source NAT using the vServer local firewall (nftables)
  • Access using a proxy like Nginx
First option using detailed NAT rules is overall not an easy task and it bears a risk for the vServer security.
The proxy solution is more secure and easier to configure for beginners.
Another advantage of the Nginx proxy is that it can not only forward webports (TCP 80, 443) but also other ports like SSH etc.
apt install nginx installs the Nginx proxy.

The following easy configuration example shows a port translation to avoid exposing the popular TCP 80 (HTTP) port to the public and port scanners.
The vServer can be accessed with TCP 58080 and forwards the traffic to the local webserver with TCP 80. http://<ip_adresse_hostname>:58080
In case TCP 443 should be forwarded the Listen ports should be changed into "443" and "proxy_pass http:/ /;" too. Same for TCP 80.
The simple config under /etc/nginx/sites-available/default should look like this:
After a configuration change the proxy needs to be restarted with systemctl restart nginx to activate the new settings.
The Nginx reverse proxy is very powerful with flexible config options. The description of all possible options is beyond the scope of this tutorial.

back-to-topSecure port forwarding with nftables firewall

To let only wanted traffic pass through the vServer ingress port it makes sense to secure it also with the nftables firewall by customizing the startup config under /etc/nftables.conf:

back-to-topLinks with further information

Tutorial in 🇩🇪:
IKEv2 VPN Server für Windows und Apple Clients mit Raspberry Pi

Basic Raspberry Pi setup:
Netzwerk Management Server mit Raspberry Pi

pfSense / OPNsense certificate secured IKEv2 VPN server for mobile user access with onboard VPN software:
IPsec VPN für mobile Benutzer auf der pfSense oder OPNsense Firewall einrichten

StrongSwan command documentation:

Windows 10: Quick VPN access with a single mouseclick: ...

Microsoft Power Shell VPN command syntax: ...

Apple iOS Configurator 2:

Content-Key: 1769120412


Printed on: March 20, 2023 at 21:03 o'clock

Member: Frank
Frank Jan 28, 2022 at 17:52:46 (UTC)
Goto Top
Thanks face-smile