Traffic is dropped for IPsec with firewall4

I used to successfully run IPsec VPN with Strongswan (IKEv2) in a Road-Warrior setup on my router. Before v22.03 I had most my config in ipsec.conf and /etc/firewall.user. With the latest OpenWrt 22.03 two things have changed: fw4 cannot handle my config from /etc/firewall.user and ipsec.conf has been deprecated for swanctl.conf.

While I think I am good on the "strongswan side of things" (I can connect to my VPN from a road-warrior), the firewall troubles me. The traffic from my road-warrior gets somehow dropped when connected to my vpn router.

These are my old settings:

/etc/firewall.user
iptables -I INPUT  -m policy --dir in --pol ipsec --proto esp -j ACCEPT
iptables -I FORWARD  -m policy --dir in --pol ipsec --proto esp -j ACCEPT
iptables -I FORWARD  -m policy --dir out --pol ipsec --proto esp -j ACCEPT
iptables -I OUTPUT   -m policy --dir out --pol ipsec --proto esp -j ACCEPT
iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT

iptables -t nat -I POSTROUTING -s 10.10.20.0/29 -o wan -j MASQUERADE

These are my new settings:

/etc/config/network
config globals 'globals'
	option packet_steering	'1'
	option ula_prefix	'fdf1:5e87:bb9c::/48'

config device
	option type		'bridge'
	option name		'br-lan'
	option ipv6		'0'
	list ports		'lan1'
	list ports		'lan2'
	list ports		'lan3'
	list ports		'lan4'

config device
	option type		'bridge'
	option name		'br-vpn'
	option ipv6		'0'
	list ports		'br-lan.20'

config device
	option type		'bridge'
	option name		'br-tkh'
	option ipv6		'0'
	list ports		'br-lan.28'

config bridge-vlan
	option device		'br-lan'
	option vlan		'28'
	list ports		'lan1:u*'
	list ports		'lan4:t'

config device
	option type		'8021q'
	option ifname		'br-lan'
	option vid		'20'
	option name		'br-lan.20'
	option ipv6		'0'

config device
	option type		'8021q'
	option ifname		'br-lan'
	option vid		'28'
	option name		'br-lan.28'
	option ipv6		'0'

config interface 'loopback'
	option device	'lo'
	option proto	'static'
	option ipaddr	'127.0.0.1'
	option netmask	'255.0.0.0'

config interface 'WAN'
	option device	'wan'
	option proto	'dhcp'

config interface 'HOME'
	option proto	'static'
	option device	'br-tkh'
	option ipaddr	'10.10.28.1'
	option netmask	'255.255.255.0'
	option delegate	'0'

config interface 'VPN'
	option proto	'static'
	option device	'br-vpn'
	option ipaddr	'10.10.20.1'
	option netmask	'255.255.255.248'
	option delegate	'0'
/etc/config/firewall
config defaults
	option input			'ACCEPT'
	option output			'ACCEPT'
	option forward			'REJECT'
	option synflood_protect		'1'
	option flow_offloading		'1'
	option flow_offloading_hw	'1'

config zone
	option name		'wan'
	list network		'WAN'
	option input		REJECT
	option output		ACCEPT
	option forward		REJECT
	option masq		1
	option mtu_fix		1
#	list masq_dest		'!10.10.20.0/29'

config zone
	option name		'home'
	list network		'HOME'
	option input		ACCEPT
	option output		ACCEPT
	option forward		ACCEPT

config zone
	option name		'vpn'
	list network		'VPN'
	option input		ACCEPT
	option output		ACCEPT
	option forward		ACCEPT
	option masq		1

config forwarding
	option src		home
	option dest		wan

config forwarding
	option src		vpn
	option dest		home

config forwarding
	option src		vpn
	option dest		wan

config rule
	option name		Allow-DHCP-Renew
	option src		wan
	option proto		udp
	option dest_port	68
	option target		ACCEPT
	option family		ipv4

config rule
	option name		Allow-Ping
	option src		wan
	option proto		icmp
	option icmp_type	echo-request
	option target		ACCEPT
	option family		ipv4

config rule
	option name		Allow-IGMP
	option src		wan
	option proto		igmp
	option target		ACCEPT
	option family		ipv4

config rule
	option name		Allow-IPSec-ESP
	option src		wan
	option proto		esp
	option target		ACCEPT

config rule
	option name		Allow-ISAKMP
	option src		wan   
	option dest_port	500
	option proto		udp
	option target		ACCEPT

config rule
	option name		Allow-IPSec-NAT
	option src		wan
	option dest_port	4500
	option proto		udp
	option target		ACCEPT

config rule
	option name		Allow-IPSec-AH
	option src		wan
	option proto		ah
	option target		ACCEPT
