A default-deny firewall (nftables)
A host firewall you can actually read.
A hardened host runs a firewall that denies everything by default and allows only the specific traffic it needs. On modern Linux that firewall is nftables (the successor to iptables), and its great virtue is a readable, single-file ruleset you can review at a glance. The model is simple: set the input policy to drop, then explicitly accept established connections, loopback, and the handful of ports your services actually use — everything else is silently dropped.
table inet filter {chain input {type filter hook input priority 0; policy drop; # default-denyct state established,related accept # replies to our own connectionsiif "lo" accept # loopbackct state invalid droptcp dport 22 accept # SSH (ideally: from the bastion only)tcp dport { 80, 443 } accept # the web serviceip protocol icmp accept # basic ping}chain forward { type filter hook forward priority 0; policy drop; }chain output { type filter hook output priority 0; policy accept; }}
Why default-deny changes everything
The power is in the policy drop. With a default-deny input chain, a service you forgot about, a debug port someone left open, or a backdoor an attacker tries to bind are all unreachable from the network unless you deliberately opened them. You go from "everything is exposed unless blocked" to "nothing is exposed unless allowed" — which means new mistakes fail closed. The firewall becomes the backstop for the "minimize services" discipline in the next lesson.
Scope the rules tightly
A good ruleset does not just open a port, it opens it to the right sources. SSH should accept only from your bastion or management network, not the whole internet; an internal API port should accept only from the app tier. nftables lets you match source addresses, so "port 22 from anywhere" becomes "port 22 from 10.0.0.0/24," shrinking exposure even for the ports you must keep open. Combine that with binding services to specific interfaces and you control both who can reach a port and whether it is even listening broadly.
$ sudo nft -c -f /etc/nftables.conf # -c checks the ruleset without applying it$ sudo systemctl enable --now nftables # load at boot$ sudo nft list ruleset # the whole live firewall, readable in one screen