WHY ??
I need unblocked Internet connection, because in my country Reddit is blocked by all mobile operator and most of Internet provider! Sssstttt… and also, this, this, and of course this.
I am not sysadmin, so basically this article is my note to build my VPN server on Ubuntu 16.04 in chronological order. Please adjust IP Address, Cert CN, Cert O, Cert Name according to your server and your need.
REQUIREMENTS
Install required software packages :
# apt update
# apt upgrade
# apt autoremove
# apt install haveged strongswan strongswan-charon \
libstrongswan-standard-plugins libstrongswan-extra-plugins libcharon-extra-plugins
Make sure haveged
service is running :
# systemctl status haveged
It should output something like (green on dot and active (running)
) :
● haveged.service - Entropy daemon using the HAVEGE algorithm
Loaded: loaded (/lib/systemd/system/haveged.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2017-06-15 14:31:51 UTC; 4s ago
Docs: man:haveged(8)
http://www.issihosts.com/haveged/
Main PID: 3410 (haveged)
Tasks: 1
Memory: 3.0M
CPU: 443ms
CGroup: /system.slice/haveged.service
└─3410 /usr/sbin/haveged --Foreground --verbose=1 -w 1024
Stop strongswan
service before we start setup :
# systemctl stop strongswan
Our working folder is ipsec.d
config folder:
# cd /etc/ipsec.d
CA CERTIFICATE
Generate CA certificate private key :
# ipsec pki --gen --type rsa --size 4096 --outform der > private/ca.key.der
# chmod 600 private/ca.key.der
Generate CA certificate :
# ipsec pki --self --ca --lifetime 3650 --in private/ca.key.der \
--type rsa --dn "C=ID, O=SIMUKTINET, CN=SIMUKTI MIAMIVPN CA" \
--outform der > cacerts/ca.crt.der
View generated CA certificate :
# ipsec pki --print --in cacerts/ca.crt.der
It should output something like :
cert: X509
subject: "C=ID, O=SIMUKTINET, CN=SIMUKTI MIAMIVPN CA"
issuer: "C=ID, O=SIMUKTINET, CN=SIMUKTI MIAMIVPN CA"
validity: not before Jun 15 17:35:14 2017, ok
not after Jun 13 17:35:14 2027, ok (expires in 3649 days)
serial: 1c:0f:2c:80:32:e9:dc:0d
flags: CA CRLSign self-signed
subjkeyId: 5b:ef:c5:9d:c6:4a:2a:a1:92:fa:e3:61:70:b0:eb:cf:8b:6d:f5:e3
pubkey: RSA 4096 bits
keyid: ee:4c:88:ab:77:c5:54:ef:64:83:5c:ae:54:37:99:6f:88:5b:ab:72
subjkey: 5b:ef:c5:9d:c6:4a:2a:a1:92:fa:e3:61:70:b0:eb:cf:8b:6d:f5:e3
HOST CERTIFICATE
Generate host certificate private key:
# ipsec pki --gen --type rsa --size 4096 --outform der > private/host.key.der
# chmod 600 private/host.key.der
Generate host certificate :
# ipsec pki --pub --in private/host.key.der --type rsa | \
ipsec pki --issue --lifetime 1460 --cacert cacerts/ca.crt.der --cakey private/ca.key.der \
--dn "C=ID, O=SIMUKTINET, CN=miami-vpn.simukti.net" \
--san miami-vpn.simukti.net --san 93.184.216.34 --san @93.184.216.34 \
--flag serverAuth --flag ikeIntermediate --outform der > certs/host.crt.der
View generated host certificate :
# ipsec pki --print --in certs/host.crt.der
It should output something like :
cert: X509
subject: "C=ID, O=SIMUKTINET, CN=miami-vpn.simukti.net"
issuer: "C=ID, O=SIMUKTINET, CN=SIMUKTI MIAMIVPN CA"
validity: not before Jun 15 17:36:58 2017, ok
not after Jun 14 17:36:58 2021, ok (expires in 1459 days)
serial: 5f:ce:f8:a9:16:7f:e1:5b
altNames: miami-vpn.simukti.net, 93.184.216.34, 93.184.216.34
flags: serverAuth iKEIntermediate
authkeyId: 5b:ef:c5:9d:c6:4a:2a:a1:92:fa:e3:61:70:b0:eb:cf:8b:6d:f5:e3
subjkeyId: cb:c5:82:e6:f3:2a:92:ff:f6:c5:82:67:36:bb:74:15:ab:27:ce:aa
pubkey: RSA 4096 bits
keyid: 79:aa:91:ee:ee:50:46:3d:56:ed:40:da:c5:60:3a:a2:45:58:2d:6e
subjkey: cb:c5:82:e6:f3:2a:92:ff:f6:c5:82:67:36:bb:74:15:ab:27:ce:aa
USER CERTIFICATE
Generate user certificate private key :
# ipsec pki --gen --type rsa --size 2048 --outform der > private/simukti.key.der
# chmod 600 private/simukti.key.der
Generate user certificate public key :
# ipsec pki --pub --type rsa --in private/simukti.key.der | \
ipsec pki --issue --lifetime 1460 --cacert cacerts/ca.crt.der \
--cakey private/ca.key.der --dn "C=ID, O=SIMUKTINET, [email protected]" \
--san "[email protected]" --san "[email protected]" \
--outform der > certs/simukti.crt.der
View generated user certificate :
# ipsec pki --print --in certs/simukti.crt.der
It should output something like :
cert: X509
subject: "C=ID, O=SIMUKTINET, [email protected]"
issuer: "C=ID, O=SIMUKTINET, CN=SIMUKTI MIAMIVPN CA"
validity: not before Jun 15 17:39:08 2017, ok
not after Jun 14 17:39:08 2021, ok (expires in 1459 days)
serial: 7b:29:ad:a4:b9:5e:3c:27
altNames: [email protected], [email protected]
flags:
authkeyId: 5b:ef:c5:9d:c6:4a:2a:a1:92:fa:e3:61:70:b0:eb:cf:8b:6d:f5:e3
subjkeyId: ca:35:f5:54:d7:78:c6:bd:fc:24:ef:2d:31:bd:a5:1d:f9:f1:fc:11
pubkey: RSA 2048 bits
keyid: 55:a6:44:dd:47:fc:50:cc:8c:cd:e4:ac:b2:e4:15:e9:fd:d8:8b:45
subjkey: ca:35:f5:54:d7:78:c6:bd:fc:24:ef:2d:31:bd:a5:1d:f9:f1:fc:11
After user certificate created, we should convert required certificates to PEM format, and embed it as one importable PKCS#12 format for client system.
Convert user private key to PEM format :
# openssl rsa -inform DER -in private/simukti.key.der -outform PEM -out private/simukti.key.pem
Convert user certificate to PEM format :
# openssl x509 -inform DER -in certs/simukti.crt.der -outform PEM -out certs/simukti.crt.pem
Convert root certificate to PEM format :
# openssl x509 -inform DER -in cacerts/ca.crt.der -outform PEM -out cacerts/ca.crt.pem
Bundle required certificates as PKCS#12 :
# mkdir p12
# openssl pkcs12 -export -inkey private/simukti.key.pem \
-in certs/simukti.crt.pem -name "SIMUKTI's MIAMI VPN Cert" \
-certfile cacerts/ca.crt.pem -caname "SIMUKTI MIAMIVPN CA" \
-out p12/simukti.miami-vpn.simukti.net.p12
After we hit enter, there is a prompt for export’s password :
Enter Export Password:
Verifying - Enter Export Password:
IPSEC CONFIGURATION
Open ipsec.secrets
using nano
:
# nano /etc/ipsec.secrets
Fill ipsec.secrets
content with something like :
# 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.
: RSA /etc/ipsec.d/private/host.key.der
host.key.der
is host’s private key from Host Certificate section.
Open ipsec.conf
using nano
:
# nano /etc/ipsec.conf
Fill ipsec.conf
content with :
# ipsec.conf - strongSwan IPsec configuration file
# https://wiki.strongswan.org/projects/strongswan/wiki/ConfigSetupSection
config setup
# https://wiki.strongswan.org/projects/strongswan/wiki/LoggerConfiguration
charondebug="ike 0, knl 0, cfg 0, net 0, esp 0, dmn 0, mgr 0, job 0, enc 0, lib 0"
# https://wiki.strongswan.org/projects/strongswan/wiki/ConnSection
conn %default
keyexchange=ikev2
ike=aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024!
esp=aes128gcm16-ecp256,aes256gcm16-ecp384,aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128gcm16,aes256gcm16,aes128-sha256,aes128-sha1,aes256-sha384,aes256-sha256,aes256-sha1!
dpdaction=clear
dpddelay=300s
authby=pubkey
rekey=no
forceencaps=yes
fragmentation=yes
mobike=yes
ikelifetime=6h
compress=yes
left=%any
leftid=miami-vpn.simukti.net
leftsubnet=0.0.0.0/0
leftcert=/etc/ipsec.d/certs/host.crt.der
leftsendcert=always
leftfirewall=yes
right=%any
# you can use subnet /24, your choice
rightsourceip=10.10.1.0/29
rightdns=8.8.4.4,8.8.8.8
## ANDROID STRONGSWAN CLIENT (.p12 import)
## OSX IKEv2 (.p12 import)
conn IPSEC-IKEv2
## UPDATE 2018-03-25
rightauth=pubkey
keyexchange=ikev2
auto=add
## UPDATE 2018-03-25 (MacOS High Sierra)
## WINDOWS CLIENT
## OSX SIERRA IKEv2 username+password
conn IKEv2-EAP
also="IPSEC-IKEv2"
rightauth=eap-mschapv2
Make sure leftid
is value from host certificate CN. And now start strongswan
service :
UPDATE 2018-03-25 (MacOS High Sierra)
For conn IKEv2-EAP
we use username and password because after client upgrade to MacOS High Sierra I cannot use certificate based login.
If those config not working, try to change ike
and esp
value for MacOS HighSierra client with the following values :
ike=aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,3des-sha1-modp1024!
esp=aes128gcm16-ecp256,aes256gcm16-ecp384,aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128gcm16,aes256gcm16,aes128-sha256,aes128-sha1,aes256-sha384,aes256-sha256,aes256-sha1,3des-sha1!
# nano /etc/ipsec.secrets
Add username and password authentication
# RSA private key for this host, authenticating it to any other host
# which knows the public part.
: RSA /etc/ipsec.d/private/host.key.der
# UPDATE 2018-03-25
# USERNAME %any% : EAP "PASSWORD"
your_username %any% : EAP "your_password"
# systemctl start strongswan
View status of running strongswan
:
# systemctl status strongswan
It should output something like (green on dot and active (running)
):
● strongswan.service - strongSwan IPsec services
Loaded: loaded (/lib/systemd/system/strongswan.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2017-06-15 14:50:34 UTC; 5s ago
Process: 3528 ExecStopPost=/bin/rm -f /var/run/charon.pid /var/run/starter.charon.pid (code=exited, status=0/SUCCESS)
Process: 3520 ExecStop=/usr/sbin/ipsec stop (code=exited, status=0/SUCCESS)
Process: 3538 ExecStart=/usr/sbin/ipsec start (code=exited, status=0/SUCCESS)
Process: 3535 ExecStartPre=/bin/mkdir -p /var/lock/subsys (code=exited, status=0/SUCCESS)
Main PID: 3555 (starter)
Tasks: 18
Memory: 4.2M
CPU: 90ms
CGroup: /system.slice/strongswan.service
├─3555 /usr/lib/ipsec/starter --daemon charon
└─3556 /usr/lib/ipsec/charon --use-syslog --debug-ike 0 --debug-knl 0 --debug-cfg 0 --debug-net 0 --debug-esp 0 --debug-dmn 0 --debug-mgr 0 --debug-job 0 --debug-enc 0 --debug-lib 0
View IPSec status :
# ipsec statusall
It should output something like :
Status of IKE charon daemon (strongSwan 5.3.5, Linux 4.4.0-79-generic, x86_64):
uptime: 29 seconds, since Jun 15 17:45:46 2017
malloc: sbrk 2199552, mmap 532480, used 1031312, free 1168240
worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 0
loaded plugins: charon test-vectors unbound ldap pkcs11 aes rc2 sha1 sha2 md4 md5 rdrand random nonce x509 revocation constraints acert pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey dnscert ipseckey pem openssl gcrypt af-alg fips-prf gmp agent chapoly xcbc cmac hmac ctr ccm gcm ntru bliss curl soup mysql sqlite attr kernel-netlink resolve socket-default connmark farp stroke updown eap-identity eap-sim eap-sim-pcsc eap-aka eap-aka-3gpp2 eap-simaka-pseudonym eap-simaka-reauth eap-md5 eap-gtc eap-mschapv2 eap-dynamic eap-radius eap-tls eap-ttls eap-peap eap-tnc xauth-generic xauth-eap xauth-pam xauth-noauth tnc-tnccs tnccs-20 tnccs-11 tnccs-dynamic dhcp whitelist lookip error-notify certexpire led radattr addrblock unity
Virtual IP pools (size/online/offline):
10.10.1.0/29: 6/0/0
Listening IP addresses:
93.184.216.34
Connections:
IPSEC-IKEv2: %any...%any IKEv2, dpddelay=300s
IPSEC-IKEv2: local: [miami-vpn.simukti.net] uses public key authentication
IPSEC-IKEv2: cert: "C=ID, O=SIMUKTINET, CN=miami-vpn.simukti.net"
IPSEC-IKEv2: remote: uses public key authentication
IPSEC-IKEv2: child: 0.0.0.0/0 === dynamic TUNNEL, dpdaction=clear
Security Associations (0 up, 0 connecting):
none
SYSCTL VARIABLES
To allow packet forwarding, we should set sysctl
variables.
# nano /etc/sysctl.conf
Add these variables :
# STRONGSWAN
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1
View sysctl.conf
values, and reload without reboot :
# sysctl -p
# sysctl --system
IPTABLES RULES
Allow system to receive network packets on UDP port 500 (IKE port) and UDP 4500 (NAT Traversal).
First, check our network card config :
# ifconfig
It should output something like :
ens3 Link encap:Ethernet HWaddr 44:00:00:14:00:ee
inet addr:93.184.216.34 Bcast:93.184.216.255 Mask:255.255.254.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4303 errors:0 dropped:0 overruns:0 frame:0
TX packets:3003 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:9022990 (9.0 MB) TX bytes:490839 (490.8 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Note that our primary network card is ens3
(see that inet addr). That IP address (inet addr) must be equivalent with all certificate’s --san
values.
Edit rc.local
for persistent iptables config after reboot :
# nano /etc/rc.local
Now add postrouting to ens3
ip address and allow input on port 500 and 4500 :
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
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
iptables -t nat -A POSTROUTING -j SNAT --to-source 93.184.216.34 -o ens+
for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
exit 0
If our network card’s name is something like eth0
, change -o ens+
to -o eth+
.
Now, run rc.local
:
# /etc/rc.local
OSX NATIVE VPN CLIENT SETUP
Copy those PKCS#12 file using scp :
# scp [email protected]:/etc/ipsec.d/p12/simukti.miami-vpn.simukti.net.p12 ~/Downloads/
Open Keychain Access, click on left bottom Category -> Certificates, and drag simukti.miami-vpn.simukti.net.p12
to right window. Enter our export’s password.
Trust all imported certificates :
- Double click on SIMUKTI MIAMIVPN CA
- Click
Trust
and set value ofWhen using this certificate
to Always Trust - Close those pop-up window
- Double click on
[email protected]
- Click
Trust
and set value ofWhen using this certificate
to Always Trust - Close those pop-up window
- Expand on
[email protected]
- Double click on
SIMUKTI's MIAMI VPN Cert
- Click tab
Access Control
and choose Allow all applications to access this item - Click
Save Changes
button on bottom right of pop-up window - Close those pop-up window
Now setup native VPN on OSX :
- Click Apple logo on top left
- Choose
System Preferences
- Choose
Network
- Click gold lock on bottom left window
- Click
+
- Choose Interface: VPN
- Choose VPN Type: IKEv2
- Service Name:
miami-vpn.simukti.net
- Click
Create
button
Configure VPN profile miami-vpn.simukti.net
:
- Server address:
93.184.216.34
- Remote ID:
miami-vpn.simukti.net
- Local ID:
[email protected]
- Click
Authentication Settings...
button - On
Authentication Settings
pop-window - Authentication Settings: None
- Choose
Certificate
, and clickSelect...
button - Scroll to bottom, and choose
[email protected] (SIMUKTI MIAMIVPN CA)
- Click
Continue
button - Click
OK
button - Make sure to mark
Show VPN status in menu bar
- Click
Apply
button - Click
Connect
button
In menu bar (top right), we should see timer for connected VPN connection.
We are done connecting OSX to our new IKEv2 VPN server.
UPDATE 2018-03-25 (MacOS High Sierra)
Using username password same with previous IPSec VPN, except for authentication, use Username, and input username and password you’ve defined in /etc/ipsec.secrets
.
ANDROID STRONGSWAN CLIENT SETUP
Certificates import :
- Open/Import
simukti.miami-vpn.simukti.net.p12
from our Android (I send that p12 file via Telegram, you can also copy it via usb and open it using your favorite file manager) - We will be asked for password (previously set on USER CERTIFICATE section)
- After we tap
OK
button, there is a pop-up displaying certificate import confirmation - Certificate name must be the same with the one you set on bundling pkcs#12 section (SIMUKTI’s MIAMI VPN Cert)
- Credential use: VPN and apps
- Tap
OK
button
strongSwan setup :
- Install strongSwan from PlayStore: Click Here
- My Android version at this time of writing is: 7.1.1
- My strongSwan version at this time of writing is: 1.8.2
- Open strongSwan
- Tap ADD VPN PROFILE
- Server : 93.184.216.34
- VPN Type: IKEv2 Certificate
- Tap
Select user certificate
- Choose the one we’ve just import (SIMUKTI’s MIAMI VPN Cert)
- Tap Allow
- CA certificate: mark
Select Automatically
- Profile name:
miami-vpn.simukti.net
- Mark Show advanced settings
- Scroll down
- On Split tunneling, mark
Block IPv4 traffic not destined for the VPN
andBlock IPv6 traffic not destined for the VPN
- Tap Save button (second from top right)
New profile has been added to list of strongSwan VPN profile, tap one of profile to connect to a VPN server.
If we see Status: Connected with green color, we are done connecting Android to our new IKEv2 VPN Server.
Now back to server, if we successfully connect OSX and Android, we should see 2 connections on IPSec status.
# ipsec status
It should output something like:
Security Associations (2 up, 0 connecting):
IPSEC-IKEv2[7]: ESTABLISHED 11 seconds ago, 93.184.216.34[miami-vpn.simukti.net]...112.215.44.77[C=ID, O=SIMUKTINET, CN=[email protected]]
IPSEC-IKEv2{5}: INSTALLED, TUNNEL, reqid 5, ESP in UDP SPIs: cc33bd64_i 1570d7e5_o
IPSEC-IKEv2{5}: 0.0.0.0/0 === 10.10.1.2/32
IPSEC-IKEv2[6]: ESTABLISHED 17 seconds ago, 93.184.216.34[miami-vpn.simukti.net]...112.215.44.77[[email protected]]
IPSEC-IKEv2{4}: INSTALLED, TUNNEL, reqid 4, ESP in UDP SPIs: c73ec2bf_i 0bd80f1c_o
IPSEC-IKEv2{4}: 0.0.0.0/0 === 10.10.1.1/32
Congratulation, we just build our very own IPSec-IKEv2 VPN server for OSX and Android client.
This article is mostly taken from Remy van Elst’s blog 1 2. If you think this article is useful, you should thanks to him.