nftables running in OpenWrt (Perfectly)

Hi everyone, I have been able to run nftables on my WRT3200ACM after several attempts and I want to share it with anyone who is interested.
Download its version in my case:
https://downloads.openwrt.org/releases/19.07.5/targets/mvebu/cortexa9/openwrt-imagebuilder-19.07.5-mvebu-cortexa9.Linux-x86_64.tar.xz
Unzip.
vim /include/target.mk
and add:
DEFAULT_PACKAGES: = uhttpd luci-mod-admin-full luci-theme-bootstrap luci-app-opkg luci-proto-ppp libiwinfo-lua luci-proto-ipv6 rpcd-mod-rrdns base-files libc libgcc busybox dropbear mtd opkg netifd fstools uclient-fetch logd urandom-seed urngd uci
DEFAULT_PACKAGES.router: = dnsmasq ppp ppp-mod-pppoe odhcpd-ipv6only odhcp6c nftables kmod-nft-core kmod-nft-nat kmod-nfnetlink kmod-nft-nat6 kmod-nft-netdev kmod-nft-offload kmod-nft-bridge kmod-bridge kmod-nft-arp kmod-nft-fib
Compile.
And voila, don't install luci-ssl this will add the iptables firewall.
When you install and configure ssh, upload an nftables.conf to / etc
My nftables.conf
#!/usr/sbin/nft -f

