Build individual nftables rules or a whole starter ruleset. Covers the stateful base every firewall needs, which is the part most examples leave out.
With policy drop, a ruleset that only allows port 22 will still break, because replies to your own outbound traffic are not new connections and get dropped. Every working ruleset starts with ct state established,related accept, then ct state invalid drop, then accepting loopback. Get those in before anything else. And test with nft -c -f before applying: a mistake in an input chain on a remote server locks you out immediately, with no equivalent of ufw asking whether you are sure.
This nftables rule generator builds individual rules for the inet filter table and a complete starter ruleset with stateful connection tracking already in place. It covers port sets, source and interface matching, rate limiting for brute-force resistance, logging with a prefix, and the reject versus drop distinction. nftables replaced iptables as the kernel default, and this is the syntax modern distributions actually use.
nftables. It is the kernel default, iptables on modern systems is usually a translation layer on top of it, and distributions have been migrating for years. Existing iptables knowledge transfers conceptually, and iptables-translate will convert individual rules for you.
One table that handles both IPv4 and IPv6. With the older ip and ip6 families you write and maintain every rule twice, and the classic failure is a host firewalled correctly on IPv4 and wide open on IPv6. inet avoids that entirely.
Rules added with nft add exist only in memory. Put them in /etc/nftables.conf and enable the nftables service, or dump the running ruleset with nft list ruleset > /etc/nftables.conf once you are happy with it.
Docker inserts its own rules and publishes ports by manipulating the forward path, so a published port is reachable even when your input chain never allowed it. Bind containers to 127.0.0.1 and proxy to them, which is the reliable fix regardless of firewall.