How to use the WAN address in Nftables custom rules?

Hi,

I'm tryining to add NAT reflection rules for additional zones in fw4 to workaround this issue.

For that, I'm creating my rules in /etc/nftables.d/nat_reflection.nft. However I need to use the WAN address in the rule but I don't know how. I see that there are some variables defined like $wan_devices and $wan_subnets. Is there any way to get the current IPv4 WAN address?, also, any way to filter the subnets to get only the IPv4 one?

My rules look like:

chain user_dstnat {
    type nat hook prerouting priority dstnat; policy accept;
    iifname $lan_devices ip saddr 192.168.10.0/24 ip daddr $WAN_ADDRESS tcp dport 80 dnat ip to 192.168.7.5:80 comment "!fw4: forward-http (reflection for lan)"
    iifname $lan_devices ip saddr 192.168.10.0/24 ip daddr $WAN_ADDRESS tcp dport 443 dnat ip to 192.168.7.5:443 comment "!fw4: forward-https (reflection for lan)"
}

Thank you.

Hi, did you ever figure out how to do this? As it is not possible to define a whitelist for WAN->LAN port forwarding in LuCi, I had to create my own nftables rules. With that approach I lost the convenience of automatically generated reflection rules. I could create the necessary rules but for that I need the WAN interface address which changes on every reconnection (PPPoE). I would appreciate any ideas how to solve this problem. Thank you!

Hi, did you ever figure out how to do this? As it is not possible to define a whitelist for WAN->LAN port forwarding in LuCi, I had to create my own nftables rules.

You have the option to define a source IP or subnet in the port forward rule in LuCi: Advanced settings -> Source IP address. Not sure if that's enough for your case.

Another alternative I can think of is creating a prerouting rule to reject all IPs except the ones whitelisted to the port you are forwarding.

Thanks for your reply. I got it working with the following configuration:

config ipset
        option name 'fwd-allow'
        option match 'src_ip'
        option enabled '1'
        option loadfile '/root/fwd-allow.txt'

config redirect
        option dest 'lan'
        option target 'DNAT'
        option name 'fwd'
        option src 'wan'
        option src_dport 'pppp'
        option dest_ip 'zzz.zzz.zzz.zzz'
        option dest_port 'qqqq'

config rule
        option src 'wan'
        option ipset '!fwd-whitelist'
        option dest 'lan'
        list dest_ip 'zzz.zzz.zzz.zzz'
        option target 'REJECT'
        option name 'fwd-reject'

However, I do not feel comfortable with that solution. If the REJECT rule gets deleted or disabled accidentally, the service gets exposed to the whole internet.

My previous solution was a custom rule:

config include
        option type 'nftables'
        option path '/root/chain-post-dstnat_wan.nft'
        option position 'chain-post'
        option chain 'dstnat_wan'

Content of /root/chain-post-dstnat_wan.nft:

meta nfproto ipv4 ip saddr @fwd-allow tcp dport pppp counter dnat ip to zzz.zzz.zzz.zzz:qqqq comment "fwd-with-ipset"

That way, a single rule contains both the allowed addresses and the forwarding definition. If it is lost, nothing is exposed. This would work perfectly fine, the only problem is the missing reflection which I wanted to solve with a custom entry in chain 'dstnat_lan', similar to the ones generated automatically:

ip saddr xxx.xxx.xxx.0/24 ip daddr yyy.yyy.yyy.yyy  tcp dport pppp dnat ip to zzz.zzz.zzz.zzz:qqqq comment "!fw4: fwd (reflection)"

xxx.xxx.xxx -> LAN subnet
yyy.yyy.yyy.yyy -> WAN IP address
zzz.zzz.zzz.zzz -> LAN host IP address to forward to
pppp -> WAN facing port number
qqqq -> service port number on LAN host

As I have a dynamic WAN IP address, I do not know the value of yyy.yyy.yyy.yyy and was hoping there is some kind of a macro/variable containing the current WAN IP which could be used in the definition. Sadly, it seems there is no solution for that.

Thanks anyway for the idea!