table inet raw {

    chain PREROUTING {
            type filter hook prerouting priority -300; policy accept;
    }

    chain OUTPUT {
            type filter hook output priority -300; policy accept;
    }

table inet mangle {

    chain PREROUTING {
            type filter hook prerouting priority -150; policy accept;
    }

    chain INPUT {
            type filter hook input priority -150; policy accept;
    }

    chain FORWARD {
            type filter hook forward priority -150; policy accept;
                #tcp flags & (syn|rst) == syn counter tcp option maxseg size set rt mtu
    }

    chain POSTROUTING {
            type filter hook postrouting priority -150; policy accept;
                #counter meta mark set 0x100000
                #mark 0x100000 counter ip dscp set 0x00
                #counter meta mark set 1
    }

table ip nat {

    chain PREROUTING {
            type nat hook prerouting priority -100; policy accept;
    }

    chain INPUT {
            type nat hook input priority -100; policy accept;
    }

    chain POSTROUTING {
            type nat hook postrouting priority -100; policy accept;
                oifname "eth1.2" masquerade fully-random
    }

table inet filter {

    chain INPUT {
            type filter hook input priority 0; policy drop;
                ct state related,established counter accept
                udp sport bootpc udp dport bootps counter accept
                udp sport bootps udp dport bootpc counter accept
                udp sport dhcpv6-server udp dport dhcpv6-client counter accept
                udp sport dhcpv6-client udp dport dhcpv6-server counter accept                     
                ip protocol igmp counter accept
                meta iifname != "eth1.2" counter accept
                #ct state untracked counter goto NOTRACK
                counter drop
    }

    chain FORWARD {
            type filter hook forward priority 0; policy drop;
                ct state related,established counter accept
                meta iifname != "eth1.2" counter accept
                counter drop
    }

    chain OUTPUT {
            type filter hook output priority 0; policy accept;
                #ip daddr 239.255.255.250 counter drop
    }                                                       

add in rc.local
/usr/sbin/nft -f /etc/nftables.conf

4 Likes

hello i'm interested for mikrotik hap ac2 :slight_smile:

thanks for you work !

Hello, I am happy to help you. Thanks
For Luci with ssl, install libustream-mbedtls20150806, px5g

Here I leave my current nftables.conf with dscp per flow and more, it can serve as a reference

#!/sbin/nft -f
# ipv4/ipv6 Simple & Safe Firewall

flush ruleset

table netdev filter {
	
	chain wanin {
		type filter hook ingress device eth1.2 priority -500;
		    ip saddr 8.8.8.8 udp sport 53 counter drop
	}
        
	chain lanin {
	        type filter hook ingress device br-lan priority -500;
        }	
}	

table inet raw {
	
        chain PREROUTING {
		type filter hook prerouting priority -300; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority -300; policy accept;
	}
}



table inet mangle {
	
        chain PREROUTING {
		type filter hook prerouting priority -150; policy accept;
	}

	chain INPUT {
		type filter hook input priority -150; policy accept;
		    #ct state invalid counter reject 
		    ip frag-off & 0x1fff != 0 counter reject
		    tcp flags & (fin | syn | rst | psh | ack | urg) == fin | syn | rst | psh | ack | urg counter reject
		    tcp flags & (fin | syn | rst | psh | ack | urg) == 0x0 counter reject
		    tcp flags syn tcp option maxseg size 1-536 counter reject
                    tcp flags & (fin|syn|rst|ack) != syn ct state new counter reject
		    mark & 0xff0 == 0x130 counter ip dscp set af22 return

	# real-time application
	## Rocket league
	udp dport 7000-9000 \
	meta mark set mark & 0xfffff00f ^ 0x110 counter ip dscp set af41 return

	## ICMP
	ip protocol icmp \
	meta mark set mark & 0xfffff00f ^ 0x110 counter ip dscp set af41 return

	## TCP low-flow
	meter wan-11-tcp { tcp sport . ip saddr timeout 10s limit rate 8 kbytes/second burst 16 kbytes } \
	meta mark set mark & 0xfffff00f ^ 0x110 counter ip dscp set af42 return

	## UDP low-flow
	meter wan-11-udp { udp sport . ip saddr timeout 10s limit rate 8 kbytes/second burst 16 kbytes } \
	meta mark set mark & 0xfffff00f ^ 0x110 counter ip dscp set af42 return

	# TCP midium-flow
	meter wan-12 { tcp sport . ip saddr timeout 3s limit rate 64 kbytes/second burst 512 kbytes } \
	meta mark set mark & 0xfffff00f ^ 0x120 counter ip dscp set af31 return

	# TCP high-flow & UDP {midium,high}-flow (default)
	meta mark set mark & 0xfffff00f ^ 0x130 counter ip dscp set af22
	}

	chain FORWARD {
		type filter hook forward priority -150; policy accept;
                    #tcp flags & (syn|rst) == syn counter tcp option maxseg size set rt mtu
	}

#	chain OUTPUT {
#		type route hook output priority -150; policy accept;
#	}

	chain POSTROUTING {
		type filter hook postrouting priority -150; policy accept;
		    mark & 0xff0 == 0x130 counter ip dscp set af23 return

	# internal traffic
	ip saddr 10.210.120.32/27 \
	meta mark set mark & 0xfffff00f ^ 0x200 counter ip dscp set af21 return

	# real-time application
	## Rocket league
	udp sport 7000-9000 \
	meta mark set mark & 0xfffff00f ^ 0x110 counter ip dscp set af41 return

	## ICMP
	ip protocol icmp \
	meta mark set mark & 0xfffff00f ^ 0x110 counter ip dscp set af41 return

	## TCP low-flow
	mark & 0xff0 != 0x120 \
	meter lan-11-tcp { tcp dport . ip daddr timeout 10s limit rate 16 kbytes/second burst 32 kbytes } \
	meta mark set mark & 0xfffff00f ^ 0x110 counter ip dscp set af42 return

	## UDP low-flow
	mark & 0xff0 != 0x120 \
	meter lan-11-udp { udp dport . ip daddr timeout 10s limit rate 16 kbytes/second burst 32 kbytes } \
	meta mark set mark & 0xfffff00f ^ 0x110 counter ip dscp set af42 return

	# TCP midium-flow
	meter lan-12 { tcp dport . ip daddr timeout 3s limit rate 512 kbytes/second burst 2 mbytes } \
	meta mark set mark & 0xfffff00f ^ 0x120 counter ip dscp set af31 return

	# TCP high-flow & UDP {midium,high}-flow (default)
	meta mark set mark & 0xfffff00f ^ 0x130 counter ip dscp set af23
	}
}



table ip nat {
	
        chain PREROUTING {
		type nat hook prerouting priority -100; policy accept;
		    #iif br-lan ether saddr 60:36:DD:7F:9E:32 udp dport 53 counter dnat 1.1.1.1:53
		    iif br-lan ip daddr { 8.8.8.8, 8.8.4.4 } udp dport 53 counter dnat 10.210.120.33:53
		    iif br-lan udp dport 53 counter dnat 10.210.120.33:53
		    iif br-lan tcp dport 53 counter dnat 10.210.120.33:53
		    #iif eth1.2 tcp dport 4321 counter dnat 10.210.120.47:80
		    #iif eth1.2 ip protocol icmp counter dnat 10.210.120.32/27
	}

	chain INPUT {
		type nat hook input priority -100; policy accept;
	}

	chain POSTROUTING {
		type nat hook postrouting priority -100; policy accept;
		    oif "eth1.2" counter masquerade 
		    #persistent
	}
}



table inet filter {
	
        chain INPUT {
		type filter hook input priority 0; policy accept;
                    ct state established,related counter accept
		    ct state invalid counter reject
		    #ip protocol icmp counter accept
		    meta iif br-lan counter accept
		    iif lo counter accept
                    #udp sport bootpc udp dport bootps counter accept
                    ip saddr 10.0.0.0/8 udp sport bootps udp dport bootpc counter accept
		    meta l4proto icmp icmp type { destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } counter accept
                    #udp sport dhcpv6-server udp dport dhcpv6-client counter accept
                    #udp sport dhcpv6-client udp dport dhcpv6-server counter accept                     
                    #ip protocol igmp counter accept
                    #ct state untracked counter goto NOTRACK
                    counter reject
	}

	chain FORWARD {
		type filter hook forward priority 0; policy drop;
                    ct state established,related counter accept
		    iif eth1.2 ct status dnat counter accept
		    ct state invalid counter reject
		    #meta iif br-lan ether saddr 84:38:38:F3:6E:F4 ip daddr youtube.com counter drop comment "Samu"
		    #meta iif br-lan ether saddr 16:A4:CE:11:02:F1 ip daddr youtube.com counter drop comment "Nata"
		    #meta iif br-lan ether saddr 18:CF:5E:43:35:8A ip daddr youtube.com counter drop comment "Portatil"
		    #iif br-lan ether saddr 60:36:DD:7F:9E:32 counter accept
		    iif br-lan udp dport { 443, 80, 5353 } counter reject
		    iif br-lan tcp dport { 5228, 5222, 5229 } counter reject
		    oif eth1.2 counter accept
		    #meta iif br-lan oif eth1.2 counter accept
                    counter reject
	}

	chain OUTPUT {
		type filter hook output priority 0; policy accept;
		    oif lo counter accept
		    ct state established,related counter accept
		    ct state invalid counter drop
		    oif br-lan counter accept
		    oif eth1.2 ct state invalid counter drop
		    oif eth1.2 counter accept
                    ip daddr 239.255.255.250 counter drop
	}                                                       

}	


Something else, if you want to log the connections you choose, install libnetfilter-log1, ulogd, ulogd-mod-nflog, ulogd-mod-extra.
Configure ulogd.conf
plugin = "/ usr / lib / ulogd / ulogd_inppkt_NFLOG.so"
plugin = "/ usr / lib / ulogd / ulogd_filter_IFINDEX.so"
plugin = "/ usr / lib / ulogd / ulogd_filter_IP2STR.so"
plugin = "/ usr / lib / ulogd / ulogd_filter_PRINTPKT.so"
plugin = "/ usr / lib / ulogd / ulogd_output_LOGEMU.so"
plugin = "/ usr / lib / ulogd / ulogd_raw2packet_BASE.so"

stack = log1: NFLOG, base1: BASE, ifi1: IFINDEX, ip2str1: IP2STR, print1: PRINTPKT, emu1: LOGEMU

[emu1]
file = "/ tmp / log / nftables.log"
sync = 1

Insert the rules where you want the log, example;
counter log prefix "REJECT" group 0 reject
To see;
tail -f /tmp/log/nftables.log

And you can use cron to clear the log or put it on a USB.
0 11,23 * * * /etc/init.d/ulogd stop && rm /tmp/log/nftables.log && /etc/init.d/ulogd start
1 Like

Hi, if I want to just add some tproxy rules with nftables without migrating the firewall, which modules are needed?
I installed nftables-json through LuCI, and tried the example on nftables manual. However:

/etc/nftables.conf:4:3-34: Error: Could not process rule: No such file or directory
tcp dport 60000 tproxy to :10000
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I guess it's missing modules. I installed kmod-ipt-tproxy and iptables-mod-tproxy but it's still the same.

I think it needs an nftables tproxy module, not ipt/iptables modules.

It's possible the tproxy stuff isn't yet available in nftables versions that OpenWrt is using?

1 Like

I have error..how to fix it?

* opkg_install_cmd: Cannot install package kmod-bridge.
make[2]: *** [Makefile:158: package_install] Error 255
make[1]: *** [Makefile:118: _call_image] Error 2
make: *** [Makefile:208: image] Error 2

Your script worked great for me on a dir-882, on rc1 it's the fastest version of openwrt i've seen yet. Thanks.

Still see this issue on 22.03.0 release, and didn't find any tproxy mod for ntfables. Have to rollback to 21.02 due to lack of TProxy support :cry:

It might be that you are looking for kmod-nft-tproxy, which I found easily enough.