This is a guide that I’ve put together using various different articles and tutorials I’ve found and put them all together in one package.
The end result is your very own private VPN server running off of your OpenWRT 15.05.01 router using RSA certificates for authentication. With a few small tweaks you can use username/password log authentication but I preferred to go the certificates route. These steps should work fine with most modern clients – I have personally tested this with Windows 10 (Version 1607 OS Build 14393.10) and on iOS 9.3.4 both with and without certificates and it works great.
First and foremost, you need to be running OpenWRT (https://openwrt.org/) on your router. Installing OpenWRT is out of the scope for this guide, so please do your research for getting it onto your device – it’s very straight forward.
Also, make sure that you have enough space on router’s flash memory, most routers do not come with very much now a days, but if you have a USB port, you can easily add an extra 8GB (or more) as storage.
Install strongswan-full and openssl-util
We will need to install both StrongSwan and OpenSSL (to generate certificates) onto the router. SSH into your router and run the following command:
This will refresh your software repository lists. Once that has completed, install strongswan-full and openssl-util by running the following command in your shell:
opkg install strongswan-full openssl-util
Let’s run a quick test to make sure StrongSwan install correctly:
You should see:
Linux strongSwan U5.3.3/K3.18.23
Institute for Internet Technologies and Applications
University of Applied Sciences Rapperswil, Switzerland
See 'ipsec --copyright' for copyright information.
Generating Your Certificates
The tricky part with setting up StrongSwan is in the generation of your certificates. I’ve tried to make this as easy and compatible as possible.
CA Root Certificate/Key
- The commands below will generate a self-signed CA certificate (
CA_CERT.pem) and a CA private key (
- You should change the country (C), organization (O) and common name (CN) to your own values.
- This certificate will be valid for 10 years, but you can adjust that by changing the
--lifetime 3650value to something else, in days.
ipsec pki --gen --type rsa --size 4096 --outform pem > private/CA_KEY.pem
chmod 600 private/CA_KEY.pem
ipsec pki --self --ca --lifetime 3650 --in private/CA_KEY.pem --type rsa --dn "C=CA, O=blog.nicktamm.com, CN=vpn.blog.nicktamm.com Root CA" --outform pem > cacerts/CA_CERT.pem
Server (router) Certificate/Key
- The commands below will generate a server (i.e. your router) certificate (
SERVER_CERT.pem) and a server private key (
- Important note: the command name (
CN=) must be either the hostname or IP of your VPN server. If you do not set this correctly, the VPN connection will not be established. You will also need to adjust the
--sanvalue to match what you enter in the CN.
- This certificate is valid for 2 years, which can be changed by adjusting the
ipsec pki --gen --type rsa --size 2048 --outform pem > private/SERVER_KEY.pem
chmod 600 private/SERVER_KEY.pem
ipsec pki --pub --in private/SERVER_KEY.pem --type rsa | ipsec pki --issue --lifetime 730 --cacert cacerts/CA_CERT.pem --cakey private/CA_KEY.pem --dn "C=CA, O=blog.nicktamm.com, CN=vpn.blog.nicktamm.com" --san vpn.blog.nicktamm.com --flag serverAuth --flag ikeIntermediate --outform pem > certs/SERVER_CERT.pem
- The commands below will generate a client certificate (
CLIENT_CERT.pem) and a server private key (
--san [email protected]value needs to be named after the name of the device you are generating your certificate for. For example, if my machine name is
GHOSTI will need to adjust the san setting to
--san [email protected]. This is especially important for iOS devices.
- The CN value should also be changed to match whatever you entered for the san
- You will need to repeat these steps for each client that you want to connect to your VPN.
ipsec pki --gen --type rsa --size 2048 --outform pem > private/CLIENT_KEY.pem
chmod 600 private/CLIENT_KEY.pem
ipsec pki --pub --in private/CLIENT_KEY.pem --type rsa | ipsec pki --issue --lifetime 730 --cacert cacerts/CA_CERT.pem --cakey private/CA_KEY.pem --dn "C=CA, O=blog.nicktamm.com, [email protected]" --san CLIENT@vpn.blog.nicktamm.com --outform pem > certs/CLIENT_CERT.pem
- This is the last certificate that we will need to generate. This will be the certificate that you deliver to each client that is going to connect to your VPN.
- This will contain the client certificate, client key and the CA certificate in one package. Again, you will need to generate this for each client.
- For added security, you will need to add a password when generating this certificate. This password will be asked for when importing the certificate on your client.
openssl pkcs12 -export -inkey private/CLIENT_KEY.pem -in certs/CLIENT_CERT.pem -name "vpn.blog.nicktamm.com VPN Certificate" -certfile cacerts/CA_CERT.pem -caname "vpn.blog.nicktamm.com Root CA" -out CLIENT.p12
Ok! Now we have all our certificates generated. One VERY important thing you need to do is to copy the
CA_KEY.pem to a safe location and delete it from the router, located in
etc/ipsec.d/private. If someone were to get a hold of your CA key, they could generate their own certificates for use on your VPN essentially compromising the entire security of your VPN/network.
VPN Server Configuration
Now we will begin configuring the server (router in this case) to work with the VPN as well as make the necessary adjustments to the firewall.
There are 2 main files that we will be working with,
ipsec.conf which handles the main configuration settings for our VPN and
ipsec.secrets which contains any username/passwords and private key information. These files can be located in the
Below is the
ipsec.conf file that we are going to use.
There is a lot here, but I will be reviewing the important parts that need to be changed. For more information on these options, see https://libreswan.org/man/ipsec.conf.5.html
# ipsec.conf - strongSwan IPsec configuration file
charondebug="cfg 2, dmn 2, ike 2, net 2"
Ok, let’s look at that we need to adjust.
leftid=vpn.blog.nicktamm.com– This needs to be changed to the IP/hostname of your server. This should match the
--sanvalue you entered for the
leftcert=SERVER_CERT.pem– Change this to match the named of your
rightdns=10.2.3.4,18.104.22.168,22.214.171.124– The first IP,
126.96.36.199should be changed to match your router’s DNS IP address. This is necessary if you want to be able to access any resources on your LAN. IF you do not want to access your LAN, simply remove this entry.
rightsourceip=188.8.131.52/24– You will need to adjust this to match the IP range that you want the VPN to use. A few things to note:
- This IP range should be somewhere outside of your IP addresses on your LAN. For example, if you LAN is in the 184.108.40.206/24 range, you could change this to 10.2.1.0/24 range. This however will not allow you to resolve hostnames on your LAN when connected to the VPN.
- If however you want seamless access on your LAN, you can enter your current assigned IP range but change the octet. For example, if you current IP range is 10.1.1.0/24, change it to 10.1.200./24. The only downside is that you may run into an IP conflict. An alternative to this would be to simply use a host file to map the IP(s) to hostname(s).
This file is where the private keys are loaded. Simply modify the file to match your private keys as shown in the example files below:
# 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. Suitable public keys, for ipsec.conf, DNS,
# or configuration of other implementations, can be extracted conveniently
# with "ipsec showhostkey".
# To reload, type ipsec rereadsecrets
: RSA SERVER_KEY.pem
: RSA CLIENT_KEY.pem
Now it’s time to modify the firewall.
First, we need to allow the VPN to connect from the WAN. To do this, edit
etc/config/firewall and add the following:
# Allow VPN from WAN
option src wan
option proto esp
option target ACCEPT config rule option src wan option proto udp option dest_port 500 option target ACCEPT config rule option src wan option proto udp option dest_port 4500 option target ACCEPT config rule option src wan option proto ah option target ACCEPT
Next, you want to make sure the VPN is correctly routing the VPN tunnel. To do this, edit the
etc/sysctl.conf and add the following:
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
Lastly, if you have a restrictive firewall, you can add these lines to the
iptables -A INPUT -p udp --dport 500 --j ACCEPT
iptables -A INPUT -p udp --dport 4500 --j ACCEPT
iptables -A INPUT -p esp -j ACCEPT
That should be it for the firewall! Go ahead and reboot your router now.
Once your router is back online, we can start to get everything up and running. Since we modified the
ipsec.secrets file, let’s reload it. This is done by typing the following in your shell:
Now, we want to get the VPN actually working. We will turn it on but allow the output to be displayed on-screen. The command you want to run is:
ipsec start --nofork
We can now begin finalizing the setup and setting up our clients.
For this VPN, we will setup two clients – a Windows 10 PC and an iPhone. Let’s start with the PC.
Adding Certificates to the Certificate Store
First, we will need to import our certificates into the certificate store.
- Right-click on the Start button and select
Run. Type in
mmc.exeand the press
- Go to
File > Add/Remove Snap-in....
Certificatesthen click on the
My user accountfollowed by
Console Root, expand
Certificates - Current User > Personal > Certificates.
- Right-click on
All Tasks > Import...
- Browse to the location where you saved you
.p12file then click on
- Here you will be asked to enter the password you created when generating your
.p12file. Also remember to check the
Mark this key as exportableoption in case you need to export it in the future then click
- You will be asked which store you want to place the certificates into – select
Personalthen click on
- You will now have two certificates imported into the
Personalstore – your CA certificate and your client certificate with private key.
- Drag the CA certificate to
Trusted Root Certification Authorities > Certificates. You will be asked if you want to install the certificate here – click on
- Now, close down your
mmcconsole and open a new one, but this time select
Computer account > Local computer.
- Repeat the same steps as above, but when you have finished importing your certificates, delete the Client certificate and move the CA certificate into the
Trusted Root Certification Authorities > Certificates.
Configuring the Windows 10 VPN Client
Almost done! We can now configure the Windows 10 VPN client and test our connection.
- Click on the
Startbutton and begin typing
VPNto bring up the
Change virtual private networks (VPN)option.
- Click on
Add a VPN connectionand enter in the following settings:
- VPN Provider: Windows (built-in)
- Connection name: A name for your connection
- Server name or address: The hostname/IP of your VPN server
- VPN type: IKEv2
- Type of sign-in info: Certificate
- Click on the
Startbutton and type
Control Panelto open the
Control Paneland navigate to
Network and Sharing Center > Change adapter settings.
- Look for the VPN connection you just created, right-click on it and select
- Click on the
Securitytab and change the
Data encryptionoption to
Requirethen click on
- Click on the
Networkingtab and select
Internet Protocol Version 4 (TCP/IPv4)then click on the
- Click on the
Advanced...button. In the
IP Settingstab, enable
Use default gateway on remote network
- Lastly, click on the
OKbutton to close all open windows.
Now try connecting to your VPN. You will be asked if you want to trust the certificate (which you will say yes to) during the connection process. You should now have a successful VPN connection. Congratulations!
To verify that your VPN is working connect to a different network (such as a mobile hot-spot – basically anything not connected to your home internet connection) and go to any website that shows you your IP address, such as https://ipleak.net/. You should see the public IP address of your home internet connection.
If you look at your shell, you should now see your connection attempt being logged and what the server is responding with. /if your connection failed, you can check here for any error messages and troubleshoot accordingly.
Once your connection has been established, you will want to stop and start the VPN connection one final time as we started it the with
--nofork switch earlier.
To restart it, type the following in your shell:
Let’s take a look at setting up our iOS client.
Configuring the iOS VPN Client
Since this is another client device, I’ve gone ahead and generated a new set of certificates/keys and a new .p12 file for this device. You should also do the same thing for each device you want to connect to your VPN.
Note: I have tested this on iOS 9.3.4. It should still work on any iOS 9.x device.
- E-mail your
CA root certificateand your
.p12file to your iOS device.
- Once the email arrives, click on the
CA root certificateand you will be prompted to install it on your device. Follow the on-screen steps.
- Do the same for your
.p12file as well. Note that you will also need to input the password that you created when you generated your
- These certificates will be available in
Settings > General > Profiles.
- Go to
Settings > VPN > Add VPN Configuration...and enter in the following settings:
- Type: IKEv2
- Description: A name for your VPN connection.
- Server: The hostname/IP of your VPN server.
- Remote ID: The value you entered in
--sanwhen setting up your
SERVER_CERT.pemcertificate. In this example,
- Local ID:The value you entered in
--sanwhen setting up your
CLIENT_CERT.pemcertificate. In this example,
- User Authentication: Certificate
- Certificate: Tap here and select your client certificate.
Save your settings and try connect to the VPN. You should now have established a successful connection.
Please feel free to leave any comments or questions.