/etc/nftables.d/20-ipsec.nft
chain ipsec_chain {
     type nat hook postrouting priority -1;
     ip daddr 10.10.20.0/29 counter accept
}

chain forward {
     type filter hook forward priority 0;
     ip saddr 10.10.20.0/29 counter drop
}

Here are my connection details for analysis:

swanctl trace (on vpn router)
root@vpn:~# swanctl --log
15[NET] received packet: from 192.168.28.123[500] to 192.168.28.186[500] (604 bytes)
15[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(REDIR_SUP) N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) ]
15[IKE] 192.168.28.123 is initiating an IKE_SA
15[CFG] selected proposal: IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
15[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(CHDLESS_SUP) N(MULT_AUTH) ]
15[NET] sending packet: from 192.168.28.186[500] to 192.168.28.123[500] (456 bytes)
05[NET] received packet: from 192.168.28.123[4500] to 192.168.28.186[4500] (512 bytes)
05[ENC] unknown attribute type INTERNAL_DNS_DOMAIN
05[ENC] parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr CPRQ(ADDR MASK DHCP DNS ADDR6 DHCP6 DNS6 DOMAIN) N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) SA TSi TSr N(MOBIKE_SUP) ]
05[CFG] looking for peer configs matching 192.168.28.186[setup.test]...192.168.28.123[192.168.28.123]
05[CFG] selected peer config 'rw-eapmschapv2'
05[IKE] EAP-Identity request configured, but not supported
05[IKE] initiating EAP_MSCHAPV2 method (id 0x6B)
05[IKE] received ESP_TFC_PADDING_NOT_SUPPORTED, not using ESPv3 TFC padding
05[IKE] peer supports MOBIKE
05[IKE] authentication of 'setup.test' (myself) with RSA signature successful
05[IKE] sending end entity cert "xxx"
05[IKE] sending issuer cert "xxx"
05[ENC] generating IKE_AUTH response 1 [ IDr CERT CERT AUTH EAP/REQ/MSCHAPV2 ]
05[ENC] splitting IKE message (4096 bytes) into 4 fragments
05[ENC] generating IKE_AUTH response 1 [ EF(1/4) ]
05[ENC] generating IKE_AUTH response 1 [ EF(2/4) ]
05[ENC] generating IKE_AUTH response 1 [ EF(3/4) ]
05[ENC] generating IKE_AUTH response 1 [ EF(4/4) ]
05[NET] sending packet: from 192.168.28.186[4500] to 192.168.28.123[4500] (1236 bytes)
05[NET] sending packet: from 192.168.28.186[4500] to 192.168.28.123[4500] (1236 bytes)
05[NET] sending packet: from 192.168.28.186[4500] to 192.168.28.123[4500] (1236 bytes)
05[NET] sending packet: from 192.168.28.186[4500] to 192.168.28.123[4500] (612 bytes)
12[NET] received packet: from 192.168.28.123[4500] to 192.168.28.186[4500] (144 bytes)
12[ENC] parsed IKE_AUTH request 2 [ EAP/RES/MSCHAPV2 ]
12[IKE] EAP-MS-CHAPv2 username: 'testuser'
12[ENC] generating IKE_AUTH response 2 [ EAP/REQ/MSCHAPV2 ]
12[NET] sending packet: from 192.168.28.186[4500] to 192.168.28.123[4500] (144 bytes)
14[NET] received packet: from 192.168.28.123[4500] to 192.168.28.186[4500] (80 bytes)
14[ENC] parsed IKE_AUTH request 3 [ EAP/RES/MSCHAPV2 ]
14[IKE] EAP method EAP_MSCHAPV2 succeeded, MSK established
14[ENC] generating IKE_AUTH response 3 [ EAP/SUCC ]
14[NET] sending packet: from 192.168.28.186[4500] to 192.168.28.123[4500] (80 bytes)
06[NET] received packet: from 192.168.28.123[4500] to 192.168.28.186[4500] (112 bytes)
06[ENC] parsed IKE_AUTH request 4 [ AUTH ]
06[IKE] authentication of '192.168.28.123' with EAP successful
06[IKE] authentication of 'setup.test' (myself) with EAP
06[IKE] IKE_SA rw-eapmschapv2[7] established between 192.168.28.186[setup.test]...192.168.28.123[192.168.28.123]
06[IKE] scheduling rekeying in 13623s
06[IKE] maximum IKE_SA lifetime 15063s
06[IKE] peer requested virtual IP %any
06[CFG] assigning new lease to 'test user'
06[IKE] assigning virtual IP 10.10.20.3 to peer 'testuser'
06[IKE] peer requested virtual IP %any6
06[IKE] no virtual IP found for %any6 requested by 'testuser'
06[CFG] selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
06[IKE] CHILD_SA ikev2clients{7} established with SPIs c13503d4_i 0e5c0e69_o and TS 10.10.10.0/24 10.10.11.0/24 10.10.12.0/24 10.10.20.0/29 10.10.28.0/24 === 10.10.20.3/32
06[ENC] generating IKE_AUTH response 4 [ AUTH CPRP(ADDR DNS NBNS SUBNET U_DEFDOM U_SPLITDNS DOMAIN DNS) SA TSi TSr N(MOBIKE_SUP) N(ADD_4_ADDR) N(ADD_4_ADDR) N(ADD_4_ADDR) N(ADD_4_ADDR) N(ADD_4_ADDR) N(ADD_4_ADDR) ]
06[NET] sending packet: from 192.168.28.186[4500] to 192.168.28.123[4500] (448 bytes)
table 220 (on vpn router)
root@vpn:~# ip route show table 220
10.10.20.2 via 192.168.28.123 dev wan proto static src 10.10.28.1 
ping (from road-warrior)
> ping -c 3 10.10.28.1
PING 10.10.28.1 (10.10.28.1): 56 data bytes
64 bytes from 10.10.28.1: icmp_seq=0 ttl=64 time=0.854 ms
64 bytes from 10.10.28.1: icmp_seq=1 ttl=64 time=0.668 ms
64 bytes from 10.10.28.1: icmp_seq=2 ttl=64 time=0.618 ms

