Firewall

The hardener configures UFW with default-deny inbound and allows only what you need.

Default rules

TrafficWhen
SSH on public SSH_PORTKEEP_PUBLIC_SSH=true, or Tailscale not joined yet
SSH on tailscale0USE_TAILSCALE=true
SSH from CIDRsKEEP_PUBLIC_SSH=false without Tailscale — uses ALLOW_SSH_FROM
TCP 80 / 443ALLOW_HTTP=true / ALLOW_HTTPS=true (defaults)
OutboundAllowed
Established / relatedAllowed by UFW defaults

Tailscale-only SSH

sudo USE_TAILSCALE=true KEEP_PUBLIC_SSH=false TAILSCALE_AUTHKEY=tskey-auth-xxx bash hardener.sh

Public SSH is removed only after tailscale ip -4 succeeds.

CIDR-restricted SSH (no Tailscale)

sudo KEEP_PUBLIC_SSH=false ALLOW_SSH_FROM=203.0.113.10/32,198.51.100.0/24 bash hardener.sh

Inspect rules

sudo ufw status verbose

Recovery

From provider console:

sudo ufw disable
# or remove a rule:
sudo ufw status numbered
sudo ufw delete <number>

See troubleshooting.md.