Securing Your Homelab with UFW Firewall Rules and Network Segmentation

Securing Your Homelab with UFW Firewall Rules and Network Segmentation

When I first built my homelab, I made the rookie mistake of assuming that being behind a home router made me safe. I opened ports, ran services with default credentials, and left SSH listening on every interface. Within weeks, I discovered someone had brute-forced my Jellyfin box and was streaming my media library. That's when I learned that security isn't something you bolt on after the fact—it's a foundation you build from day one.

In this tutorial, I'll walk you through setting up UFW (Uncomplicated Firewall) with practical rules that actually make sense for a homelab, then layer in network segmentation to keep your critical services isolated from casual browsing and IoT devices. This is the defense-in-depth approach that changed how I operate.

Why UFW? Why Now?

UFW sits on top of Linux's iptables, but without the syntax headaches. On a homelab server running Ubuntu or Debian, UFW is installed by default. I prefer it because it forces you to think about what traffic actually needs to flow—and then denies everything else. That's the fundamental security principle: default deny, explicit allow.

Network segmentation goes further. Instead of trusting all devices on your home network equally, you split them into zones: one for your critical services (NAS, databases), one for day-to-day access (laptops, desktops), and one for untrusted devices (guests' phones, smart home gadgets). This way, if someone compromises your smart fridge, they still can't reach your Vaultwarden vault.

Setting Up UFW: The Fundamentals

First, enable UFW and set the default policy. I always start from a deny-by-default stance:

sudo apt update && sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable

That's the critical foundation. Now your server blocks everything inbound except what you explicitly allow.

Before adding rules, make absolutely sure you can get back in. I learned this the hard way on a remote VPS—locking yourself out is a horrible feeling. Allow SSH from your home IP or, if you're paranoid (you should be), from a specific trusted subnet:

sudo ufw allow 22/tcp comment "SSH from home network"
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp comment "SSH from LAN only"

Verify the rules loaded:

sudo ufw status verbose

You'll see output like:

Status: active

     To                         Action      From
     --                         ------      ----
22/tcp                     ALLOW       Anywhere

Practical Rules for Common Homelab Services

Now let's add rules for the services most homelabbers run. I'll show you my actual rules, which have evolved over two years of running Docker containers, Nextcloud, and media servers.

For Nextcloud (running on port 443 via reverse proxy), I only allow HTTPS from my home network:

sudo ufw allow from 192.168.1.0/24 to any port 443 proto tcp comment "Nextcloud HTTPS from LAN"

For Jellyfin, which I want available from outside my home via Tailscale, I don't open any port—Tailscale tunnels handle it. But if you're exposing it directly:

sudo ufw allow from 192.168.1.0/24 to any port 8096 proto tcp comment "Jellyfin from LAN"

For a self-hosted game server or voice chat (Discord alt), allow the specific port only from trusted networks:

sudo ufw allow from 192.168.1.0/24 to any port 5000 proto tcp comment "Internal service"
sudo ufw allow 5000/tcp comment "Unrestricted access if needed"

DNS (Pi-hole or AdGuard Home) running on port 53 should never be open to the internet. Keep it LAN-only:

sudo ufw allow from 192.168.1.0/24 to any port 53 proto udp comment "DNS from LAN"
sudo ufw allow from 192.168.1.0/24 to any port 53 proto tcp comment "DNS from LAN"
Watch out: Exposing DNS to the internet turns your server into an open resolver, making it a target for DDoS amplification attacks. I've seen homelabs brought to their knees by this mistake. Keep DNS LAN-only, always.

Network Segmentation with VLANs

UFW protects individual servers, but network segmentation protects your entire lab. The idea is simple: physical or virtual separation of networks so devices can't talk to each other without explicit permission.

On a home network, you'll typically create VLANs on a managed switch. Here's a typical segmentation I recommend:

Your router acts as the gateway between VLANs and enforces rules. Most modern routers (UniFi, pfSense, OPNsense) support this natively. I use a cheap UniFi Dream Machine Mini—it's £200 and handles VLAN routing plus threat detection.

On the router firewall, block VLAN 30 (guests/IoT) from reaching VLAN 10 (services) entirely, except for specific ports you explicitly need:

# Pseudo-config for UniFi or pfSense-style rules
# Block VLAN 30 → VLAN 10 by default
rule: deny from 10.1.30.0/24 to 10.1.10.0/24

# Exception: allow VLAN 30 to reach NAS on port 445 (SMB) only if you want file sharing
rule: allow from 10.1.30.0/24 to 10.1.10.5 port 445 proto tcp

The beauty of this is that even if an IoT device is compromised, it can't scan your internal services or reach your database server. An attacker would need to compromise something on VLAN 20 first, and that's unlikely if you're patching and using SSH keys.

Combining UFW and VLAN Segmentation

Now the layers stack. Your core database or NAS server runs UFW with deny-by-default, AND it sits on a segmented VLAN that guests can't even reach. That's defense-in-depth.

On your Nextcloud server (VLAN 10), the UFW rules might look like:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment "SSH from admin only"
sudo ufw allow 443/tcp comment "HTTPS"
sudo ufw allow from 10.1.10.0/24 to any port 5432 proto tcp comment "PostgreSQL from VLAN 10 only"
sudo ufw enable

Even though the router prevents VLAN 20 and 30 from reaching port 5432, having UFW block it too means you're protected if someone misconfigures the router or a VLAN rule.

Tip: Use UFW's `--dry-run` flag to test rules without committing them. I use this to sanity-check complex policies: `sudo ufw --dry-run enable`. This shows what would be applied without actually enabling anything.

Logging and Monitoring

A firewall you don't monitor is a firewall you can't trust. Enable UFW logging so you can spot port scans and brute-force attempts:

sudo ufw logging on
sudo ufw logging medium
tail -f /var/log/ufw.log

Look for patterns like repeated connection attempts on port 22 (SSH brute force) or scans across many ports. If you see suspicious activity, you know to check your SSH keys or investigate what changed on that machine.

For VLAN and router-level logging, configure syslog on your UniFi or pfSense box to send logs to a central location. I run a small Loki stack with Grafana to visualize firewall logs across my entire lab—it's the first thing I check when something breaks.

Testing Your Setup

Don't trust that your rules work until you test them. From a guest VLAN device, try connecting to your NAS:

nmap -p 445,22,3306 10.1.10.5

All ports should show as filtered or closed. From your trusted VLAN, the same scan should show open ports. This confirms the VLAN rules are working.

For UFW specifically, use `ufw status verbose` to list all rules, then manually verify each one:

sudo ufw status numbered

This numbered output lets you delete rules by number if you mess up: `sudo ufw delete 5`.

Real-World Gotchas I've Hit

Docker and UFW don't always play nicely. Docker can bypass UFW rules by writing directly to iptables. If you're running Docker, add this to `/etc/docker/daemon.json`:

{
  "iptables": true,
  "ip-forward": true,
  "ip-masq": true
}

Then restart Docker and UFW. This forces Docker to respect your UFW rules instead of circumventing them.

Forgetting to allow outbound traffic for updates. A "default allow outgoing" is fine for a homelab, but if you ever need outgoing restrictions (zero-trust internal network), remember that your app servers need to reach the internet to pull updates and dependencies. I always carve out explicit allow rules for apt, pip, and Docker registries.

VLAN tagging on the NAS.. If your NAS (Synology, TrueNAS, etc.) is on a VLAN, double-check that the management interface is reachable. Some NAS boxes struggle with VLAN tags. Test the connection before you lock yourself out.

Next Steps

Once you've got UFW and VLAN segmentation in place, the next layer is authentication and encryption. I'd recommend:

Security isn't a destination—it's a habit. Start with UFW and VLAN segmentation, monitor your logs monthly, and iterate. Your homelab will be orders of magnitude safer than the default home network, and you'll sleep better knowing that a compromised IoT device can't reach your data.

If you're running services at scale and want to move to a VPS for better uptime and isolation, I'd recommend looking at RackNerd's KVM VPS offerings—they're reliable, affordable, and give you full control over the network stack. But whether you stay home or move to the cloud, apply these same principles: default deny, explicit allow, and layer your defenses.

Discussion