Is the firewall broken when an invalid rule is included?

Hi!

The configuration of my router is not yet well defined. It was connected to the Internet when I added some invalid rules by mistake in /etc/custom-netdev-table.nft. I realised that something was wrong, too late.

nft list ruleset didn't display anything. But fw4 print displayed the rules. The log told me that I had made syntax errors in some rules defined in /etc/custom-netdev-table.nft.

Specify packet priority for packets forwarded to ISP.
uci -q batch <<-EOF
	add firewall include
	set firewall.@include[-1].enabled='1'
	set firewall.@include[-1].type='nftables'
	set firewall.@include[-1].path='/etc/custom-netdev-table.nft'
	set firewall.@include[-1].position='ruleset-post'
EOF

uci -q batch <<-EOF
	add firewall include
	set firewall.@include[-1].enabled='1'
	set firewall.@include[-1].type='nftables'
	set firewall.@include[-1].path='/etc/custom-postrouting-chain.nft'
	set firewall.@include[-1].chain='mangle_postrouting'
	set firewall.@include[-1].position='chain-append'
EOF

uci -q batch <<-EOF
	add firewall include
	set firewall.@include[-1].enabled='1'
	set firewall.@include[-1].type='nftables'
	set firewall.@include[-1].path='/etc/custom-arp-table.nft'
	set firewall.@include[-1].position='ruleset-post'
EOF

uci -q batch <<-EOF
	# The local network has several subnets, which are assigned to different
	# firewall zones. Subnets must be assigned to new zones.

	# Remove the original 'lan' network.
	del_list firewall.@zone[0].network='lan'

	# Add our new subnet in the 'lan' zone.
	add_list firewall.@zone[0].network='home'
EOF

uci -q batch <<-EOF
	add firewall zone
	set firewall.@zone[-1].name='dmz'
	set firewall.@zone[-1].network='dmz'
	set firewall.@zone[-1].input='REJECT'
	set firewall.@zone[-1].output='ACCEPT'
	set firewall.@zone[-1].forward='REJECT'
EOF

uci -q batch <<-EOF
	add firewall rule
	set firewall.@rule[-1].name='Allow-DMZ-DHCPv6'
	set firewall.@rule[-1].src='dmz'
	set firewall.@rule[-1].proto='udp'
	set firewall.@rule[-1].dest_port='547'
	set firewall.@rule[-1].family='ipv6'
	set firewall.@rule[-1].target='ACCEPT'
EOF

uci -q batch <<-EOF
	add firewall rule
	set firewall.@rule[-1].name='Allow-DMZ-ICMPv6-Input'
	set firewall.@rule[-1].src='dmz'
	set firewall.@rule[-1].proto='icmp'
	add_list firewall.@rule[-1].icmp_type='echo-request'
	add_list firewall.@rule[-1].icmp_type='echo-reply'
	add_list firewall.@rule[-1].icmp_type='neighbour-advertisement'
	add_list firewall.@rule[-1].icmp_type='neighbour-solicitation'
	add_list firewall.@rule[-1].icmp_type='router-solicitation'
	set firewall.@rule[-1].family='ipv6'
	set firewall.@rule[-1].target='ACCEPT'
EOF

uci -q batch <<-EOF
	add firewall zone
	set firewall.@zone[-1].name='livebox'
	set firewall.@zone[-1].network='livebox'
	set firewall.@zone[-1].input='ACCEPT'
	set firewall.@zone[-1].output='ACCEPT'
	set firewall.@zone[-1].forward='ACCEPT'
EOF

uci -q batch <<-EOF
	add firewall forwarding
	set firewall.@forwarding[-1].src='livebox'
	set firewall.@forwarding[-1].dest='wan'
EOF

I don't have much experience of how the firewall works. As a result, I don't know whether some rules were still active or whether only invalid rules were rejected by nftables.

Full disclosure -- I'm not adept at reading nftables based rules and the like, so I cannot really provide specific guidance at that level.

Just one thing I wanted to ask, though:

With that in mind, why are you working at the lower level nftables definition instead of the higher level (and generally easier to understand/use) UCI/LuCI methods? Obviously if you're doing this to learn, that's awesome. Or if there are rules that are more complicated to implement with the higher level methods, that also makes sense. But, generally speaking, the UCI approach is easier and won't easily allow you to make syntactically invalid rules. (although, to be clear, nothing is stopping you from making 'bad' rules that don't achieve or even run counter to your goals).

