[Solved] DNAT rules with multiple targets or ipsets

Hi

I am trying to set up a DNAT rule to redirect HTTP(S) requests having different hosts in different networks as destination to a specific IP. While I was able to achieve this with on src_dip, I still need to figure this out how to do this for multiple src_dips, since it is quite clunky to create a DNAT rule for each host. Can this be even done. Or could I use IPsets for that?

Thanks for your help!

You can use maps or verdict maps.

config ipset
        option name 'dnat_src_dips'
        option match 'dest_ip'
        list entry '1.2.3.4'
        list entry '5.6.7.8'
        list entry '9.10.11.12'

config redirect
        option name 'HTTPS_DNAT'
        option target 'DNAT'
        option src 'lan'
        list proto 'tcp'
        option src_dport '443'
        option ipset 'dnat_src_dips'
        option dest_ip '192.168.1.100'

Hi,

these are new to me. How do I use them?

Hi, thanks for your template. I am just wondering if I really have to match for dest_ip in the IP set, even though the DNAT rule usually uses src_dip to match for the intendet destination of the request.

In the example provided, all HTTPS requests originating from the lan and directed to the IPs listed in the set will be DNATed to 192.168.1.100. You can use it trying to create your own rules or keep wondering if it's right or not, it's up to you.

Ok, I've tried it. This is my rule:

config redirect
        option target 'DNAT'
        option src 'lan'
        option src_dport '443'
        option name 'https-internal-to-traefik'
        option ipset 'traefik-int-hosts'
        option dest_port '443'
        list proto 'tcp'
        option dest_ip '10.10.0.40'

and this my IPset

config ipset 
        option name 'traefik-int-hosts'
        option family 'ipv4'
        list match 'dest_ip'
        list entry '10.20.0.30'
        list entry '10.20.0.40'

I've created everything via luci and added the ipset manually to the DNAT rule. Unfortunately it dies not work. Not seeing any incoming requests if I browse to the IPs in the iptset.

Do the requests to the IPs listed in the set originate from the lan zone?

Verify that the set has been created.

nft list set inet fw4 traefik-int-hosts

Verify that the DNAT rule has been created.

nft list chain inet fw4 dstnat_lan

It should look something like this:

tcp dport 443 ip daddr @traefik-int-hosts counter ... dnat ip to 10.10.0.40:443 comment ...

Check the rule counter.

This looks to me that the rules didn't get created:

root@openwrt:~# nft list set inet fw4 traefik-int-hosts
table inet fw4 {
        set traefik-int-hosts {
                type inet_service
        }
}
root@openwrt:~# nft list chain inet fw4 dstnat_lan
table inet fw4 {
        chain dstnat_lan {
                ip saddr 192.168.1.0/24 ip daddr <my public IP> tcp dport 80 dnat ip to 192.168.1.2:80 comment "!fw4: 80 - traefik-ext-proxy (reflection)"
                ip saddr 192.168.1.0/24 ip daddr <my public IP> tcp dport 443 dnat ip to 192.168.1.2:443 comment "!fw4: 443 - traefik-ext-proxy (reflection)"
        }
}
1 Like

Well, for some reason the type of the set is wrong.
The very same rules create the correct nftables entries for me (on 23.05.3).

root@MikroTik:~# nft list set inet fw4 traefik-int-hosts
table inet fw4 {
        set traefik-int-hosts {
                type ipv4_addr
                elements = { 10.20.0.30, 10.20.0.40 }
        }
}
root@MikroTik:~# nft list chain inet fw4 dstnat_lan
table inet fw4 {
        chain dstnat_lan {
                tcp dport 443 ip daddr @traefik-int-hosts counter packets 0 bytes 0 dnat ip to 10.10.0.40:443 comment "!fw4: https-internal-to-traefik"
        }
}

Ok, I've messed around for a while and I couldn't get it working. After getting somewhat annoyed, I did a reboot. Turns out, that the reboot fixed it and the rule and the ipset are working now. Thanks!

1 Like

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