UFW Firewall Baseline (Ubuntu / Debian)
Set up a secure default UFW ruleset: deny all inbound, allow SSH and common homelab services. Safe to run on a fresh VPS or LXC container.
bash# Install UFW if not present
sudo apt-get install -y ufw
# Set defaults: deny all inbound, allow all outbound
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH before enabling (prevents lockout)
sudo ufw allow ssh
# Enable the firewall
sudo ufw --force enable
# Verify rules
sudo ufw status verbose
What this does
Installs and configures UFW (Uncomplicated Firewall) with a secure default posture:
- Deny all inbound traffic by default
- Allow all outbound traffic
- Allow SSH (port 22) so you don’t lock yourself out
Why this approach
A fresh Linux server has no inbound firewall rules — every port that has a listening service is reachable from anywhere on the network (or, if the server is internet-exposed, from anywhere in the world). That’s fine during initial setup and harmless for most homelab services on a trusted LAN, but as you add services that bind to unexpected ports, the default-open posture means any new service is immediately reachable before you’ve considered whether it should be.
UFW (Uncomplicated Firewall) makes a default-deny inbound posture easy to manage. The rule model is simple: deny everything inbound, then allow only what you explicitly need. Each new service gets one ufw allow line. This is far easier to audit than a list of what’s blocked — “allow these specific ports” reads immediately, while “block everything except what I can’t remember” does not.
The critical detail when enabling UFW over SSH is the order of operations: allow SSH before enabling the firewall, not after. Enabling first and adding rules after would immediately drop your connection, requiring console or OOB access to recover. This playbook handles that by placing the SSH allow before the enable, and uses --force to skip the interactive confirmation that would otherwise pause an automated script. If you’ve moved SSH to a non-default port, update the allow rule to match before running.
Prerequisites
- Ubuntu 20.04+ or Debian 11+
- Root or sudo access
- An active SSH session (or console access as a fallback)
Adding rules for common homelab services
Run these after the baseline to open only what you need:
# Web servers
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
# Proxmox web UI
sudo ufw allow 8006/tcp
# Grafana
sudo ufw allow 3000/tcp
# Allow from a specific IP only (more secure)
sudo ufw allow from 192.168.1.0/24 to any port 8006
# Tailscale interface (if routing through Tailscale)
sudo ufw allow in on tailscale0
Restrict SSH to a specific IP or subnet
# Remove the broad SSH rule and replace with a scoped one
sudo ufw delete allow ssh
sudo ufw allow from 192.168.1.100 to any port 22
Useful commands
sudo ufw status numbered # list rules with indexes
sudo ufw delete 3 # delete rule by number
sudo ufw reload # reload without disrupting connections
sudo ufw disable # disable the firewall entirely
Notes
--force enableskips the interactive confirmation prompt — safe in scripts since SSH is already allowed above- UFW is a frontend for iptables; rules persist across reboots automatically
- If you change the SSH port, update the allow rule:
sudo ufw allow 2222/tcp - For IPv6 support, verify
IPV6=yesis set in/etc/default/ufw