1 Like

The answer is simple.

The PCP of raw sockets cannot be modified anywhere other than in the netdev table. I also need to change the priority of all packets in VLAN 840 to the value 5. This is required by my ISP. To do this, I use the nftables v.1.1.3.

table netdev filter
flush table netdev filter

table netdev filter {
        chain egress {
                type filter hook egress device sfp1 priority filter; policy accept;
                vlan id 832 udp dport 67 vlan pcp set 6 ip dscp set cs6 comment "Set DSCP value to 6 for DHCPv4 packets"
		        vlan id 840 meta nfproto ipv4 meta l4proto igmp counter vlan pcp set 5
        }
}

Otherwise, the alternative looks something like this.

config device
        option name 'sfp1.840'
        option type '8021q'
        option ifname 'sfp1'
        option vid '840'
        list egress_qos_mapping '0:5'
        list egress_qos_mapping '1:5'
        list egress_qos_mapping '2:5'
        list egress_qos_mapping '3:5'
        list egress_qos_mapping '4:5'
        list egress_qos_mapping '5:5'
        list egress_qos_mapping '6:5'
        list egress_qos_mapping '7:5'
config device
        option name 'sfp1.832'
        option type '8021q'
        option ifname 'sfp1'
        option vid '832'
        list egress_qos_mapping '1:0'
        list egress_qos_mapping '0:6'
        list egress_qos_mapping '6:6'
        option macaddr 'A2:34:56:78:19:26'
1 Like

What version of OpenWrt is this for?

ubus call system board 

At the moment, I don't know. I need to connect to the router. Is this dangerous? I don't know if the firewall has broken completely or if only invalid rules have been rejected?

I can provide the information in five minutes. I need to restart my PC to be able to connect to the router because I only have one network interface.

No, certainly not. It no is a safe command that just gets some version information from the system.

If not obvious YOUR table is not valid and you need to extract packet offsets from raw payload at netdev level.
Yes, bad includes make ruleset invalid, as opposed to bad rules which get ignored with the warning.

Yes, I know. What I meant was, is my router possibly compromised if the firewall has broken?

I can’t say. If in doubt, reset to defaults.

2 Likes

With defaults ssh and www were open to the internet. No password - 30s, simple passwird -> 5min

1 Like

Totally, preferably in failsafe if evil diverted commands.

It seems to me that the procedure I mentioned is logically valid. I use an expression to modify the fields as described in the manual page.

I think I was logged in as root. But the SSH connection by key was activated for another user. The SSH password and the SSH connection for the root user were disabled.

meta ... is populated before "raw" after packets are re-assembled.
ct ... is populated before "mangle"
neither applies to your table hook.
ref: https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks

This is the egress hook. I've read that you can filter with meta in the netdev table.

Nope, you have to do all with offsets.
same as ct state new -> tcp flags syn when moving input to raw.
Make table inet, then
nft -c -d netlink -f file.nft
it shows offsets in bytecode offered.
also fear not extracting 2 fields in one shot and comparing to binary outcome.
egress hook - cool, rest of filtering kind of figured it, but the info is no more available when you start at low priority on a different interface.

I don't understand what you're telling me. You can filter by field using ‘payload expressions’ in the egress chain of a table in the netdev family.

Yep, bytecode debug just helps with telling offsets.
I see dhcp in raw_postrouting btw.

Short answer, yes - but we don't know…

The firewall is a rather complex piece of software, it's very easy to get that wrong. The defaults using fw4 (the abstracted zone based rule sets) are secure and work for the vast majority of use cases - and the rules can be extended as needed. If you diverge from this, or completely forego this in favor of your own nftables based rules, you need to be aware what you're doing. Failure cases range from the device being inaccessible, 'internet not working', gaping security issues or even subtle issues of any kind. It's very easy to get it wrong, easier than getting it right.

OpenWrt allows you to do 'anything', but the more you diverge from 'normal' operations, the more you need to take the responsibility for your actions.

I know what I'm doing. I've made a big strategic mistake combined with a simple syntax error.

I haven't read anywhere that you can't use the meta expression in a netdev table. Nor did I read any warning in the OpenWrt documentation that including a file with syntax errors could cause the firewall "to dissolve" (break any rules).

There is a subtle error message when you reload/restart on a live system and old rules are kept. but that does not persist after reboot.