--- 10.10.28.1 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.618/0.713/0.854/0.102 ms
dns query (from road-warrior)
> dig news.ycombinator.com @10.10.20.1 

; <<>> DiG 9.10.6 <<>> news.ycombinator.com @10.10.20.1
;; global options: +cmd
;; connection timed out; no servers could be reached
nft monitor trace (on vpn router)
root@vpn:~# nft add chain inet fw4 trace_chain { type filter hook prerouting priority -301\; }
root@vpn:~# nft add rule inet fw4 trace_chain udp dport 53 meta nftrace set 1
root@vpn:~# nft monitor trace
trace id 72b14c5b inet fw4 trace_chain packet: iif "wan" ether saddr 00:50:b6:87:2f:f1 ether daddr 94:a6:7e:b5:7e:33 ip saddr 10.10.20.2 ip daddr 10.10.20.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 47760 ip protocol udp ip length 71 udp sport 60852 udp dport 53 udp length 51 @th,64,96 0x57d701200001000000000001 
trace id 72b14c5b inet fw4 trace_chain rule udp dport 53 meta nftrace set 1 (verdict continue)
trace id 72b14c5b inet fw4 trace_chain verdict continue 
trace id 72b14c5b inet fw4 trace_chain policy accept 
trace id 72b14c5b inet fw4 raw_prerouting packet: iif "wan" ether saddr 00:50:b6:87:2f:f1 ether daddr 94:a6:7e:b5:7e:33 ip saddr 10.10.20.2 ip daddr 10.10.20.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 47760 ip protocol udp ip length 71 udp sport 60852 udp dport 53 udp length 51 @th,64,96 0x57d701200001000000000001 
trace id 72b14c5b inet fw4 raw_prerouting verdict continue 
trace id 72b14c5b inet fw4 raw_prerouting policy accept 
trace id 72b14c5b inet fw4 mangle_prerouting packet: iif "wan" ether saddr 00:50:b6:87:2f:f1 ether daddr 94:a6:7e:b5:7e:33 ip saddr 10.10.20.2 ip daddr 10.10.20.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 47760 ip protocol udp ip length 71 udp sport 60852 udp dport 53 udp length 51 @th,64,96 0x57d701200001000000000001 
trace id 72b14c5b inet fw4 mangle_prerouting verdict continue 
trace id 72b14c5b inet fw4 mangle_prerouting policy accept 
trace id 72b14c5b inet fw4 dstnat packet: iif "wan" ether saddr 00:50:b6:87:2f:f1 ether daddr 94:a6:7e:b5:7e:33 ip saddr 10.10.20.2 ip daddr 10.10.20.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 47760 ip protocol udp ip length 71 udp sport 60852 udp dport 53 udp length 51 @th,64,96 0x57d701200001000000000001 
trace id 72b14c5b inet fw4 dstnat verdict continue 
trace id 72b14c5b inet fw4 dstnat policy accept 
trace id 72b14c5b inet fw4 prerouting packet: iif "wan" ether saddr 00:50:b6:87:2f:f1 ether daddr 94:a6:7e:b5:7e:33 ip saddr 10.10.20.2 ip daddr 10.10.20.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 47760 ip protocol udp ip length 71 udp sport 60852 udp dport 53 udp length 51 @th,64,96 0x57d701200001000000000001 
trace id 72b14c5b inet fw4 prerouting verdict continue 
trace id 72b14c5b inet fw4 prerouting policy accept 
trace id 72b14c5b inet fw4 mangle_input packet: iif "wan" ether saddr 00:50:b6:87:2f:f1 ether daddr 94:a6:7e:b5:7e:33 ip saddr 10.10.20.2 ip daddr 10.10.20.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 47760 ip protocol udp ip length 71 udp sport 60852 udp dport 53 udp length 51 @th,64,96 0x57d701200001000000000001 
trace id 72b14c5b inet fw4 mangle_input verdict continue 
trace id 72b14c5b inet fw4 mangle_input policy accept 
trace id 72b14c5b inet fw4 input packet: iif "wan" ether saddr 00:50:b6:87:2f:f1 ether daddr 94:a6:7e:b5:7e:33 ip saddr 10.10.20.2 ip daddr 10.10.20.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 47760 ip protocol udp ip length 71 udp sport 60852 udp dport 53 udp length 51 @th,64,96 0x57d701200001000000000001 
trace id 72b14c5b inet fw4 input rule iifname "wan" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic" (verdict jump input_wan)
trace id 72b14c5b inet fw4 input_wan rule jump reject_from_wan (verdict jump reject_from_wan)
trace id 72b14c5b inet fw4 reject_from_wan rule iifname "wan" counter packets 127 bytes 23642 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic" (verdict jump handle_reject)
trace id 72b14c5b inet fw4 handle_reject rule reject comment "!fw4: Reject any other traffic" (verdict drop)

