NFtables and QoS in 2021

replace just those lines with this one line:

1 Like
## masquerading for ipv4 output on WAN
	    table ip masq {
      map portmaps {
         type  inet_service : ipv4_addr
	 elements = { 1935 : 192.168.2.160, 3480 : 192.168.2.160, 3074 : 192.168.2.160, 3075 : 192.168.2.160, 3076 : 192.168.2.160, 3077 : 192.168.2.160, 3478 : 192.168.2.160, 3479 : 192.168.2.160, 9308 : 192.168.2.160, 3659 : 192.168.2.160 } # set these up to map ports to specific internal IPs
      }
      chain masqout {
	    type nat hook postrouting priority 0; policy accept;
	    oifname $wan masquerade

	}

	## this empty table is required to make the kernel do the unmasquerading
	chain masqin {
	    type nat hook prerouting priority 0; policy accept;
		iifname $wan protocol {udp,tcp} dnat to 192.168.2.160 #or whatever your console is
	   	}
	
} 	    
restart
/etc/nftables.conf:106:16-23: Error: syntax error, unexpected protocol, expecting newline or semicolon
                iifname $wan protocol {udp,tcp} dnat to 192.168.2.160 #or whatever your console is
                             ^^^^^^^^
root@OpenWrt:~#

It looks like it should say iifname $wan ip protocol ...

this is useful site for debugging such things: https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Ip

1 Like

