Set Up IKEv2 VPN for iOS and macOS With Local DNS Cache and Dnscrypt
Since IKEv2 VPN supports MOBIKE and is natively supported by iOS 9, OS X 10.11 and newer, it’s a good choice for iOS and macOS. In my setup, I use Debian Stretch, unbound for DNS cache and dnscrypt-proxy for dnscrypt protocol.
Set up DNS service
Set up a network interface for DNS listening
An network interface file with name 10-loopback-services.cfg should be added to folder /etc/network/interfaces.d with the following content.
auto lo:100
iface lo:100 inet static
address 172.16.0.1
netmask 255.255.255.255
Then we need to restart networking service.
$ sudo service networking restart
Set up dnscrypt-proxy
Install dnscrypt-proxy
$ wget https://download.dnscrypt.org/dnscrypt-proxy/binaries/linux/dnscrypt-proxy-x86_64-linux-musl.tar.gz
$ tar zxf dnscrypt-proxy-x86_64-linux-musl.tar.gz
$ cd dnscrypt-proxy-x86_64-linux-musl
$ sudo sh installer.sh
Now we need to replace the dnscrypt-proxy configuration, which located in /opt/dnscrypt-proxy/x86_64-linux-musl/etc/dnscrypt-proxy.conf, with the following content.
ResolverName cisco
Daemonize no
PidFile /var/run/dnscrypt-proxy.pid
LocalAddress 127.0.0.1:5353
LocalCache off
EphemeralKeys off
BlockIPv6 no
Set up auto start script
A auto start script with name dnscrypt-proxy.service should be add to folder /etc/systemd/system with the following content.
[Unit]
Description=DNSCrypt client proxy
After=network.target
Before=nss-lookup.target
[Service]
Type=simple
ExecStart=/opt/dnscrypt-proxy/x86_64-linux-musl/bin/dnscrypt-proxy /opt/dnscrypt-proxy/x86_64-linux-musl/etc/dnscrypt-proxy.conf
[Install]
WantedBy=multi-user.target
Then start dnscrypt-proxy service.
$ sudo systemctl start dnscrypt-proxy.service
$ sudo systemctl enable dnscrypt-proxy.service
Set up unbound
$ sudo apt-get install unbound -y
$ sudo wget ftp://FTP.INTERNIC.NET/domain/named.cache -O /etc/unbound/root.hints
Then the following content should be added to /etc/unbound/unbound.conf.
server:
num-threads: 2
interface: 127.0.0.1
interface: 172.16.0.1
so-rcvbuf: 4m
so-sndbuf: 4m
so-reuseport: yes
msg-cache-size: 64m
rrset-cache-size: 128m
cache-max-ttl: 3600
outgoing-num-tcp: 256
incoming-num-tcp: 1024
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes
tcp-upstream: no
access-control: 127.0.0.0/8 allow
access-control: 10.0.0.0/8 allow
access-control: 172.16.0.0/12 allow
root-hints: "/etc/unbound/root.hints"
hide-identity: yes
hide-version: yes
harden-glue: yes
module-config: "iterator"
unwanted-reply-threshold: 10000000
do-not-query-localhost: no
prefetch: yes
minimal-responses: yes
forward-zone:
name: "."
forward-addr: 127.0.0.1@5353
Then restart unbound service.
$ sudo service unbound restart
Set up IKEv2 VPN
Set up strongswan
Since strongswan in Debian Stretch is not the latest version, we compile from source.
$ sudo apt-get install -y --no-install-recommends build-essential libgmp-dev libssl-dev
$ wget https://download.strongswan.org/strongswan-5.5.3.tar.gz
$ tar zxf strongswan-5.5.3.tar.gz
$ cd strongswan-5.5.3
$ ./configure --prefix=/usr --sysconfdir=/etc \
--enable-aes \
--enable-gcm \
--enable-hmac \
--enable-kernel-netlink \
--enable-nonce \
--enable-openssl \
--enable-pem \
--enable-pgp \
--enable-pkcs12 \
--enable-pkcs7 \
--enable-pkcs8 \
--enable-pubkey \
--enable-random \
--enable-revocation \
--enable-sha2 \
--enable-socket-default \
--enable-stroke \
--enable-x509
$ make
$ sudo make install
Create certificates
Create CA
$ ipsec pki --gen --type ecdsa --size 384 --outform pem > ca-key.pem
$ ipsec pki --self --ca --lifetime 3650 --in ca-key.pem --type ecdsa --dn "C=NL, O=Example Company, CN=strongSwan Root CA" --outform pem > ca-cert.pem
Create server certificate
Repacle <server ip> with your current server ip address.
$ ipsec pki --gen --type ecdsa --size 384 --outform pem > server-key.pem
$ ipsec pki --pub --in server-key.pem --type ecdsa | ipsec pki --issue --lifetime 730 --cacert ca-cert.pem --cakey ca-key.pem --dn "C=NL, O=Example Company, CN=<server ip>" --san <server ip> --san @<server ip> --flag serverAuth --outform pem > server-cert.pem
Create client certificate
$ ipsec pki --gen --type ecdsa --size 384 --outform pem > client-key.pem
$ ipsec pki --pub --in client-key.pem --type ecdsa | ipsec pki --issue --lifetime 730 --cacert ca-cert.pem --cakey ca-key.pem --dn "C=NL, O=Example Company, CN=client" --san "client" --flag clientAuth --outform pem > client-cert.pem
Then copy certificates to necessary folders.
$ sudo cp server-key.pem /etc/ipsec.d/private
$ sudo cp server-cert.pem /etc/ipsec.d/certs
$ sudo cp ca-cert.pem /etc/ipsec.d/cacerts
Configure IPsec
Replace /etc/ipsec.conf with following content, do replace <server ip> with your server ip address.
config setup
uniqueids=never # allow multiple connections per user
charondebug="ike 2, knl 2, cfg 2, net 2, esp 2, dmn 2, mgr 2"
conn %default
fragmentation=yes
rekey=no
dpdaction=clear
keyexchange=ikev2
compress=yes
dpddelay=35s
ike=aes256gcm16-prfsha512-ecp384!
esp=aes256gcm16-ecp384!
left=%any
leftauth=pubkey
leftid=<server ip>
leftcert=server-cert.pem
leftsendcert=always
leftsubnet=0.0.0.0/0
right=%any
rightauth=pubkey
rightsourceip=10.0.0.0/24
rightdns=172.16.0.1
conn ikev2-pubkey
auto=add
Add the following line to file /etc/ipsec.secrets
: ECDSA server-key.pem
Then start IKEv2 VPN service.
$ sudo ipsec start
Configure iptables
$ iptables -A INPUT -p udp --dport 500 --j ACCEPT
$ iptables -A INPUT -p udp --dport 4500 --j ACCEPT
$ iptables -A INPUT -p ipencap -m policy --dir in --pol ipsec --proto esp -j ACCEPT
$ iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -m policy --pol none --dir out -j MASQUERADE
$ iptables -A FORWARD -m conntrack --ctstate NEW -s 10.0.0.0/24 -m policy --pol ipsec --dir in -j ACCEPT
Set up mobileconfig for iOS and macOS
Since we cannot configure details like cipher in iOS and macOS GUI, we have to use mobileconfig. I use Apple Configurator 2 on macOS. You can just change certificate’s file extension to crt for use with Apple Configurator 2. We use AES-256-GCM for encryption algorithm, SHA2-512 for Integrity Algorithm and 20 for Diffie-Hellman Group. Or a mobileconfig template at Strongswan website can be used for modification.