How can I transform my old Iptables rules from /etc/firewall.user into something that fw4 can understand?

Am I missing something else?

Good news! I think I did solve it.

The trick is to use meta ipsec exists in the nftables rules for the INPUT and FORWARD chain. Also the subnet for the VPN firewall zone must be excluded from masquerading. Create a script /etc/fwuser.nft in nftables-style

# /etc/fwuser.nft
meta ipsec exists ip saddr 10.10.20.0/29 counter accept comment "custom: allow for vpn"

...and include it in your /etc/config/firewall configuration by adding the following sections:

config include                        
        option type             'nftables'
        option path             '/etc/fwuser.nft'
        option position         'chain-pre'     
        option chain            'input_wan'
           
config include                        
        option type             'nftables'
        option path             '/etc/fwuser.nft'
        option position         'chain-pre'
        option chain            'forward_wan'

Also, make sure to exempt the subnet for your vpn firewall zone from masquerading by adding the following to your wan zone:

list masq_dest		'!10.10.20.0/29'

For completeness I add my complete firewall config.

complete /etc/config/firewall
config defaults
	option input			'ACCEPT'
	option output			'ACCEPT'
	option forward			'REJECT'
	option synflood_protect		'1'
	option flow_offloading		'1'
	option flow_offloading_hw	'1'

config zone
	option name		'wan'
	list network		'WAN'
	option input		REJECT
	option output		ACCEPT
	option forward		REJECT
	option masq		1
	option mtu_fix		1
	list masq_dest		'!10.10.20.0/29'

config zone
	option name		'home'
	list network		'HOME'
	option input		ACCEPT
	option output		ACCEPT
	option forward		ACCEPT

config zone
	option name		'vpn'
	list network		'VPN'
	option input		ACCEPT
	option output		ACCEPT
	option forward		ACCEPT
	option masq		1

config forwarding
	option src		home
	option dest		wan

config forwarding
	option src		vpn
	option dest		home

config forwarding
	option src		vpn
	option dest		wan

config rule
	option name		Allow-DHCP-Renew
	option src		wan
	option proto		udp
	option dest_port	68
	option target		ACCEPT
	option family		ipv4

config rule
	option name		Allow-Ping
	option src		wan
	option proto		icmp
	option icmp_type	echo-request
	option target		ACCEPT
	option family		ipv4

config rule
	option name		Allow-IGMP
	option src		wan
	option proto		igmp
	option target		ACCEPT
	option family		ipv4

config rule
	option name		Allow-IPSec-ESP
	option src		wan
	option proto		esp
	option target		ACCEPT

config rule
	option name		Allow-ISAKMP
	option src		wan   
	option dest_port	500
	option proto		udp
	option target		ACCEPT

config rule
	option name		Allow-IPSec-NAT
	option src		wan
	option dest_port	4500
	option proto		udp
	option target		ACCEPT

config rule
	option name		Allow-IPSec-AH
	option src		wan
	option proto		ah
	option target		ACCEPT

### ##################### ###        
###    I N C L U D E S    ###        
### ##################### ###         
                                      
config include                        
        option type             'nftables'
        option path             '/etc/fwuser.nft'
        option position         'chain-pre'     
        option chain            'input_wan'
           
config include                        
        option type             'nftables'
        option path             '/etc/fwuser.nft'
        option position         'chain-pre'
        option chain            'forward_wan'
1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.