Securing your homelab with UFW (the right way)
Running services at home without a firewall is like leaving your front door wide open and hoping nobody walks in. UFW (Uncomplicated Firewall) is the easiest way to fix that on Debian-based systems, and it’s a lot more capable than most people think once you go past the basics.
Let’s actually do this right.
Install and set defaults
Most Debian-based systems already have it:
sudo apt install ufw
Before enabling anything, set your default policies. This is the most important step and most people skip it:
sudo ufw default deny incoming
sudo ufw default allow outgoing
Drop everything incoming by default, allow everything outgoing. Clean and sane.
Allow SSH first, or you’ll lock yourself out
Do this before enabling UFW. Seriously. If you’re on default port 22:
sudo ufw allow ssh
If you already moved SSH to a different port (good):
sudo ufw allow 2222/tcp
Now you can safely enable:
sudo ufw enable
Only open what you’re actually running
The point of a firewall is whitelisting, not blacklisting. Don’t just open ports and forget about them.
Some examples:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8096/tcp
Port 8096 is Jellyfin. 3000 is Grafana. You get the idea. Open what you need, nothing more.
Lock internal services to your LAN
This is where most homelab setups fall apart. Why expose Grafana or Jellyfin to the entire internet? If it’s for you and your LAN, restrict it:
sudo ufw allow from 192.168.1.0/24 to any port 8096
sudo ufw allow from 192.168.1.0/24 to any port 3000
sudo ufw allow from 192.168.1.0/24 to any port 9000
Replace 192.168.1.0/24 with your actual subnet. Now those services are completely invisible to the outside world.
You can do the same for SSH if you only ever access it locally:
sudo ufw allow from 192.168.1.0/24 to any port 22
Rate limiting SSH
Brute force attacks are boring and they never stop. UFW has a built-in limiter that blocks IPs after 6 failed connection attempts in 30 seconds:
sudo ufw limit ssh
One command. Done. On a custom port:
sudo ufw limit 2222/tcp
Blocking specific IPs and subnets
Got something hammering your server?
sudo ufw deny from 1.2.3.4
Block a whole subnet:
sudo ufw deny from 1.2.3.0/24
These get processed before allow rules so they work as expected.
Turn on logging
You want to know what’s hitting your firewall:
sudo ufw logging on
For more detail:
sudo ufw logging medium
Levels go low, medium, high, full. Medium is enough for most people. Logs end up in /var/log/ufw.log.
Watch it live:
sudo tail -f /var/log/ufw.log
Application profiles
UFW ships with application profiles for common services. Check what’s available:
sudo ufw app list
Use a profile directly instead of specifying ports manually:
sudo ufw allow "Nginx Full"
sudo ufw allow "OpenSSH"
These are just convenience wrappers but they’re nice to have.
Commands you’ll use regularly
See what’s open:
sudo ufw status verbose
Numbered list for easier rule management:
sudo ufw status numbered
Delete a rule by number:
sudo ufw delete 3
Delete by rule definition:
sudo ufw delete allow 8096/tcp
Reload after config changes:
sudo ufw reload
Nuke everything and start fresh (careful with this one):
sudo ufw reset
A complete sane homelab config
Here’s roughly what a clean setup looks like for a homelab running a reverse proxy and a few internal services:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit 2222/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 192.168.1.0/24 to any port 8096
sudo ufw allow from 192.168.1.0/24 to any port 3000
sudo ufw allow from 192.168.1.0/24 to any port 9000
sudo ufw logging medium
sudo ufw enable
Nothing exposed that doesn’t need to be. That’s the whole point.
UFW is not the whole picture
A firewall is your baseline, not your entire security posture. You also want:
- SSH password auth disabled, keys only (
PasswordAuthentication noinsshd_config) - Unattended upgrades or at least regular manual updates
- Fail2ban if you want extra brute force protection on top of rate limiting
- A VPN like WireGuard if you want proper remote access instead of punching ports open
Get the firewall right first, then layer the rest on top.
Stay safe out there.