By Justin Ellingwood and Namo
A virtual private network, or VPN, allows you to securely encrypt traffic as it travels through untrusted networks, such as those at the coffee shop, a conference, or an airport.
IKEv2, or Internet Key Exchange v2, is a protocol that allows for direct IPSec tunneling between the server and client. In IKEv2 VPN implementations, IPSec provides encryption for the network traffic. IKEv2 is natively supported on some platforms (OS X 10.11+, iOS 9.1+, and Windows 10) with no additional applications necessary, and it handles client hiccups quite smoothly.
In this tutorial, you’ll set up an IKEv2 VPN server using StrongSwan on an Ubuntu 18.04 server and connect to it from Windows, macOS, Ubuntu, iOS, and Android clients.
To complete this tutorial, you will need:
sudo
non-root user and a firewall.First, we’ll install StrongSwan, an open-source IPSec daemon which we’ll configure as our VPN server. We’ll also install the public key infrastructure component so that we can create a certificate authority to provide credentials for our infrastructure.
Update the local package cache and install the software by typing:
- sudo apt update
- sudo apt install strongswan strongswan-pki
Now that everything’s installed, let’s move on to creating our certificates.
An IKEv2 server requires a certificate to identify itself to clients. To help us create the certificate required, the strongswan-pki
package comes with a utility to generate a certificate authority and server certificates. To begin, let’s create a few directories to store all the assets we’ll be working on. The directory structure matches some of the directories in /etc/ipsec.d
, where we will eventually move all of the items we create. We’ll lock down the permissions so that our private files can’t be seen by other users:
- mkdir -p ~/pki/{cacerts,certs,private}
- chmod 700 ~/pki
Now that we have a directory structure to store everything, we can generate a root key. This will be a 4096-bit RSA key that will be used to sign our root certificate authority.
Execute these commands to generate the key:
- ipsec pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/ca-key.pem
Now that we have a key, we can move on to creating our root certificate authority, using the key to sign the root certificate:
- ipsec pki --self --ca --lifetime 3650 --in ~/pki/private/ca-key.pem \
- --type rsa --dn "CN=VPN root CA" --outform pem > ~/pki/cacerts/ca-cert.pem
You can change the distinguished name (DN) values to something else to if you would like. The common name here is just the indicator, so it doesn’t have to match anything in your infrastructure.
Now that we’ve got our root certificate authority up and running, we can create a certificate that the VPN server will use.
We’ll now create a certificate and key for the VPN server. This certificate will allow the client to verify the server’s authenticity using the CA certificate we just generated.
First, create a private key for the VPN server with the following command:
- ipsec pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/server-key.pem
Now, create and sign the VPN server certificate with the certificate authority’s key you created in the previous step. Execute the following command, but change the Common Name (CN) and the Subject Alternate Name (SAN) field to your VPN server’s DNS name or IP address:
- ipsec pki --pub --in ~/pki/private/server-key.pem --type rsa \
- | ipsec pki --issue --lifetime 1825 \
- --cacert ~/pki/cacerts/ca-cert.pem \
- --cakey ~/pki/private/ca-key.pem \
- --dn "CN=server_domain_or_IP" --san "server_domain_or_IP" \
- --flag serverAuth --flag ikeIntermediate --outform pem \
- > ~/pki/certs/server-cert.pem
Now that we’ve generated all of the TLS/SSL files StrongSwan needs, we can move the files into place in the /etc/ipsec.d
directory by typing:
- sudo cp -r ~/pki/* /etc/ipsec.d/
In this step, we’ve created a certificate pair that would be used to secure communications between the client and the server. We’ve also signed the certificates with the CA key, so the client will be able to verify the authenticity of the VPN server using the CA certificate. Now that have all of the certificates ready, we’ll move on to configuring the software.
StrongSwan has a default configuration file with some examples, but we will have to do most of the configuration ourselves. Let’s back up the file for reference before starting from scratch:
- sudo mv /etc/ipsec.conf{,.original}
Create and open a new blank configuration file by typing:
- sudo nano /etc/ipsec.conf
First, we’ll tell StrongSwan to log daemon statuses for debugging and allow duplicate connections. Add these lines to the file:
config setup
charondebug="ike 1, knl 1, cfg 0"
uniqueids=no
Then, we’ll create a configuration section for our VPN. We’ll also tell StrongSwan to create IKEv2 VPN Tunnels and to automatically load this configuration section when it starts up. Append the following lines to the file:
. . .
conn ikev2-vpn
auto=add
compress=no
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
We’ll also configure dead-peer detection to clear any “dangling” connections in case the client unexpectedly disconnects. Add these lines:
. . .
conn ikev2-vpn
. . .
dpdaction=clear
dpddelay=300s
rekey=no
Then, we’ll configure the server (left) side IPSec parameters. Add this to the file:
. . .
conn ikev2-vpn
. . .
left=%any
leftid=@server_domain_or_IP
leftcert=server-cert.pem
leftsendcert=always
leftsubnet=0.0.0.0/0
Note: When configuring the server ID (leftid
), only include the @
character if your VPN server will be identified by a domain name:
leftid=@vpn.example.com
If the server will be identified by its IP address, just put the IP address in:
leftid=203.0.113.7
Next, we can configure the client (right) side IPSec parameters, like the private IP address ranges and DNS servers to use:
. . .
conn ikev2-vpn
. . .
right=%any
rightid=%any
rightauth=eap-mschapv2
rightsourceip=10.10.10.0/24
rightdns=8.8.8.8,8.8.4.4
rightsendcert=never
Finally, we’ll tell StrongSwan to ask the client for user credentials when they connect:
. . .
conn ikev2-vpn
. . .
eap_identity=%identity
The configuration file should look like this:
config setup
charondebug="ike 1, knl 1, cfg 0"
uniqueids=no
conn ikev2-vpn
auto=add
compress=no
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
dpdaction=clear
dpddelay=300s
rekey=no
left=%any
leftid=@server_domain_or_IP
leftcert=server-cert.pem
leftsendcert=always
leftsubnet=0.0.0.0/0
right=%any
rightid=%any
rightauth=eap-mschapv2
rightsourceip=10.10.10.0/24
rightdns=8.8.8.8,8.8.4.4
rightsendcert=never
eap_identity=%identity
Save and close the file once you’ve verified that you’ve configured things as shown.
Now that we’ve configured the VPN parameters, let’s move on to creating an account so our users can connect to the server.
Our VPN server is now configured to accept client connections, but we don’t have any credentials configured yet. We’ll need to configure a couple things in a special configuration file called ipsec.secrets
:
Let’s open the secrets file for editing:
- sudo nano /etc/ipsec.secrets
First, we’ll tell StrongSwan where to find our private key:
: RSA "server-key.pem"
Then, we’ll define the user credentials. You can make up any username or password combination that you like:
your_username : EAP "your_password"
Save and close the file. Now that we’ve finished working with the VPN parameters, we’ll restart the VPN service so that our configuration is applied:
- sudo systemctl restart strongswan
Now that the VPN server has been fully configured with both server options and user credentials, it’s time to move on to configuring the most important part: the firewall.
With the StrongSwan configuration complete, we need to configure the firewall to forward and allow VPN traffic through.
If you followed the prerequisite tutorial, you should have a very basic UFW firewall enabled. If you don’t yet have UFW configured, you can create a baseline configuration and enable it by typing:
- sudo ufw allow OpenSSH
- sudo ufw enable
Now, add a rule to allow UDP traffic to the standard IPSec ports, 500 and 4500:
- sudo ufw allow 500,4500/udp
Next, we will open up one of UFW’s configuration files to add a few low-level policies for routing and forwarding IPSec packets. Before we do, we need to find which network interface on our server is used for internet access. We can find that by querying for the interface associated with the default route:
- ip route | grep default
Your public interface should follow the word “dev”. For example, this result shows the interface named eth0
, which is highlighted below:
Outputdefault via 203.0.113.7 dev eth0 proto static
When you have your public network interface, open the /etc/ufw/before.rules
file in your text editor:
- sudo nano /etc/ufw/before.rules
Near the top of the file (before the *filter
line), add the following configuration block:
*nat
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
COMMIT
*mangle
-A FORWARD --match policy --pol ipsec --dir in -s 10.10.10.0/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
. . .
Change each instance of eth0
in the above configuration to match the interface name you found with ip route
. The *nat
lines create rules so that the firewall can correctly route and manipulate traffic between the VPN clients and the internet. The *mangle
line adjusts the maximum packet segment size to prevent potential issues with certain VPN clients.
Next, after the *filter
and chain definition lines, add one more block of configuration:
. . .
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s 10.10.10.0/24 -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d 10.10.10.0/24 -j ACCEPT
These lines tell the firewall to forward ESP (Encapsulating Security Payload) traffic so the VPN clients will be able to connect. ESP provides additional security for our VPN packets as they’re traversing untrusted networks.
When you’re finished, save and close the file.
Before we restart the firewall, we’ll change some network kernel parameters to allow routing from one interface to another. Open UFW’s kernel parameters configuration file:
- sudo nano /etc/ufw/sysctl.conf
We’ll need to configure a few things here:
The changes you need to make to the file are highlighted in the following code:
. . .
# Enable forwarding
# Uncomment the following line
net/ipv4/ip_forward=1
. . .
# Do not accept ICMP redirects (prevent MITM attacks)
# Ensure the following line is set
net/ipv4/conf/all/accept_redirects=0
# Do not send ICMP redirects (we are not a router)
# Add the following lines
net/ipv4/conf/all/send_redirects=0
net/ipv4/ip_no_pmtu_disc=1
Save the file when you are finished. UFW will apply these changes the next time it starts.
Now, we can enable all of our changes by disabling and re-enabling the firewall:
- sudo ufw disable
- sudo ufw enable
You’ll be prompted to confirm the process. Type Y
to enable UFW again with the new settings.
Now that you have everything set up, it’s time to try it out. First, you’ll need to copy the CA certificate you created and install it on your client device(s) that will connect to the VPN. The easiest way to do this is to log into your server and output the contents of the certificate file:
- cat /etc/ipsec.d/cacerts/ca-cert.pem
You’ll see output similar to this:
Output-----BEGIN CERTIFICATE-----
MIIFQjCCAyqgAwIBAgIIFkQGvkH4ej0wDQYJKoZIhvcNAQEMBQAwPzELMAkGA1UE
. . .
EwbVLOXcNduWK2TPbk/+82GRMtjftran6hKbpKGghBVDPVFGFT6Z0OfubpkQ9RsQ
BayqOb/Q
-----END CERTIFICATE-----
Copy this output to your computer, including the -----BEGIN CERTIFICATE-----
and -----END CERTIFICATE-----
lines, and save it to a file with a recognizable name, such as ca-cert.pem
. Ensure the file you create has the .pem
extension.
Alternatively, use SFTP to transfer the file to your computer.
Once you have the ca-cert.pem
file downloaded to your computer, you can set up the connection to the VPN.
First, import the root certificate by following these steps:
Press WINDOWS+R
to bring up the Run dialog, and enter mmc.exe
to launch the Windows Management Console.
From the File menu, navigate to Add or Remove Snap-in, select Certificates from the list of available snap-ins, and click Add.
We want the VPN to work with any user, so select Computer Account and click Next.
We’re configuring things on the local computer, so select Local Computer, then click Finish.
Under the Console Root node, expand the Certificates (Local Computer) entry, expand Trusted Root Certification Authorities, and then select the Certificates entry:
From the Action menu, select All Tasks and click Import to display the Certificate Import Wizard. Click Next to move past the introduction.
On the File to Import screen, press the Browse button and select the certificate file that you’ve saved. Then click Next.
Ensure that the Certificate Store is set to Trusted Root Certification Authorities, and click Next.
Click Finish to import the certificate.
Then configure the VPN with these steps:
Your new VPN connection will be visible under the list of networks. Select the VPN and click Connect. You’ll be prompted for your username and password. Type them in, click OK, and you’ll be connected.
Follow these steps to import the certificate:
Now that the certificate is important and trusted, configure the VPN connection with these steps:
Finally, click on Connect to connect to the VPN. You should now be connected to the VPN.
To connect from an Ubuntu machine, you can set up and manage StrongSwan as a service or use a one-off command every time you wish to connect. Instructions are provided for both.
sudo apt update
sudo apt install strongswan libcharon-extra-plugins
/etc/ipsec.d/cacerts
directory: sudo cp /tmp/ca-cert.pem /etc/ipsec.d/cacerts
sudo systemctl disable --now strongswan
/etc/ipsec.secrets
file: your_username : EAP "your_password"
/etc/ipsec.conf
file to define your configuration.config setup
conn ikev2-rw
right=server_domain_or_IP
# This should match the `leftid` value on your server's configuration
rightid=server_domain_or_IP
rightsubnet=0.0.0.0/0
rightauth=pubkey
leftsourceip=%config
leftid=username
leftauth=eap-mschapv2
eap_identity=%identity
auto=start
To connect to the VPN, type:
- sudo systemctl start strongswan
To disconnect again, type:
- sudo systemctl stop strongswan
sudo apt update
charon-cmd
and related software sudo apt install charon-cmd libcharon-extra-plugins
cd <^>/path/to/ca-cert.pem
charon-cmd
using the server’s CA certificate, the VPN server’s IP address, and the username you configured: sudo charon-cmd --cert ca-cert.pem --host vpn_domain_or_IP --identity your_username
You should now be connected to the VPN. To disconnect, press CTRL+C
and wait for the connection to close.
To configure the VPN connection on an iOS device, follow these steps:
Follow these steps to import the certificate:
Now that the certificate is imported into the StrongSwan app, you can configure the VPN connection with these steps:
When you wish to connect to the VPN, click on profile you just created in the StrongSwan application.
If you are unable to import the certificate, ensure the file has the .pem
extension, and not .pem.txt
.
If you’re unable to connect to the VPN, check the server name or IP address you used. The server’s domain name or IP address must match what you’ve configured as the common name (CN) while creating the certificate. If they don’t match, the VPN connection won’t work. If you set up a certificate with the CN of vpn.example.com
, you must use vpn.example.com
when you enter the VPN server details. Double-check the command you used to generate the certificate, and the values you used when creating your VPN connection.
Finally, double-check the VPN configuration to ensure the leftid
value is configured with the @
symbol if you’re using a domain name:
leftid=@vpn.example.com
And if you’re using an IP address, ensure that the @
symbol is omitted.
In this tutorial, you’ve built a VPN server that uses the IKEv2 protocol. Now you can be assured that your online activities will remain secure wherever you go!
To add or remove users, just take a look at Step 5 again. Each line is for one user, so adding or removing users is as simple as editing the file.
From here, you might want to look into setting up a log file analyzer, because StrongSwan dumps its logs into syslog. The tutorial How To Install and Use Logwatch Log Analyzer and Reporter on a VPS has more information on setting that up.
You might also be interested in this guide from the EFF about online privacy.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Former Senior Technical Writer at DigitalOcean, specializing in DevOps topics across multiple Linux distributions, including Ubuntu 18.04, 20.04, 22.04, as well as Debian 10 and 11.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Fix this line please:
sudo ufw allow OpenVPN
to this one:
sudo ufw allow OpenSSH
Works like a charm for my windows clients. But i´m having issues with my iOS device.
Jul 23 10:03:40 vserver charon: 08[NET] received packet: from *iosIP*[29314] to *serverIP*[500] (604 bytes)
Jul 23 10:03:40 vserver charon: 08[NET] received packet: from *iosIP*[29314] to *serverIP*[500] (604 bytes)
Jul 23 10:03:40 vserver charon: 08[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(REDIR_SUP) N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) ]
Jul 23 10:03:40 vserver charon: 08[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(REDIR_SUP) N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) ]
Jul 23 10:03:40 vserver charon: 08[IKE] *iosIP* is initiating an IKE_SA
Jul 23 10:03:40 vserver charon: 08[IKE] *iosIP* is initiating an IKE_SA
Jul 23 10:03:40 vserver charon: 08[IKE] remote host is behind NAT
Jul 23 10:03:40 vserver charon: 08[IKE] remote host is behind NAT
Jul 23 10:03:40 vserver charon: 08[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(MULT_AUTH) ]
Jul 23 10:03:40 vserver charon: 08[NET] sending packet: from *serverIP*[500] to *iosIP*[29314] (448 bytes)
Jul 23 10:03:40 vserver charon: 08[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(MULT_AUTH) ]
Jul 23 10:03:40 vserver charon: 08[NET] sending packet: from *serverIP*[500] to *iosIP*[29314] (448 bytes)
Jul 23 10:03:40 vserver charon: 09[NET] received packet: from *iosIP*[26929] to *serverIP*[4500] (512 bytes)
Jul 23 10:03:40 vserver charon: 09[NET] received packet: from *iosIP*[26929] to *serverIP*[4500] (512 bytes)
Jul 23 10:03:40 vserver charon: 09[ENC] unknown attribute type (25)
Jul 23 10:03:40 vserver charon: 09[ENC] unknown attribute type (25)
Jul 23 10:03:40 vserver charon: 09[ENC] parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) N(MOBIKE_SUP) IDr CPRQ(ADDR DHCP DNS MASK ADDR6 DHCP6 DNS6 (25)) N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) SA TSi TSr ]
Jul 23 10:03:40 vserver charon: 09[ENC] parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) N(MOBIKE_SUP) IDr CPRQ(ADDR DHCP DNS MASK ADDR6 DHCP6 DNS6 (25)) N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) SA TSi TSr ]
Jul 23 10:03:40 vserver charon: 09[IKE] received ESP_TFC_PADDING_NOT_SUPPORTED, not using ESPv3 TFC padding
Jul 23 10:03:40 vserver charon: 09[IKE] received ESP_TFC_PADDING_NOT_SUPPORTED, not using ESPv3 TFC padding
Jul 23 10:03:40 vserver charon: 09[IKE] peer supports MOBIKE
Jul 23 10:03:40 vserver charon: 09[IKE] peer supports MOBIKE
Jul 23 10:03:40 vserver charon: 09[ENC] generating IKE_AUTH response 1 [ N(AUTH_FAILED) ]
Jul 23 10:03:40 vserver charon: 09[ENC] generating IKE_AUTH response 1 [ N(AUTH_FAILED) ]
Jul 23 10:03:40 vserver charon: 09[NET] sending packet: from *serverIP*[4500] to *iosIP*[26929] (80 bytes)
Jul 23 10:03:40 vserver charon: 09[NET] sending packet: from *serverIP*[4500] to *iosIP*[26929] (80 bytes)
Any idea?
Would you mind adding instructions for making IPv6 functional? I’ve tried workarounds and they don’t work, and I’d love to have phones on my VPN. But I can’t because they all use IPv6, and I can’t figure out the ip6tables rules for that to function.
This comment has been deleted
This fails to authenticate for MacOS and iOS both.
charon: 08[ENC] generating IKE_AUTH response 1 [ N(AUTH_FAILED) ]
I have tried this on a fresh ubuntu 18.04 droplet with windows 10/7 and iOS device as clients.
I have to add following lines to /etc/ipsec.conf
to make windows 10/7 connect:
ike=aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
esp=aes256-sha256,aes256-sha1,3des-sha1!
And I still have a weird behavior on windows: The password is already saved but will always be asked again while connecting. And if tried with command “rasdial <VPN NAME>”, an error 645 will occur.
It seems the EAP authentication is failed the first time and on the server side when this happens, you could see in log:
Aug 5 09:57:23 testserver charon: 09[ENC] parsed IKE_AUTH request 2 [ EAP/RES/MSCHAPV2 ]
Aug 5 09:57:23 testserver charon: 09[IKE] EAP-MS-CHAPv2 username: '%any'
Aug 5 09:57:23 testserver charon: 09[IKE] no EAP key found for hosts '%any' - '%any'
Aug 5 09:57:23 testserver charon: 09[IKE] EAP-MS-CHAPv2 verification failed, retry (1)
Don’t know whether it is a windows problem or a bug in strongswan …
very clever tutorial. this is good way to have better vpn service and lower price
Both my lastest macOS(v10.13.6) and LG V20(android 7.0) show connected, but all web page & app no response from network. I reinstall droplet and then follow steps in this tutorial & prerequisites except enable firewall.
Chrome shows: DNS_PROBE_FINISHED_NO_INTERNET
Potentially naive question. Would you have to configure multiple certificates or multiple users when connecting with two devices simultaneously? When I connect with both my Android phone and my Linux laptop, it seems like only the phone is working. When I do ipsec staus on my droplet, it says that only one Security Association is up, even though both clients think they’re connected (though one appears not to be working). Additionally, the logs and network info for both seem to indicate that they have been assigned the same virtual IP.
So essentially the question is, can I run through this tutorial once, and use same config/cert for simultaneous connections on different machines?
When connecting from Windows 10 using the above configuration and setup, you will be unable to connect due to the 4096-bit cert encryption scheme used. Windows only supports 1024-bit max by default. However, we can up that to 2048-bit, as long as you make sure you add this registry value:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Rasman\Parameters
[Type] Key Name: [DWORD 32bit] NegotiateDH2048_AES256
Value: 1
Further, you must recreate you root CA cert and your private key cert with 2048 instead of 4096. Then sign the new private key with the root CA cert. Then you need to delete the old root CA cert your imported into Windows and replace it with the 2048-bit version.
Thankfully, a bit of Googling helped me out here, but I don’t want others to have to go through the headache that I did.
Also, if your VPN server is behind a firewall, make sure you forward the ports 500 and 4500 UDP to your server. Make sure IPSec passthrough is enabled too.
When adding users to /etc/ipsec.secrets (one each line, same format as the original), you need to restart strong swan for it to notice the addition (and probably any changes).
Can I use this setup (with changes ofc) to connect multiple clients with possibility of communication for clients?
I try to change leftsubnet option and add rightsubnet option, but it is not helps.
I want to connect few clients (alice-10.10.10.2 bob-10.10.10.3) and want ping bob from alice
First of all, thank you very much for this really useful tutorial. Everything is working fine exactly as expected. However I’m also trying to have RoadWarriors using IPv6 services (web, etc) and this is not working. On top of everything in this tutorial, I managed to get my iOS 12 client to get an IPv6 address however, all IPv4 traffic works fine but IPv6 doesn’t work (i.e. websites on IPv4 load properly but websites on IPv6, like ipv6.google.com, don’t load at all). Any chance of an update to this tutorial so that this important topic of IPv6 is addressed? It would be amazing to have IPv6 working on iOS or Android clients.
Thanks in advance! Regards
I’m having issues with this. I setup everything as shown, and heck, even tried some suggestions in the comments. However, no matter what I do, my Mac, iPhone, and iPad all can’t connect. They say that the authentication failed, which makes absolutely no sense. The login info was copied and pasted on my Mac, anyways, and it’s so simple, messing up with be laughably hard ( the username and password are under 12 characters TOGETHER ).
The syslog file doesn’t seem to be giving anything useful, in fact, from what I see ( and others who’ve I tried asking for help ) it appears to be successful. Maybe somebody here can help. I tried it with my firewall enabled. but I disabled it now. I didn’t have it on in the first place.
The output when trying to connect in syslog
Nov 8 21:07:40 MEMail charon: 11[NET] received packet: from 68.175.135.232[500] to 68.183.16.15[500] (604 bytes)
Nov 8 21:07:40 MEMail charon: 11[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(REDIR_SUP) N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) ]
Nov 8 21:07:40 MEMail charon: 11[IKE] 68.175.135.232 is initiating an IKE_SA
Nov 8 21:07:40 MEMail charon: 11[IKE] remote host is behind NAT
Nov 8 21:07:40 MEMail charon: 11[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(MULT_AUTH) ]
Nov 8 21:07:40 MEMail charon: 11[NET] sending packet: from 68.183.16.15[500] to 68.175.135.232[500] (448 bytes)
Nov 8 21:07:40 MEMail charon: 12[NET] received packet: from 68.175.135.232[4500] to 68.183.16.15[4500] (512 bytes)
Nov 8 21:07:40 MEMail charon: 12[ENC] unknown attribute type (25)
Nov 8 21:07:40 MEMail charon: 12[ENC] parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) N(MOBIKE_SUP) IDr CPRQ(ADDR DHCP DNS MASK ADDR6 DHCP6 DNS6 (25)) N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) SA TSi TSr ]
Nov 8 21:07:40 MEMail charon: 12[CFG] looking for peer configs matching 68.183.16.15[meproduction.org]...68.175.135.232[192.168.1.27]
Nov 8 21:07:40 MEMail charon: 12[CFG] selected peer config 'ikev2-vpn'
Nov 8 21:07:40 MEMail charon: 12[IKE] initiating EAP_IDENTITY method (id 0x00)
Nov 8 21:07:40 MEMail charon: 12[IKE] received ESP_TFC_PADDING_NOT_SUPPORTED, not using ESPv3 TFC padding
Nov 8 21:07:40 MEMail charon: 12[IKE] peer supports MOBIKE
Nov 8 21:07:40 MEMail charon: 12[IKE] authentication of 'meproduction.org' (myself) with RSA signature successful
Nov 8 21:07:40 MEMail charon: 12[IKE] sending end entity cert "CN=meproduction.org"
Nov 8 21:07:40 MEMail charon: 12[ENC] generating IKE_AUTH response 1 [ IDr CERT AUTH EAP/REQ/ID ]
Nov 8 21:07:40 MEMail charon: 12[ENC] splitting IKE message with length of 1936 bytes into 2 fragments
Nov 8 21:07:40 MEMail charon: 12[ENC] generating IKE_AUTH response 1 [ EF(1/2) ]
Nov 8 21:07:40 MEMail charon: 12[ENC] generating IKE_AUTH response 1 [ EF(2/2) ]
Nov 8 21:07:40 MEMail charon: 12[NET] sending packet: from 68.183.16.15[4500] to 68.175.135.232[4500] (1236 bytes)
Nov 8 21:07:40 MEMail charon: 12[NET] sending packet: from 68.183.16.15[4500] to 68.175.135.232[4500] (772 bytes)
No clue what’s going on. If somebody can at least try to help me out, I’d really appreciate it.
how can i setup the same thing but instead of using a certificate file for authentication, i want to use a pre-shared key, username and password?
Got this working on Ubuntu 18.04, with a MacOS 10.14.1 (Mojave) client, but noticed two issues:
“Failed to receive isakmp packet: Network is unreachable” “Failed to receive isakmp packet: Connection refused”
After about 10-20 seconds, the connection becomes stable, though it continues to reconnect every 5 minutes or so. Any idea what’s causing this? I’d set this up before on Sierra (with the same guide), and never saw this behavior.
PS: Also, my primary reason to setup VPN on my droplet was to create a gateway to connect to all servers that have Private Networking enabled. I realized I needed to duplicate the ufw rules for the public interface to also specify the private one, but might be useful to add a tip about that for others looking to do the same.
Hello, Extremely good tutorial for setting up strong swan IPSec server on Linux. It worked absolutely fine for username and password based authentication.
I would like to change the authentication to certificate based. Can you help me with that ? or can your point me to other resources for certificate based authentication.
Thanks a lot
Hi. If I use ipsec.conf from this article, my ios device disconnects after a few minutes of inactivity. But what if I want it to stay connected for a few days even if I don’t use it all night?
Hello,
Thanks for the howto.
Currently, I’m running into the following issue:
opening ‘~/pki/private/server-key.pem’ failed: No such file or directory building CRED_PRIVATE_KEY - RSA failed, tried 9 builders parsing private key failed building CRED_PUBLIC_KEY - ANY failed, tried 6 builders parsing public key failed
Does anyone have this issue? How to solve it?
A note on connecting from Windows using the server’s IP address (as opposed to DNS name).
https://wiki.strongswan.org/projects/strongswan/wiki/Win7CertReq
If you intend to use IP addresses instead of host names with Windows clients, add them in a subjectAltName of type dNSName (i.e. DNS:x.x.x.x) and not one of type iPAddress (i.e. IP:x.x.x.x). The client will throw a 13801 error if this is not met. The same applies to some versions of Apple’s iOS/Mac OS X when using EAP-TLS, which will fail with error 1001 -9807.
And so, in server certificate generation command, this
--san "server_domain_or_IP"
should probably be replaced with this, specifically in case of connecting to server by its IP address:
--san "server_IP" --san "@server_IP"
This will record the server’s IP address as both IP: and DNS: in the certificate’s subjectAltNames, as explained in the strongSwan WIKI.
I was struggling interconnecting two Ubuntu 18.04 servers. After an hour of debugging I found that I needed to install libcharon-standard-plugins
both on client and server to be able to connect.
rekey=no
This line should be removed as when it was on my IPsec connect frequently got lost.
how can i create this kind of vpn for multiple user, or can i use this kind of vpn with one account and multiple devices at the same time?
This comment has been deleted
One step is missing
set DEFAULT_FORWARD_POLICY=“ACCEPT” in /etc/default/ufw
Great article, thank you!
One thing to remember on Win10, is if you want the Default Route to be passed to Win10, you must make that configuration change in the adapter GUI screens to accept remote network default gateway.
For those who have problems with macOS. In my case the problem was that the OS did not trust the certificate. By default, if you double-click the certificate file, it will just be added to the keychain. To trust it, you need to manually find it in the keychain, open its preferences and set “Always Trust”. I also used System keychain instead of login, but I think either is fine. The difference seems to be applying the certificate for all users or for current. iOS worked from the first time (it makes you trust the cert if you add it).
You guys (the authors) are ABSOLUTE LEGENDs!
After coming to China I badly needed a VPN because I needed proper English search engines to do my work. None of the commercial VPN services were working (including Nord, IPVanish and ExpressVPN). So I wanted to setup mine and came across this tutorial.
There were some issues with my Windows Setup and had to add the following two lines to ipsec.conf
ike=aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
esp=aes256-sha256,aes256-sha1,3des-sha1!
This tutorial is written brilliantly and I thank you both for your contribution.
Keep up the awesome work! Cheers.
Hi,
I can’t connect my clients to the VPN. I can’t figure out what i’ve miconfigured. Could you help me please ?
journalctl give me this :
sept. 24 13:32:47 strongswan charon[1396]: 01[NET] received packet: from 80.12.89.53[34693] to 10.0.0.249[500] (1116 bytes) sept. 24 13:32:47 strongswan charon[1396]: 01[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) ] sept. 24 13:32:47 strongswan charon[1396]: 01[IKE] 80.12.89.53 is initiating an IKE_SA sept. 24 13:32:47 strongswan charon[1396]: 01[IKE] 80.12.89.53 is initiating an IKE_SA sept. 24 13:32:47 strongswan charon[1396]: 01[IKE] local host is behind NAT, sending keep alives sept. 24 13:32:47 strongswan charon[1396]: 01[IKE] remote host is behind NAT sept. 24 13:32:47 strongswan charon[1396]: 01[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(MULT_AUTH) ] sept. 24 13:32:47 strongswan charon[1396]: 01[NET] sending packet: from 10.0.0.249[500] to 80.12.89.53[34693] (272 bytes) sept. 24 13:32:47 strongswan charon[1396]: 04[NET] received packet: from 80.12.89.53[58503] to 10.0.0.249[4500] (320 bytes) sept. 24 13:32:47 strongswan charon[1396]: 04[ENC] parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) CERTREQ CPRQ(ADDR DNS NBNS) SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ] sept. 24 13:32:47 strongswan charon[1396]: 04[IKE] received cert request for “CN=VPN root CA” sept. 24 13:32:47 strongswan charon[1396]: 04[IKE] initiating EAP_IDENTITY method (id 0x00) sept. 24 13:32:47 strongswan charon[1396]: 04[IKE] peer supports MOBIKE sept. 24 13:32:47 strongswan charon[1396]: 04[IKE] authentication of ‘10.0.0.249’ (myself) with RSA_EMSA_PKCS1_SHA2_384 successful sept. 24 13:32:47 strongswan charon[1396]: 04[ENC] generating IKE_AUTH response 1 [ IDr AUTH EAP/REQ/ID ] sept. 24 13:32:47 strongswan charon[1396]: 04[NET] sending packet: from 10.0.0.249[4500] to 80.12.89.53[58503] (624 bytes) sept. 24 13:32:47 strongswan charon[1396]: 06[NET] received packet: from 80.12.89.53[58503] to 10.0.0.249[4500] (80 bytes) sept. 24 13:32:47 strongswan charon[1396]: 06[ENC] parsed INFORMATIONAL request 2 [ N(AUTH_FAILED) ] sept. 24 13:32:47 strongswan charon[1396]: 06[ENC] generating INFORMATIONAL response 2 [ N(AUTH_FAILED) ] sept. 24 13:32:47 strongswan charon[1396]: 06[NET] sending packet: from 10.0.0.249[4500] to 80.12.89.53[58503] (80 bytes)
and there’s my /etc/ipsec.conf
#log daemon statuses for debugging and allow duplicate
config setup charondebug=“ike 1, knl 1, cfg 0” uniqueids=no
#configuration section for VPN
conn ikev2-vpn auto=add compress=no type=tunnel keyexchange=ikev2 fragmentation=yes forceencaps=yes dpdaction=clear dpddelay=300s rekey=no left=%any leftid=10.0.0.249 leftcert=server-cert.pem leftsendcert=never leftsubnet=10.0.0.0/21 right=%any rightid=%any rightauth=eap-mschapv2 rightsourceip=10.0.3.0/27 rightdns=8.8.8.8,8.8.4.4,10.0.0.1,10.0.0.2 rightsendcert=never eap_identity=%identity
my strongswan server is behind a pfsense with correct NAT rules Thanks
Please fix the line in Step 3 to create and sign the VPN server certificate. If you’ve got an error “supplied --dn is not a distinguished name” you should type “–dn “CN=something” --san “CN=something”” instead of “–dn “something” --san “something””.
● strongswan.service - strongSwan IPsec IKEv1/IKEv2 daemon using ipsec.conf
Loaded: loaded (/lib/systemd/system/strongswan.service; enabled; vendor prese
Active: inactive (dead) since Thu 2020-01-02 16:36:14 KST; 46min ago
Process: 16410 ExecStart=/usr/sbin/ipsec start --nofork (code=exited, status=0
Main PID: 16410 (code=exited, status=0/SUCCESS)
I don’t know why this happens all the time
when I run the strongswan with the code
systemctl start strongswan
It still doesn’t work at all
Hello,
This config works fine for me, i was able to establish a connection. the only issue i am having is that after the connection is established and i tried to check my ip-address, i am still seeing the ip-address of my home network instead of the ip-address of the server. Please what would you suggest i do in other to fix this issue. Thanks
Why am I getting “E: Unable to locate package strongswan-pki” error while trying to run “sudo apt install strongswan strongswan-pki” in command line?
Cannot ping any local resources. Just local address of server (192.168.0.210) nothing else. How i can fix it?
How can I do implement CA certificate on server instead of client, I mean user ables to connect without install CA cert on his device…
Thanks very much. It almost worked for me but I had to remove the two last lines inside the ipsec.conf that appears in the file after the installation.
ike=chacha20poly1305-sha512-curve25519-prfsha512,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
esp=chacha20poly1304-sha512,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,3des-sha1!
Good tutorial, I would add that for IOS you need to import the ca-cert.pem before attempting to connect. Otherwise will fail.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.