openbsd 6.0 l2tp/ipsec vpn howto

This is my setup, which is working in production.
I’m using openbsd 6.0 which is acting as l2tp ipsec vpn router. I have multiple Windows OS clients and mobile IOS too. This setup can be installed in a few minutes.

tuning syscontrol


net.inet.gre.allow=1
net.inet.ip.forwarding=1 # 1=Permit forwarding (routing) of IPv4 packets
net.inet.esp.enable=1 #0=Disable the ESP IPsec protocol
net.inet.ah.enable=1 # 0=Disable the AH IPsec protocol
net.inet.esp.udpencap=1 # 0=Disable ESP-in-UDP encapsulation
net.inet.ipcomp.enable=1 # 1=Enable the IPCOMP protocol
net.pipex.enable=1 # 1=Enable pipex(4) for npppd(8)

/etc/rc.conf

isakmpd_flags="-K"
npppd_flags="-f /etc/npppd/npppd.conf "
ipsec=YES # IPsec
ipsec_rules=/etc/ipsec.conf

/ipsec shared secret key/
vim /etc/ipsec.conf

ike passive esp transport proto udp from em0 to any port 1701 main auth "hmac-sha1" enc "3des" group modp1024 quick auth "hmac-sha1" enc "aes" group modp1024 psk "passwordishere"

vi /etc/npppd/npppd.conf

set user-max-session 1

authentication LOCAL type local {
users-file "/etc/npppd/npppd-users"
}

tunnel L2TP protocol l2tp {
listen on 46.35.160.170
idle-timeout 3600
}

ipcp IPCP {
pool-address 172.12.0.2-172.12.0.254
dns-servers 8.8.8.8
}

interface tun0 address 172.12.0.1 ipcp IPCP
bind tunnel from L2TP authenticated by LOCAL to tun0

vi /etc/npppd/npppd-users

ibekyarov:\
:password=theuserpasswordishere:

vim /etc/pf.conf

ext_if = "em0"
ipsec_if = "enc0"
ipsec_tun = "tun0"
table { 172.12.0.0/24 }

pass out all
block in log all

pass in log proto { esp } from any to ($ext_if)
pass in log on $ext_if proto udp from any to any port {500, 1701, 4500} keep state

pass in log on $ipsec_if from any to ($ext_if) keep state (if-bound)
pass in log on $ipsec_tun from to any keep state (if-bound)
pass in log on $ext_if from to any keep state (if-bound)
pass in log on $ext_if from 192.168.4.0/24 to any keep state (if-bound)
pass in log on em1 from 192.168.99.0/23 to any keep state (if-bound)

pass out log on $ipsec_tun from to any nat-to 46.35.160.170
pass out log from to any nat-to 46.35.160.170