A host firewall enforces default-deny: nothing gets in unless you explicitly allow it. ufw is the friendly front end; nftables is the modern engine underneath.
ufw (the easy way)
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp # SSH (or restrict to your IP, below)
sudo ufw allow 80,443/tcp # web
sudo ufw enable
sudo ufw status verbose
Restrict a port to a source:
sudo ufw allow from 100.64.0.0/10 to any port 22 # tailnet only
nftables (direct)
sudo nft list ruleset # view current rules
# /etc/nftables.conf — default-deny input, allow loopback + established + ssh
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
tcp dport { 22, 80, 443 } accept
}
}
| Goal | Rule |
|---|---|
| Block all inbound | default deny incoming |
| Allow tailnet only | allow from 100.64.0.0/10 |
| Rate-limit SSH | ufw limit 22/tcp |
On this fleet: combine with Cloudflare/Tailscale so origin ports aren't internet-exposed at all. Pairs with Linux Server Hardening Baseline.