Static route on xfrm interface

I'm trying to implement StrongSwan site to site tunnel and I have stumbled upon static route configuration. For some reason routes are not created.

Tunnel start working as expected if I add route manually, following command is used:

ip route add 192.168.1.0/24 dev ipsec0 scope link

Relevant config sections:

network.wan=interface
network.wan.proto='dhcp'
network.wan.device='eth0.2'
network.lan=interface
network.lan.proto='static'
network.lan.netmask='255.255.255.0'
network.lan.device='eth0.1'
network.lan.ipaddr='192.168.128.1'
network.lan.type='bridge'
network.ipsec0=interface
network.ipsec0.proto='xfrm'
network.ipsec0.tunlink='wan'
network.ipsec0.zone='lan_vpn'
network.ipsec0.ifid='129'
network.ipsec0.force_link='1'
network.@route[0]=route
network.@route[0].interface='ipsec0'
network.@route[0].target='192.168.1.0/24'
network.@route[0].netmask='192.168.1.0/24'
network.@route[0].source='192.168.128.1'
ipsec.@ipsec[0]=ipsec
ipsec.@ipsec[0].rtinstall_enabled='1'
ipsec.@ipsec[0].debug='1'
ipsec.hq=remote
ipsec.hq.enabled='1'
ipsec.hq.keyingtries='%forever'
ipsec.hq.gateway='[REDACTED]'
ipsec.hq.remote_identifier='[REDACTED]'
ipsec.hq.authentication_method='psk'
ipsec.hq.pre_shared_key='[REDACTED]'
ipsec.hq.tunnel='ipsec0'
ipsec.hq.local_identifier='[REDACTED]'
ipsec.ipsec0=tunnel
ipsec.ipsec0.startaction='route'
ipsec.ipsec0.if_id='129'
ipsec.ipsec0.remote_subnet='192.168.1.0/24'
ipsec.ipsec0.local_subnet='192.168.128.0/24'
firewall.@defaults[0]=defaults
firewall.@defaults[0].input='ACCEPT'
firewall.@defaults[0].output='ACCEPT'
firewall.@defaults[0].forward='REJECT'
firewall.@defaults[0].synflood_protect='1'
firewall.@zone[0]=zone
firewall.@zone[0].name='lan'
firewall.@zone[0].input='ACCEPT'
firewall.@zone[0].output='ACCEPT'
firewall.@zone[0].forward='ACCEPT'
firewall.@zone[0].network='lan'
== cut ==
firewall.@zone[4]=zone
firewall.@zone[4].input='ACCEPT'
firewall.@zone[4].output='ACCEPT'
firewall.@zone[4].network='ipsec0'
firewall.@zone[4].name='lan_vpn'
firewall.@zone[4].forward='ACCEPT'
firewall.@forwarding[2]=forwarding
firewall.@forwarding[2].src='lan_vpn'
firewall.@forwarding[2].dest='lan'
firewall.@forwarding[3]=forwarding
firewall.@forwarding[3].src='lan'
firewall.@forwarding[3].dest='lan_vpn'

It's been a while I was confronted with (static) Policy route IPsec, but wasn't this covered by leftsubnet and rightsubnet using strongswan?

See https://wiki.strongswan.org/projects/strongswan/wiki/connsection

I'm using swanctl variant of the strongwan configuration and I think in swanctl leftsubnet and rightsubnet are translated to local_ts and remote_ts, swantctl startup script correctly translates ipsec.ipsec0.remote_subnet and
ipsec.ipsec0.local_subnet to corresponding parameters.

My generated swanctl.conf is:

 # generated by /etc/init.d/swanctl
 # config for hq
 connections {
   hq {
     local_addrs = %any
     remote_addrs = REDACTED
     fragmentation = yes
     local {
      auth = psk
       id = "REDACTED"
     }
     remote {
       auth = psk
       id = "REDACTED"
     }
     children {
       ipsec0 {
         local_ts = 192.168.128.0/24
         remote_ts = 192.168.1.0/24
         if_id_in = 129
         if_id_out = 129
         start_action = trap
         esp_proposals =
         mode = tunnel
       }
     }
     version = 2
     mobike = yes
     proposals =
     dpd_delay = 0s
     keyingtries = 0
   }
 }
 
 secrets {
   ike {
     secret = [REDACTED]
   }
}

Reference: https://docs.strongswan.org/docs/5.9/swanctl/swanctlConf.html#_connections_conn_children

That is not a valid option. To install a route in /etc/config/network it is necessary to have target (in CIDR notation), and interface.
The general practice with xfrm is to avoid using the ipsec policy route hooks in the kernel. This is done by setting the ipsec subnets on both ends of the point to point tunnel to 0.0.0.0/0 then control routing entirely outside ipsec, using xfrm as an ordinary interface.

1 Like

As always I recommend bird (https://bird.network.cz/?get_doc&f=bird.html&v=20) for this task...