This repository contains a Dockerfile for generating an image with StrongSwan and Alpine Linux.
This image can be used on the server or client in a variety of configurations.
The reference configuration in this repository and following guidelines are intended to provide an attempt at a best-practice example for setting up a universal VPN server that can handle modern IKEv2 roadwarrior clients (with IPv6 support in mind).
Download the following configuration files from https://github.com/stanback/alpine-strongswan-vpn.git:
- generate_certs.sh
- config/
- config/ipsec.conf
- config/ipsec.secrets
- config/strongswan.conf
- config/ipsec.d/firewall.updown
Edit the configuration files to your liking.
You should change the secrets in ipsec.secrets
,
update rightsourceip=
and leftid=
in ipsec.conf
to match your network setup, and review the rules
in ipsec.d/firewall.updown
.
If running behind a router, you'll need to forward ports 500/udp and 4500udp. If you have a local firewall, you'll need to accept packets from ports 500/udp, 4500/udp, and possibly rotocol 50 (ESP), and protocol 51 (AH).
Also a caveat for docker hosts receiving their IP and
gateway from router advertisements. With IPv6 packet
forwarding enabled, advertisements are disabled unless
you set accept_ra=2
for your interface with sysctl or
in /etc/network/interfaces
.
Generate your certificate signing authority, server
certificate, and client certificate. Edit and run
the generate_certs.sh
script to generate the
necessary certificates and directories.
Running this particular Docker container typically requires
running with elevated privileges including --cap-add=NET_ADMIN
and --net=host
. It will have permission to modify your Docker
host's networking and iptables configuration.
Ensure the config folder is in your current directory ($PWD) and run:
docker run -d \
--cap-add=NET_ADMIN \
--net=host \
-v $PWD/config/strongswan.conf:/etc/strongswan.conf \
-v $PWD/config/ipsec.conf:/etc/ipsec.conf \
-v $PWD/config/ipsec.secrets:/etc/ipsec.secrets \
-v $PWD/config/ipsec.d:/etc/ipsec.d \
--name=strongswan \
stanback/alpine-strongswan-vpn
You can append arguments like start --nofork --debug
to
get debug output. Run --help
for list of arguments.
You may need to enable packet forwarding and ndp proxying on your docker host via sysctl or /etc/sysctl.conf:
sudo sysctl net.ipv4.ip_forward=1
sudo sysctl net.ipv6.conf.all.forwarding=1
sudo sysctl net.ipv6.conf.all.proxy_ndp=1
sudo iptables -A FORWARD -j ACCEPT
There are various ways to check on StrongSwan, including tailing
the Docker logging output (stdout/stderr), the ipsec
command,
and the swanctl
command:
docker logs -f --tail 100 strongswan
docker exec -it strongswan ipsec statusall
docker exec -it strongswan swanctl --list-sas
Crypto: IKEv2 AES256-SHA256-MODP2048
On OSX, you'll need to import and trust the client certificate
and the CA certificate from config/ipsec.d/cacerts/caCert.pem
and possibly the exported .p12 file if you are using
certificate-based authentication. For iOS, you can email yourself
the pem and .p12 and import them as a new profile onto the device.
- For eap password, select Username for the authentication type
- For eap cert, select Certificate for the authentication type
- For pubkey cert, select None for the authentication type and select cert
Crypto: IKEv2 AES256-SHA256-MODP1024
For Windows, you'll need to import the certificates into your trusted root CA store (Machine) from the exported .p12 file.
After creating the VPN connection, go to the properties for the network connection, click on the Networking tab, and go to the IPv4 connection properties. Click Advanced and check the box, "Use default gateway on remote network" to allow tunneling.
To enable IPv6 gateway you'll need aministrator access. Run
the first command to find your interface number (Idx
) which
should be named the same as the name of your VPN connection.
netsh int ipv6 show interfaces
netsh interface ipv6 add route ::/0 interface=INTERFACE_NUMBER
In Windows, modp2048 Diffie Hellman is disabled by default, you can change this behavior by creating or setting the following registry REG_DWORD to a (Hex) value of 0, 1 or 2. No reboot should be required.
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Rasman\Parameters\NegotiateDH2048_AES256
- 0 = disable (default)
- 1 = enable modp2048
- 2 = enforce modp2048 and aes-256-cbc
Crypto: IKEv2 AES256-SHA256-MODP2048
To setup, go to Settings -> General -> VPN. Add a new VPN configuration with type "IKEv2". Enter a description, server, remote ID, and local ID. Local ID should typically be your username. For authentication, you can select "Username" for EAP+mschapv2, "Certificate" for EAP+tls, or "None" for pubkey or PSK-based authentication.
Crypto: IKEv2 CHACHA20POLY1305-PRFSHA256-ECP256 (via strongSwan VPN Client)
Native Android VPN on Android 5 Lollipop and Andorid 6 Marshmallow is limited to IKEv1 which is not supported in this configuration.
Most users should consider using the excellent strongSwan VPN Client.
Crypto: IKEv2 CHACHA20POLY1305-PRFSHA256-NEWHOPE128
In addition to serving VPN connections, StrongSwan will act as a client. You can use this Docker image on Linux to act as a client (and it can act as a client and server simultaneously). (Note: You should only run one instance of the strongswan Docker container per host.)
To configure a StrongSwant client to be used with this Docker image,
you can use same configuration for the server (above), namely:
ipsec.conf
, ipsec.secrets
, strongswan.conf
, and any generated
cacerts and client certificates in ipsec.d/cacerts
and ipsec.d/certs
.
The ipsec.conf
file has rules for a client connection called
"home". If you haven't already, start up the Docker container the same
way you would when starting it for the server (above) and issue
commands such as the ones below to connect, check status, and
disconnect:
docker exec -it strongswan ipsec up home
docker exec -it strongswan ipsec status
docker exec -it strongswan ipsec down home
You can also choose to install the StrongSwan package from your
Linux distribution and use the files in config/
as a reference
for setting it up. If you're looking for a GUI, there's a
NetworkManager plugin (in Ubuntu, the package is called
network-manager-strongswan
).
This configuration attemps to balance higher grade ciphers with performance and compatibility with the lastest versions of OSX, Windows, Linux, and mobile devices. The list of ciphers is intentionally kept short, users can always modify the list if higher grade encryption is desired.
This build uses OpenSSL rather than LibreSSL in order to support the NIST Elliptic Curves (ecp256, etc). In addition, OpenSSL provides the same functionality provided by gmp.
I would love hearing any feedback regarding the ciphers or overall ways we can improve the current settings.
Useful resources: