nftables and sets 2023-01-30
If you want to keep "bad traffic" from getting to your computer or device you are probably looking for a firewall of some kind. If you are running Windows your device comes with a firewall (though you may have bigger issues to deal with). If you are running Linux you have a selection of firewall applications to choose from. In general, these firewall applications are probably just front ends for nftables. Even if you are using iptables it is likely that you are really using legacy commands for nftables. nftables is made by netfilter... and iptables [the predecessor to nftables] was also made by netfilter. The trouble is, some day the old iptables commands are supposed to disappear and everyone is expected to use just plain old nftables because it is better than the old iptables. That is, except if you use sets.
So let's begin by looking at an example of an iptables command:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
One of the reasons nftables is supposed to be better than iptables is improved syntax.
table inet filter {
chain input {
type filter hook input priority 0;
tcp dport { 22 } ct state new accept
}
}
Oh yeah. That's much better. In fact I am not even convinced that is the correct way to allow access to SSH, it is just a paste of the closest thing I could find to it. The "state new" part would allow new connections and a "related,established" statement would be needed elsewhere to make this work. Ultimately, the amount of text required to allow SSH is the same as what you see above and the syntax is generally similar. Another reason nftables is supposed to be better than iptables is because you don't need to use a script. You see, with iptables you would normally create a shell script that has a bunch of iptables commands all laid out in order. Well in nftables you create a config file that has all of your nftables commands. Seriously, this is not an improvement, it is the exact same thing. But it still isn't even the point...
The point is that iptables has/had a companion application called ipset which could group together multiple IP addresses. Then your set of IP addresses could be used in iptables rules like this:
iptables -A INPUT -p tcp -m set --match-set canadaips src --match multiport --dports 993,995,587 -j ACCEPT
In this example the set named canadaips would contain all of the IP addresses that are in Canada, and the command would allow access to send/receive email from those IP addresses. The lookups are very fast and do not have a lot of overhead. If I am troubleshooting connectivity problems I can check to confirm that my current IP address is in the set by doing this:
ipset test canadaips 2.4.6.8
The nftables equavalent to that is:
nft get element ip filter canadaips { 2.4.6.8 }
Oh yeah, that's better. Well, with ipset I can use the "swap" action to update a set immediately. For example, the list of Canadian IPs is kind of a long list and maybe it takes my computer a little time to populate the set with all those addresses. What I would do instead is create a tempset and then populate it. While it is populating my iptables rule is still using a set called canadaips so it is just using the current list. Once the tempset is fully populated I run:
ipset swap tempset canadaips
... and my canadaips set is instantly updated. Without this swap feature I would have to empty my canadaips set and then populate it in place, which would mean that some network connections could be dropped while the set is incomplete. What does nftables do to accommodate this? Nothing. nftables has no swap equivalent for sets. Now the list of Canadian IPs is about 5500 lines and doesn't actually take very long to process. But what if I had a set that contained multiple countries or many organizations? That could be tens of thousands or hundreds of thousands of lines. What if I hosted my services on a small home server that doesn't have the same fancy fast processor I'd get from a hosting company? It could take a while to process. And what if the set I'm using is intended to block traffic rather than allow it? My nftables firewall [or at least part of it] would essentially be down temporarily while the set populates. Pump the brakes snowflake, that's a hard no.
Can anyone tell me how to maintain access to iptables after debian decides it is no longer worth keeping?