Re: nftables port forward on DHCP interface to static IP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2021/04/19 13:22, Pekka Järvinen wrote:
On Sun, 18 Apr 2021 at 22:23, Frank Myhr <fmyhr@xxxxxxxxxxx> wrote:

Hi Pekka,

Try:
iifname $wanif tcp dport 12345 dnat 192.168.1.11

or
iifname $wanif tcp dport {12345} dnat 192.168.1.11
         (but the braces are unnecessary unless you want to add more than one dport)

https://wiki.nftables.org/wiki-nftables/index.php/Performing_Network_Address_Translation_(NAT)#Destination_NAT

Thanks. I managed to fix it just moments ago.

Great! Thanks for reporting back. A few comments:


I had remnants of iptables kernel modules which I blacklisted:

# cat /etc/modprobe.d/blacklist.conf
blacklist ip_tables
blacklist iptable_nat

Good to have those out of the way.


I also upgraded kernel to 5.11.14.

Probably not necessary, but think it can't hurt.


This might have caused the whole line erroring earlier.

Yes, recent nftables / kernels have improved error reporting. But you were already on 5.11.2... so probably not much difference.


I moved NAT related stuff to ip (IPv4) filter instead of inet:

Two comments:

1) Mea culpa! I didn't read your original ruleset carefully enough. Just looking at it quickly I thought you had a trivial syntax error. But now I see:

a) Your original rule in inet table:
iifname $wanif tcp dport {12345} dnat ip to 192.168.1.11

looks fine to me according to syntax at
https://wiki.nftables.org/wiki-nftables/index.php/Performing_Network_Address_Translation_(NAT)#Inet_family_NAT

I don't think it should be necessary to move from inet to ip table to get this to work. You might have encountered a bug which should be reported.

Could you please check the version of your nft command?:
nft -v

b) The other part of the syntax error I mistakenly thought I spotted is whether or not to include the "to" keyword, i.e. "dnat to {ip}" vs. just "dnat {ip}". Looking at nftables source parser_bison.y it appears to me that the "to" is optional in case of nat in ip (IPv4) table but NECESSARY when doing nat in inet table. The nft man page uses "dnat to", whereas the wiki uses bare "nat" in places. 'nft list ruleset' always includes the "to". I will update the wiki to include the "to" in all cases: it seems a good habit since inet table requires it.


define wanif = wan0
define lanif = lan0
define home_net = 192.168.1.0/24
define home_net_gw = 192.168.1.1

# Port forwards
define port_fwd_ip = 192.168.1.11
define port_fwds_udp = {12345}
define port_fwds_tcp = {54321}

# IPv4 & IPv6
table inet filter {

Nitpick: just in my personal opinion, better not to use table name that is a nftables keyword ("filter"). I know the wiki does it lots of places. And it's not technically wrong. But:

a) There have been recent bugs (hopefully now all fixed!) from nft confusing a user-named object with a reserved keyword.

b) Again just in my opinion, it makes the ruleset harder to read: *I* have to determine whether a word is a keyword or a label from its context.

    # ...

    chain forward {
        type filter hook forward priority filter; policy drop;
        ct state invalid drop

        # ...

        # Port forward WAN -> LAN
        iifname $wanif oifname $lanif tcp dport $port_fwds_tcp accept
comment "Accept forwarded TCP"
        iifname $wanif oifname $lanif udp dport $port_fwds_udp accept
comment "Accept forwarded UDP"
    }

    # ...

}

# IPv4
table ip filter {

    # NAT
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;
        ct state invalid drop

        # TCP SYN (CT NEW)
        tcp flags & (fin|syn|rst|ack) != syn ct state {new} drop

You're filtering in a nat chain, generally not a good idea. My understanding is that, since nat is based on connection tracking, this chain will see only the FIRST packet of each connection. You probably want additional rules in a filter chain (maybe you already have them in the #... in your forward chain).

You could add counters (if only temporarily) to your rules in your nat and filter chains and see where packets are getting handled.

Also a nitpick: no need for {} around the state here.


        # Port forward WAN -> LAN
        iifname $wanif tcp dport $port_fwds_tcp dnat to $port_fwd_ip
comment "Port forwards TCP"
        iifname $wanif udp dport $port_fwds_udp dnat to $port_fwd_ip
comment "Port forwards UDP"
    }

    # NAT
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        ct state invalid drop
        oifname $wanif masquerade persistent comment "MasqNAT"
    }
}


Best regards,
Frank




[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux