Skip to content

Convert firewall rules to nftables#66

Open
znerol wants to merge 5 commits into
mainfrom
feat-nftables
Open

Convert firewall rules to nftables#66
znerol wants to merge 5 commits into
mainfrom
feat-nftables

Conversation

@znerol

@znerol znerol commented May 18, 2026

Copy link
Copy Markdown
Member

A largely 1:1 conversion from iptables to nftables.

Munin uses the iptables binary for traffic accounting by ip address. Those rules need to be named exactly as how the iptables binary expects them (e.g., table ip filter chain INPUT).

@znerol

znerol commented May 18, 2026

Copy link
Copy Markdown
Member Author

There is quite some room for improvements (e.g., a general rule for ct state at the top):

    ct state vmap { established : accept, related : accept, invalid : drop }

Then the rest of the ingress rules could be much tighter (example).

Not sure whether to do the cleanup here or in a follow-up. What are your thoughts @maederm ?

@maederm

maederm commented May 18, 2026

Copy link
Copy Markdown
Contributor

I like the file based approach.

Not sure whether to do the cleanup here or in a follow-up. What are your thoughts @maederm ?
I'm ok with both.

What other kinds of cleanup do you have in mind? @znerol
I see that we could split the vip rules from the node rules and then allow without specifying the destination address. But then we'd lose the counters there.

We could still have individual counters like this:

        set allowed_portcounter {
                type inet_proto . inet_service
                size 131070
                flags dynamic
                counter
        }
[...]
        tcp dport { domain, http, https } add @allowed_portcounter {meta l4proto . tcp dport counter} counter accept

(I seriously hope that there is a more elegant solution. Or we just have some entries multiple times)

@znerol

znerol commented May 18, 2026

Copy link
Copy Markdown
Member Author

What other kinds of cleanup do you have in mind? @znerol
I see that we could split the vip rules from the node rules and then allow without specifying the destination address.

Yes.

#
# Filter rules
#
table inet nf_filter {

	chain filter_ingress {
		type filter hook input priority filter; policy drop;

		# Allow traffic on loopback interface.
		iif "lo" counter accept

		# Divert to service ip rules.
		ip daddr {{ ip4_vip_dns1 }} jump filter_ingress_service_ip
		ip daddr {{ ip4_vip_dns2 }} jump filter_ingress_service_ip
		ip6 daddr {{ ip6_vip_dns1 }} jump filter_ingress_service_ip
		ip6 daddr {{ ip6_vip_dns2 }} jump filter_ingress_service_ip

		# Divert to node ip rules.
		ip daddr {{ ip4 }} jump filter_ingress_node_ip
		ip daddr {{ ip6 }} jump filter_ingress_node_ip

		[...]
	}

	chain filter_ingress_service_ip {
		# Allow DoH / DoT queries to service address.
		tcp dport { 80, 443, 853 } counter accept

		# Reject unencrypted DNS to service address.
		tcp dport 53 counter reject
		udp dport 53 counter reject
	}

	chain filter_ingress_node_ip {
		[...]
	}

}

We could still have individual counters like this:

I do not know how much we need the port counters. Munin doesn't seem to query them. And we still have stats from dnsdist.

@znerol

znerol commented May 18, 2026

Copy link
Copy Markdown
Member Author

Found a small issue with the nginx acme challenge proxy fragment while debugging the ruleset: #67

@znerol znerol marked this pull request as ready for review May 21, 2026 05:23
@znerol

znerol commented May 21, 2026

Copy link
Copy Markdown
Member Author

I think I'm happy with the structure now. I'd like to tighten the icmp rule. I believe we do no need to allow more than echo request, neighbor discovery and router advertisement.

Edit: https://www.rfc-editor.org/info/rfc4890/#section-4.4

@maederm

maederm commented May 23, 2026

Copy link
Copy Markdown
Contributor

Regarding ICMPv6, I used this in the past:

icmpv6 type {echo-request,nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,
             nd-router-advert,mld-listener-query,destination-unreachable,
             packet-too-big,time-exceeded,parameter-problem} accept

However I'm good with just using meta l4proto ipv6-icmp counter accept doesn't make much of a difference.

(Based on https://serverfault.com/a/801137)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants