A sensible server firewall drops inbound traffic by default and then allows only what you named: replies to your own connections, loopback, and the service ports you run. In nftables that is a short ruleset. The risk is locking yourself out over SSH, so check the file first and schedule a rollback.
The shape of the ruleset
The nftables wiki's simple server example uses the same structure: one table, an input chain with policy drop, a rule that accepts established and related connections and drops invalid ones, a rule for loopback, then a rule opening the service ports. It also drops forwarded traffic when the machine is not a router, and leaves output at the default accept.
Here is a smaller version written for a host that serves SSH and HTTPS:
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iifname "lo" accept
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
tcp dport 22 accept
tcp dport 443 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
}
Using the inet family means one table covers IPv4 and IPv6. The wiki notes that for IPv6 you must accept neighbour discovery messages or connectivity breaks, which the broad icmpv6 line above covers. You can narrow it to specific types and add a rate limit, as the wiki's example does for ping, if you do not want the host to answer probes freely.
Load it without a lockout
- Check syntax first.
nft -c -f /etc/nftables.confparses the file without applying it. - Keep a second session open. If the first one dies after the change, the second is your way back.
- Schedule a rollback. For example,
at now + 5 minuteswith a command that flushes the ruleset, then cancel it after you confirm access. Aflush rulesetrollback leaves the host open, so only use it as a temporary safety net. - Apply.
nft -f /etc/nftables.conf. - Test from outside. Check that SSH and HTTPS work and that a closed port is dropped.
- Make it persistent with your distribution's nftables service, and confirm after a reboot.
Choices worth making on purpose
- Limit SSH sources. Replace
tcp dport 22 acceptwith a rule that matchesip saddragainst your office or VPN range if you can. - Log drops carefully. A log rule on dropped traffic is useful briefly, and noisy forever. Rate limit it.
- Output filtering. The default output policy is accept. Egress rules are stronger, harder to maintain and worth it for servers with a narrow job.
- Docker and Kubernetes. Container runtimes add their own rules. Check the combined ruleset with
nft list ruleset, not just your file.
Review and drift
Keep the file in version control. Compare nft list ruleset with the file during reviews. If you want the same intent across many hosts, generate the file from one template. Related: how a host firewall differs on a laptop and open to the world SSH review for cloud hosts.
Safeguard offers asset discovery and policy gates, and a free scan at gold.safeguard.sh/scan for your dependencies.
Quick check
What does policy drop do on the input chain?
Any inbound packet that no rule accepts is dropped, so you must explicitly allow replies, loopback and the service ports you need.
How can I test a ruleset without applying it?
Run nft -c -f file, which checks the syntax without loading the rules.
Sources
Last reviewed: 19 October 2026.