ok seems better

        }

        chain forward {
                type filter hook forward priority filter; policy drop;
                ct state established,related accept
                iifname "lo" accept
                iifname { "eth0.5", "eth0.10" } oifname "br-lan" drop
                iifname { "eth0.5", "br-lan", "eth0.10" } oifname "wan" accept
                counter packets 0 bytes 0 log prefix "FIREWALL FAIL FORWARDING: " drop
        }
}
table ip masq {
        map portmaps {
                type inet_service : ipv4_addr
                elements = { 3074 : 10.13.17.33, 8888 : 10.13.17.91 }
        }

        chain masqout {
                type nat hook postrouting priority filter; policy accept;
                oifname "wan" masquerade
        }

        chain masqin {
                type nat hook prerouting priority filter; policy accept;
                iifname "wan" ip protocol { tcp, udp } dnat to 192.168.2.160
        }

Hi Daniel,

What about mss clamping with a nftables? how it handled? is it included in your conf? (maybe I missed that part)

Thanks

No, it's not included at the moment. if you want MSS clamping there's an example here: https://wiki.nftables.org/wiki-nftables/index.php/Mangling_packet_headers

So you'd need to make a raw packet prerouting chain... I can work it out later today if you test it. Or if you figure it out, let us know and I'll copy it into the script.

Always not

Normally in game open...

Sure, will do!

Just let me know and I will perform the needed tests!

1 Like

im playing COD also, I will test nftables on the evening and check if I have similar issues. Maybe it is related to mss? just an idea if you have pppoe and no mss clamping activated, psn will bring you NAT3

1 Like

Ok, I pushed a version that has an MSS clamping line based on the example from the wiki, let me know if it works. It also has a commented out DMZ line.

2 Likes

Thanks, i have to exit for a few hours, but, i will provide feedback this evening!

1 Like

ok i' come back i will test your push for dmz
@dlakelan

i can't see the new push

it was sitting there asking for a password... I pushed now.

1 Like

ok he has no error but dmz doesn't work i have put like this

and he has error to dmz push not "dat" but "dnat" :wink:

table ip masq {
      map portmaps {
         type  inet_service : ipv4_addr
	 elements = {3074 : 10.13.17.33, 8888 : 10.13.17.91 } # set these up to map ports to specific internal IPs
      }
      chain masqout {
	    type nat hook postrouting priority 0; policy accept;
	    oifname $wan masquerade

	}

	## this empty table is required to make the kernel do the unmasquerading
	chain masqin {
	    type nat hook prerouting priority 0; policy accept;

	    iifname $wan dnat to tcp dport map @portmaps
	    iifname $wan dnat to udp dport map @portmaps

	    #if you want to do a DMZ style "all ports sent to this address" do this:

	    iifname $wan ip protocol {tcp,udp} dnat to 192.168.2.160


	}
	
}

maybe i will do desinstall upnp of my router ?

absolutely, do not use UPNP with this!

Hello .. i also play cod. Have the same problem with the nat type not open with your script.
I was looking at some old nft code when i was testen nftables.
When i put this line iif wan ct status dnat counter accept in de foward chain i get open nat. @dlakelan maybe you no why this works. I'm not an expert.
My setup is Wrt32X kernel 5.10.97. I build my own image from master.

2 Likes

Nice find. I pushed a version adding a line like that to the forward table. It matches on iifname $wan which is more reliable.

Weird thing is that dnat is reliable for me in my own firewall without this... though I just dnat a few ports for things like a mumble server etc.

@dlakelan another question. I'm using Adguardhome at my router at port 5353. I would like to forward port 192.168.1.1:53 tot 192.168.1.1:5353 .
I could only get this to work if i put this line meta iif br-lan counter accept in the input chain. The next line is

iif br-lan udp dport 53 counter dnat 192.168.1.1:5353
iif br-lan tcp dport 53 counter dnat 192.168.1.1:5353

in the masqin chain. Do you have a better solution for this?

Daniel,

For the moment I'm using the router as an AP, so behind the router I have other router.

The wan device is wan
The lan device is br-lan
Openwrt 21.02.1

the output of nft list ruleset:

Summary
root@OpenWrt:~# nft list ruleset
table inet filter {
	chain input {
		type filter hook input priority filter; policy drop;
		ct state established,related accept
		iifname "lo" accept
		ip6 nexthdr ipv6-icmp accept
		ip protocol icmp icmp type { destination-unreachable, router-advertisement, router-solicitation, time-exceeded, parameter-problem } accept
		ip protocol igmp accept
		ip protocol icmp iifname "br-lan" accept
		udp dport 123 iifname "br-lan" accept
		iifname "br-lan" ip protocol udp udp sport 68 udp dport 67 log prefix "FIREWALL ACCEPT DHCP: " accept
		iifname "br-lan" udp sport 546 udp dport 547 accept
		iifname "wan" udp sport 547 udp dport 546 accept
		ct state new tcp dport 22 meter ssh-meter4 size 65535 { ip saddr limit rate 10/minute burst 15 packets } accept
		ct state new ip6 nexthdr tcp tcp dport 22 meter ssh-meter6 size 65535 { ip6 saddr limit rate 10/minute burst 15 packets } accept
		iifname "br-lan" tcp dport { 80, 443 } accept
		iifname "br-lan" udp dport 53 meter dommeter4 size 65535 { ip saddr limit rate 240/minute burst 240 packets } accept
		iifname "br-lan" udp dport 53 meter dommeter6 size 65535 { ip6 saddr limit rate 240/minute burst 240 packets } accept
		iifname "br-lan" tcp dport 53 meter dommeter4tcp size 65535 { ip saddr limit rate 240/minute burst 240 packets } accept
		iifname "br-lan" tcp dport 53 meter dommeter6tcp size 65535 { ip6 saddr limit rate 240/minute burst 240 packets } accept
		counter packets 18 bytes 1620 log prefix "FIREWALL INPUT DROP: " drop
	}

	chain forward {
		type filter hook forward priority filter; policy drop;
		tcp flags syn tcp option maxseg size set 1450
		ct state established,related accept
		iifname "lo" accept
		counter packets 718 bytes 45808 log prefix "FIREWALL FAIL FORWARDING: " drop
	}
}
table ip masq {
	map portmaps {
		type inet_service : ipv4_addr
		elements = { 3074 : 192.168.1.55 }
	}

	chain masqout {
		type nat hook postrouting priority filter; policy accept;
		oifname "wan" masquerade
	}

	chain masqin {
		type nat hook prerouting priority filter; policy accept;
		iifname "wan" dnat to tcp dport map @portmaps
		iifname "wan" dnat to udp dport map @portmaps
	}
}
table inet tags {
	chain tagrouted {
		type filter hook postrouting priority filter; policy accept;
		jump cttags
	}

	chain cttags {
		ip protocol tcp tcp sport != { 2049 } ip dscp < af41 ct bytes >= 35000000 ip dscp set cs1
		ip6 nexthdr tcp tcp sport != { 2049 } ip6 dscp < af41 ct bytes >= 35000000 ip6 dscp set cs1
		ip protocol udp ip dscp < cs5 udp dport != { 53, 80, 443 } udp sport != { 53, 80, 443 } meter udp4meter size 65535 { ip saddr . ip daddr . udp sport . udp dport limit rate over 200/second burst 100 packets } counter packets 0 bytes 0 ct mark set 0x00000055
		ip6 nexthdr udp ip6 dscp < cs5 udp dport != { 53, 80, 443 } udp sport != { 53, 80, 443 } meter udp6meter size 65535 { ip6 saddr . ip6 daddr . udp sport . udp dport limit rate over 200/second burst 100 packets } counter packets 0 bytes 0 ct mark set 0x00000055
		ct mark 0x00000055 numgen random mod 10000 < 5 ct mark set 0x00000000 comment "small probability to unmark over-threshold connections"
		ct mark != 0x00000055 ip protocol udp ip dscp < cs5 udp dport != { 53, 80, 443 } udp sport != { 53, 80, 443 } ct avgpkt 0-450 counter packets 19 bytes 1444 ip dscp set cs5
		ct mark != 0x00000055 ip6 nexthdr udp ip6 dscp < cs5 udp dport != { 53, 80, 443 } udp sport != { 53, 80, 443 } ct avgpkt 0-450 counter packets 0 bytes 0 ip6 dscp set cs5
		jump tagchain
	}

	chain tagchain {
		ip saddr { 10.0.98.113 } ip protocol udp ip dscp set cs6
		ip daddr { 10.0.98.113 } ip protocol udp ip dscp set cs6
		udp dport 3478-3479 ip dscp set cs5
		udp dport 3478-3479 ip6 dscp set cs5
		udp sport 3478-3479 ip dscp set cs5
		udp sport 3478-3479 ip6 dscp set cs5
		tcp sport 25565 ip dscp set cs5
		tcp sport 25565 ip6 dscp set cs5
		tcp dport 25565 ip dscp set cs5
		tcp dport 25565 ip6 dscp set cs5
		udp sport 10000 ip dscp set af41
		udp dport 10000 ip dscp set af41
		udp sport { 3478-3479, 8801-8810 } ip dscp set af41
		udp dport { 3478-3479, 8801-8810 } ip dscp set af41
	}
}

No internet in my case, what im missing?

yeah, I think you want a "redirect" not a dnat.

in the masqin chain:

	   iifname $lan tcp dport 53 redirect to 5353 #to redirect your DNS on the router

Then in the input chain:

		iifname $lan udp dport {domain,5353} meter dommeter4 { ip saddr limit rate 240/minute burst 240 packets} accept
		iifname $lan udp dport {domain,5353} domain meter dommeter6 { ip6 saddr limit rate 240/minute burst 240 packets} accept