This is an update of my previous post about configuring IPsec in OpenWrt.
The network scenario I’m describing is a central OpenWrt router with 2 internal LANs, plus 2 external hosts connected with VPN and some roadwarriors with all their traffic redirected through the IPsec tunnel.

Because I’m going to use public key authentication, a CA is needed. These are the commands I have used:
#!/bin/sh
umask 0077
cd /etc/ipsec.d
# CA
ipsec pki --gen --size 2048 --outform pem > private/caKey.pem
ipsec pki --self --in private/caKey.pem --dn "C=ES, O=IT, CN=StrongSwan CA" --ca --digest sha1 --lifetime 3650 --outform pem > cacerts/caCert.pem
chmod 0644 cacerts/caCert.pem
# openwrt.example.com
ipsec pki --gen --size 2048 --outform pem > private/openwrtKey.pem
ipsec pki --pub --in private/openwrtKey.pem | ipsec pki --issue --cacert cacerts/caCert.pem --cakey private/caKey.pem --dn "C=ES, O=IT, CN=openwrt.example.com" --san openwrt.example.com --flag clientAuth --flag serverAuth --flag ikeIntermediate --digest sha1 --lifetime 3650 --outform pem > certs/openwrtCert.pem
chmod 0644 certs/openwrtCert.pem
# server1.example.com
ipsec pki --gen --size 2048 --outform pem > private/server1Key.pem
ipsec pki --pub --in private/server1Key.pem | ipsec pki --issue --cacert cacerts/caCert.pem --cakey private/caKey.pem --dn "C=ES, O=IT, CN=server1.example.com" --san server1.example.com --flag clientAuth --flag serverAuth --flag ikeIntermediate --digest sha1 --lifetime 3650 --outform pem > certs/server1Cert.pem
chmod 0644 certs/server1Cert.pem
# server2.example.com
ipsec pki --gen --size 2048 --outform pem > private/server2Key.pem
ipsec pki --pub --in private/server2Key.pem | ipsec pki --issue --cacert cacerts/caCert.pem --cakey private/caKey.pem --dn "C=ES, O=IT, CN=server2.example.com" --san server2.example.com --flag clientAuth --flag serverAuth --flag ikeIntermediate --digest sha1 --lifetime 3650 --outform pem > certs/server2Cert.pem
chmod 0644 certs/server2Cert.pem
# Roadwarrior1
ipsec pki --gen --size 2048 --outform pem > private/roadwarrior1Key.pem
ipsec pki --pub --in private/roadwarrior1Key.pem | ipsec pki --issue --cacert cacerts/caCert.pem --cakey private/caKey.pem --dn "C=ES, O=IT, CN=roadwarrior1" --san roadwarrior1 --flag clientAuth --digest sha1 --lifetime 3650 --outform pem > certs/roadwarrior1Cert.pem
openssl pkcs12 -export -out roadwarrior1Cert.pfx -inkey private/roadwarrior1Key.pem -in certs/roadwarrior1Cert.pem -certfile cacerts/caCert.pem
chmod 0644 certs/roadwarrior1Cert.pem
We copy the generated files to /etc/ipsec.d/certs, /etc/ipsec.d/cacerts, /etc/ipsec.d/private depending in its function.
In /etc/ipsec.secrets we add our certificate
: RSA openwrtKey.pem
/etc/strongswan.conf:
charon {
dns1 = 192.168.100.1
plugins {
# dhcp {
# server = 192.168.101.1
# }
duplicheck {
enable = no
}
}
syslog {
daemon {
default = -1
ike = 0
}
}
}
The most important part of the configuration are the tunnels definitions in /etc/ipsec.conf. In this example, I have copied the openwrtCert.pem to all the other computers and vice-versa, so no certificate is needed to be transferred in the ike negotiation. You can omit that by removing the entries “leftsendcert” and “rightcert”.
config setup
strictcrlpolicy=no
#uniqueids=no
conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyexchange=ikev2
esp=aes128-sha1-modp4096!
leftcert=openwrtCert.pem
leftid=@openwrt.example.com
lefthostaccess=yes
leftfirewall=yes
conn server1-ipv4
left=203.0.113.1
right=198.51.100.1
rightcert=server1Cert.pem
rightid=@server1.example.com
leftsendcert=never
keyingtries=%forever
dpdaction=restart
auto=start
conn server1-ipv6
left=2001:db8:0:1::1
right=2001:db8:0:a::1
rightcert=server1Cert.pem
rightid=@server1.example.com
leftsendcert=never
keyingtries=%forever
dpdaction=restart
auto=start
conn net-server1-ipv6
also=server1-ipv6
leftsubnet=2001:db8:0:100::/64
rightsubnet=2001:db8:0:a::1/128
conn server2-ipv4
left=203.0.113.1
right=192.0.2.1
rightcert=server2Cert.pem
rightid=@server2.example.com
leftsendcert=never
keyingtries=%forever
dpdaction=restart
auto=start
conn server2-ipv6
left=2001:db8:0:1::1
right=2001:db8:0:b::1
rightcert=server2Cert.pem
rightid=@server2.example.com
leftsendcert=never
keyingtries=%forever
dpdaction=restart
auto=start
conn net-server2-ipv6
also=server2-ipv6
leftsubnet=2001:db8:0:100::/64
rightsubnet=2001:db8:0:b::1/128
conn roadwarrior
left=%any
right=%any
keyingtries=3
leftsubnet=0.0.0.0/0
rightsourceip=192.168.101.0/24
forceencaps=yes
dpdaction=clear
auto=add
At the server1 I have this configuration in ipsec.conf:
config setup
#crlcheckinterval=180
strictcrlpolicy=no
#uniqueids=no
conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=%forever
keyexchange=ikev2
esp=aes128-sha1-modp4096!
leftcert=server1Cert.pem
leftid=@server1.example.com
leftfirewall=yes
leftsendcert=never
dpdaction=restart
conn openwrt-ipv4
left=198.51.100.1
right=203.0.113.1
rightid=@openwrt.example.com
rightcert=openwrtCert.pem
auto=start
conn openwrt-ipv6
left=2001:db8:0:a::1
right=2001:db8:0:1::1
rightid=@openwrt.example.com
rightcert=openwrtCert.pem
auto=start
conn net-openwrt-ipv6
also=openwrt-ipv6
leftsubnet=2001:db8:0:a::1/128
rightsubnet=2001:db8:0:100::1/64
In the OpenWrt router we need to add a couple of iptables rules to avoid the roadwarrior clients to be natted, as their packets are sent through the wan interface. In /etc/firewall.user:
#!/bin/sh
# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.
subnet_rw="192.168.101.0/24"
iptables -t nat -I zone_wan_prerouting 1 -s $subnet_rw -m policy --dir in --pol ipsec -j ACCEPT
iptables -t nat -I zone_wan_nat 1 -d $subnet_rw -m policy --dir out --pol ipsec -j ACCEPT
/etc/init.d/ipsec restart
To monitor the status of the tunnels we can do:
# ipsec statusall