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