SNAT rules with nftables

Since latest RC1 has switched to nftables (fw4) instead of iptables (fw3), I have encountered the problem of getting guest network to private network ips dropped while with some exceptions, e.g., access to NAS service for specific hosts.

Tried with:

config rule
        option name 'Allow Samba Access'
        list dest_ip '192.168.1.3'
        list dest_ip '192.168.1.7'
        option dest_port '445'
        option target 'ACCEPT'
        #option target 'SNAT'
        #option src_dip '192.168.1.2'
        list src_mac '00:xx:xx:xx:xx:4F'
        option src 'guest'
        option dest 'lan1'
        option direction 'out'
        option device 'wlan0'

and

config rule
        option name 'Block guest -> private network'
        list proto 'all'
        option src 'guest'
        option dest 'lan1'
        list dest_ip '0.0.0.0/8'
        list dest_ip '10.0.0.0/8'
        list dest_ip '127.0.0.0/8'
        list dest_ip '169.254.0.0/16'
        list dest_ip '172.16.0.0/12'
        list dest_ip '192.0.0.0/24'
        list dest_ip '192.0.2.0/24'
        list dest_ip '224.0.0.0/3'
        list dest_ip '192.168.0.0/16'
        list dest_ip '198.18.0.0/15'
        list dest_ip '198.51.100.0/24'
        list dest_ip '203.0.113.0/24'
        option target 'REJECT'

But the NAS rule does not work no matter which rule is before the other rule.

The other option, perhaps the most easy one, may be using SNAT, but the new nftables checked the rule and didn't accept src_dip option and called it 'unknown option'.

My question is, under the new fw4 stuff, how should I write the SNAT rule that's equivalent to the former fw3 era?

Your second rule looks just fine and in fact works as expected here (swapped guest with lan and lan1 with wan for testing). What specific problems do you encounter with it?

My test:

config rule                                     
        option name 'Allow Samba Access'    
        list proto 'all'                       
        option src 'lan'                     
        option dest 'wan'                       
        list dest_ip '192.168.1.3'
        list dest_ip '192.168.1.7'
        option target 'ACCEPT'                             
                                        
config rule                                 
        option name 'Block guest -> private network'
        list proto 'all'                       
        option src 'lan'                     
        option dest 'wan'                       
        list dest_ip '0.0.0.0/8'       
        list dest_ip '10.0.0.0/8'                          
        list dest_ip '127.0.0.0/8'      
        list dest_ip '169.254.0.0/16'           
        list dest_ip '172.16.0.0/12'        
        list dest_ip '192.0.0.0/24'            
        list dest_ip '192.0.2.0/24'          
        list dest_ip '224.0.0.0/3'              
        list dest_ip '192.168.0.0/16'  
        list dest_ip '198.18.0.0/15'                       
        list dest_ip '198.51.100.0/24'  
        list dest_ip '203.0.113.0/24'           
        option target 'REJECT'              

(My lan does not use the 192.168.1.0/24 range, so ping attempts there are routed out the an interface towards the ISP which drops them)

Testing from a lan client:

jow@j7:~$ ping -c 1 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
From 10.11.12.13 icmp_seq=1 Destination Port Unreachable

--- 192.168.1.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

jow@j7:~$ ping -c 1 192.168.1.3
PING 192.168.1.3 (192.168.1.3) 56(84) bytes of data.
^C
--- 192.168.1.3 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

jow@j7:~$ ping -c 1 192.168.1.7
PING 192.168.1.7 (192.168.1.7) 56(84) bytes of data.
^C
--- 192.168.1.7 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

jow@j7:~$ 

Note how the first ping towards 192.168.1.1 gets a Destination Port Unreachable, this indicates that the second firewall rule was rejecting it. The second and third ping tests towards 192.168.1.3 and 192.168.1.7 both came back without any reply, means they were matched by the first allow rule, went out wan and got dropped there in the ISP network.

I suppose the

        option direction 'out'
        option device 'wlan0'

options in your Samba-Allow rule are causing traffic to not get matched, remove those. For traffic from a random guest network client towards one of your samba servers the outgoing device is most likely not going to be wlan0 but rather something like br-lan1.

Just tried your suggestion and it works.

The culprit is the "option direction 'out'", I cannot imagine why it worked before, must have matched some other more loosen rule.

1 Like

Unfortunately 'Block guest -> private network' rule does not work as expected. Just with a Signal calling, the router still blocks udp packets destined to private ips, like 10.79.147.28 or 192.168.115.114, which should have already been rejected if the rules work.

The working rule of iptables are like this:

iptables -I forwarding_guest_rule -d 0.0.0.0/8 -j REJECT
iptables -I forwarding_guest_rule -d 10.0.0.0/8 -j REJECT
iptables -I forwarding_guest_rule -d 127.0.0.0/8 -j REJECT
iptables -I forwarding_guest_rule -d 169.254.0.0/16 -j REJECT
iptables -I forwarding_guest_rule -d 172.16.0.0/12 -j REJECT
iptables -I forwarding_guest_rule -d 192.0.0.0/24 -j REJECT
iptables -I forwarding_guest_rule -d 192.0.2.0/24 -j REJECT
iptables -I forwarding_guest_rule -d 224.0.0.0/3 -j REJECT
iptables -I forwarding_guest_rule -d 198.18.0.0/15 -j REJECT
iptables -I forwarding_guest_rule -d 198.51.100.0/24 -j REJECT
iptables -I forwarding_guest_rule -d 203.0.113.0/24 -j REJECT 

Edit: Of course the rule did not work as I expected, one possible reason might be the destination was not as ip, as domain instead perhaps?

Just confirmed today that the rule blocking packets whose dest_ip is private ip addresses not working.

Now I am desperately looking forward to an equivalent solution of the iptables rules with current fw4 (nftables).

Can you please post the uci rule that is not working? What's the output of nft list ruleset? For me dest_ip rules work as expected.

Thanks a lot for the tip.

Just checked with the nft list ruleset command and found the dest_ip rules was placed in input_guest chain, which is not correct.

Now I re-displaced the corresponding rules to the right position in firewall config file, now they moved to forward_guest fules in nft rule sets, and should be working now.