close

DEV Community

Luna Commsnet
Luna Commsnet

Posted on

Zero-Trust Homelab: Network Segmentation with VLANs and pfSense

Zero-Trust Homelab: Network Segmentation with VLANs and pfSense

Published: June 15, 2026 | CommsNet


If everything on your network can reach everything else, you don't have a network — you have a single point of failure the size of your entire infrastructure. One compromised IoT lightbulb becomes a pivot to your NAS. One breached container becomes a foothold on your management VLAN. In a flat network, trust is binary: you're either in, or you're out.

Zero-trust networking changes the assumption. Nothing is trusted by default. Every segment, every device, every flow must prove it belongs. And the mechanism that enforces this at the homelab scale isn't some expensive SDN controller — it's VLANs on a managed switch, enforced by pfSense firewall rules.

In this article, I'll walk through designing and implementing a zero-trust network segmentation strategy using IEEE 802.1Q VLANs, a managed switch, and pfSense as the inter-VLAN router and policy enforcement point. By the end, your IoT devices won't be able to touch your servers, your guest WiFi will be isolated at L2, and your management interfaces will require explicit allow rules.


Why Zero-Trust for a Homelab?

The Flat Network Problem

Most homelabs start as flat networks — one /24, everything plugged into one switch, maybe a consumer router doing NAT. It works until it doesn't:

Attack Vector Flat Network Impact Segmented Network Impact
Compromised IoT device Lateral movement to NAS, servers Contained to IoT VLAN, blocked at firewall
Malware on guest laptop Access to all L2 hosts Isolated to guest VLAN, no cross-VLAN routing
Exposed service exploit Direct path to management interfaces Must traverse firewall rules between VLANs
DNS poisoning on one host Affects entire broadcast domain Limited to single VLAN scope

Zero-Trust Principles (Adapted for Homelab)

Enterprise zero-trust frameworks (NIST SP 800-207, Forrester ZTX) assume things homelabbers don't have — identity providers, microsegmentation platforms, continuous verification. But the core principles translate:

  1. Never trust, always verify — Every inter-VLAN flow is denied by default, explicitly allowed
  2. Least privilege access — VLANs get only the routing rules they need
  3. Assume breach — Design so that compromising one VLAN doesn't compromise others
  4. Verify explicitly — pfSense rules are the policy; logging proves enforcement

Network Design

VLAN Architecture

Here's the segmentation model I use. It's designed around the principle of isolation by trust level:

┌─────────────────────────────────────────────────────────┐
│                    VLAN Architecture                      │
│                                                          │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌─────────┐ │
│  │  VLAN 10  │  │  VLAN 20  │  │  VLAN 30  │  │ VLAN 40 │ │
│  │Management│  │  Servers  │  │   IoT     │  │  Guest  │ │
│  │10.0.10/24│  │10.0.20/24│  │10.0.30/24│  │10.0.40 │ │
│  │ TRUST: H │  │ TRUST: H │  │ TRUST: L │  │TRUST: N│ │
│  └─────┬────┘  └─────┬────┘  └─────┬────┘  └────┬────┘ │
│        │              │              │            │       │
│        └──────────────┴──────┬───────┴────────────┘       │
│                              │                            │
│                     ┌────────┴────────┐                   │
│                     │    pfSense      │                   │
│                     │  Inter-VLAN     │                   │
│                     │  Router + FW    │                   │
│                     └────────────────┘                   │
└─────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

VLAN Definitions

VLAN ID Name Subnet Trust Level Purpose
10 Management 10.0.10.0/24 High pfSense, Proxmox, switches, IPMI/iDRAC
20 Servers 10.0.20.0/24 High NAS, Docker hosts, application servers
30 IoT 10.0.30.0/24 Low Smart devices, sensors, cameras
40 Guest 10.0.40.0/24 None Guest WiFi, untrusted devices
50 Services 10.0.50.0/24 Medium Exposed services, reverse proxy, tunnel endpoints

Trust Model and Flow Rules

The firewall policy is the heart of zero-trust. Every rule is explicit:

Source VLAN → Destination VLAN → Allowed? → Reason
─────────────────────────────────────────────────────
Management → Any              → ALLOW     → Admin access
Servers    → Management       → DENY      → No reverse access to mgmt
Servers    → Servers          → ALLOW     → Internal service communication
Servers    → IoT              → DENY      → No need to reach IoT
Servers    → Services         → ALLOW     → Publish services
IoT       → Servers           → LIMITED   → Only specific ports (DNS, NTP, specific API)
IoT       → Management       → DENY      → No access to mgmt interfaces
IoT       → Internet         → ALLOW     → Firmware updates, cloud APIs
IoT       → Guest            → DENY      → Mutual isolation
Guest     → Any (internal)   → DENY      → Complete isolation
Guest     → Internet          → ALLOW     → Internet-only access
Services  → Servers           → ALLOW     → Reverse proxy to backends
Services  → Management       → DENY      — No access to mgmt
Enter fullscreen mode Exit fullscreen mode

Hardware Requirements

You don't need enterprise gear. Here's what works at the homelab scale:

Managed Switch (Required)

You need a switch that supports 802.1Q VLAN tagging. Options by budget:

Switch Ports VLAN Support Price (Used) Notes
Cisco Catalyst 2960 24/48 Full 802.1Q $30-80 Bulletproof, CLI only
HPE ProCurve 2530 24 Full 802.1Q $40-100 Web UI + CLI
TP-Link SG108E 8 Basic 802.1Q $25 Budget starter, limited CLI
Ubiquiti USW-24 24 Full + UI $100-200 UniFi ecosystem
MikroTik CRS326 24 Full + RouterOS $80 Powerful but steep learning curve

My pick: Cisco Catalyst 2960G — cheap on eBay, never dies, full VLAN feature set. The CLI is an investment that pays off.

pfSense Hardware

pfSense runs the inter-VLAN routing and firewall. Options:

Option Cost Performance Notes
Netgate SG-1100 $179 ~1 Gbps routing Purpose-built, low power
Protectli Vault $300+ ~2 Gbps routing Intel NICs, fanless
Repurposed PC + 4 NICs $50-100 3+ Gbps routing Best performance/$, more power draw
Proxmox VM + virtio NICs $0 ~10 Gbps routing Already have Proxmox? Use it

My pick: pfSense as a Proxmox VM with 4 virtio NICs. You already have the hardware.


Implementation: Step by Step

Step 1: Configure VLANs on pfSense

Navigate to Interfaces → Assignments → VLANs and create each VLAN:

Parent Interface: vmx0 (LAN)
VLAN Tag: 10  Priority: 0  Description: Management
VLAN Tag: 20  Priority: 0  Description: Servers  
VLAN Tag: 30  Priority: 0  Description: IoT
VLAN Tag: 40  Priority: 0  Description: Guest
VLAN Tag: 50  Priority: 0  Description: Services
Enter fullscreen mode Exit fullscreen mode

Then assign each VLAN as a new interface:

Interfaces → Assignments:

  • vmx0.10 → OPT1 → rename to MGMT
  • vmx0.20 → OPT2 → rename to SERVERS
  • vmx0.30 → OPT3 → rename to IOT
  • vmx0.40 → OPT4 → rename to GUEST
  • vmx0.50 → OPT5 → rename to SERVICES

Enable each interface and set its IPv4 Static address:

MGMT:     10.0.10.1/24
SERVERS:  10.0.20.1/24
IOT:      10.0.30.1/24
GUEST:    10.0.40.1/24
SERVICES: 10.0.50.1/24
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure DHCP for Each VLAN

Services → DHCP Server — enable on each VLAN interface:

Interface Range DNS Gateway Lease Time
MGMT 10.0.10.100-10.0.10.200 10.0.10.1 10.0.10.1 86400
SERVERS 10.0.20.100-10.0.20.200 10.0.20.1 10.0.20.1 86400
IOT 10.0.30.50-10.0.30.200 1.1.1.1, 9.9.9.9 10.0.30.1 3600
GUEST 10.0.40.50-10.0.40.200 1.1.1.1 10.0.40.1 3600
SERVICES Static only 10.0.50.1 10.0.50.1 N/A

Key decisions:

  • IoT/Guest DNS: Point to public resolvers (1.1.1.1), NOT your internal DNS. These VLANs don't need to resolve internal names.
  • Services: No DHCP — all services get static IPs. If someone plugs into this VLAN, they get nothing.
  • Short lease times on IoT/Guest: Limits how long a rogue device keeps an address.

Step 3: Configure the Managed Switch

This is where VLAN theory meets physical reality. Each switch port must be configured as access (untagged, single VLAN) or trunk (tagged, multiple VLANs).

Port assignments:

Port 1-8:   Access, VLAN 20 (Servers)      — NAS, Proxmox hosts, Docker servers
Port 9-12:  Access, VLAN 30 (IoT)          — Smart devices, cameras
Port 13-16: Access, VLAN 40 (Guest)        — Guest WiFi AP
Port 17-20: Access, VLAN 10 (Management)   — Management workstations
Port 21-24: Trunk, VLAN ALL (tagged)        — pfSense, Proxmox, WiFi AP
Enter fullscreen mode Exit fullscreen mode

Cisco 2960 example config:

! Trunk port to pfSense
interface GigabitEthernet0/21
  switchport mode trunk
  switchport trunk allowed vlan 10,20,30,40,50
  switchport trunk native vlan 99  ! Never use VLAN 1 as native
  spanning-tree portfast trunk

! Access port for server
interface range GigabitEthernet0/1 - 8
  switchport mode access
  switchport access vlan 20
  spanning-tree portfast

! Access port for IoT
interface range GigabitEthernet0/9 - 12
  switchport mode access
  switchport access vlan 30
  spanning-tree portfast

! Access port for management workstation
interface range GigabitEthernet0/17 - 20
  switchport mode access
  switchport access vlan 10
  spanning-tree portfast
Enter fullscreen mode Exit fullscreen mode

Critical: Set native vlan 99 (or any unused VLAN) on trunk ports. Never use VLAN 1 as the native VLAN — it's the default attack surface on every Cisco switch.

Step 4: Firewall Rules — The Zero-Trust Core

This is where zero-trust is actually enforced. Navigate to Firewall → Rules for each interface.

Management VLAN (Highest Trust)

# MGMT Interface Rules (evaluated top-to-bottom)
#
# 1. Allow MGMT to anything (admin access)
IPv4 *  MGMT net  *  *  *  →  ALLOW  — "MGMT: Allow all outbound"
#
# 2. Allow pfSense DNS from MGMT
IPv4 TCP/UDP  MGMT net  *  MGMT address  53  →  ALLOW  — "MGMT: DNS to pfSense"
#
# 3. Block everything else (implicit, but be explicit)
IPv4 *  *  *  MGMT net  *  →  DENY  — "MGMT: Block all inbound"
Enter fullscreen mode Exit fullscreen mode

Management is simple — full outbound access, no inbound from other VLANs. Admins initiate connections to infrastructure; infrastructure never reaches back.

Servers VLAN

# SERVERS Interface Rules
#
# 1. Allow Servers → Servers (internal communication)
IPv4 *  SERVERS net  *  SERVERS net  *  →  ALLOW  — "SERVERS: Inter-server communication"
#
# 2. Allow Servers → Internet (updates, API calls)
IPv4 *  SERVERS net  *  !RFC1918  *  →  ALLOW  — "SERVERS: Internet access"
#
# 3. Allow Services → Servers (reverse proxy backends)
IPv4 TCP  SERVICES net  *  SERVERS net  80,443,8080  →  ALLOW  — "SERVICES: Reverse proxy to backends"
#
# 4. Block everything else
IPv4 *  *  *  SERVERS net  *  →  DENY  — "SERVERS: Block all other inbound"
Enter fullscreen mode Exit fullscreen mode

Key rule: SERVERS → !RFC1918 allows internet access but blocks access to any other internal VLAN. Servers can reach the internet for updates but cannot reach IoT, Guest, or Management.

IoT VLAN (Low Trust)

# IOT Interface Rules — MOST RESTRICTIVE
#
# 1. Allow IoT → pfSense DNS
IPv4 TCP/UDP  IOT net  *  IOT address  53  →  ALLOW  — "IOT: DNS to pfSense"
#
# 2. Allow IoT → pfSense NTP
IPv4 UDP  IOT net  *  IOT address  123  →  ALLOW  — "IOT: NTP to pfSense"
#
# 3. Allow specific IoT → Server API (e.g., Home Assistant)
IPv4 TCP  IOT net  *  10.0.20.50  8123  →  ALLOW  — "IOT: Home Assistant API"
#
# 4. Allow IoT → Internet (firmware, cloud APIs)
IPv4 *  IOT net  *  !RFC1918  *  →  ALLOW  — "IOT: Internet access"
#
# 5. Block everything else
IPv4 *  *  *  IOT net  *  →  DENY  — "IOT: Block all other inbound"
Enter fullscreen mode Exit fullscreen mode

The IoT rules are surgical — only DNS, NTP, one specific API endpoint, and internet. This is the most important VLAN to lock down because IoT devices are the most likely to be compromised.

Pro tip: Use aliases in pfSense for the IoT API rules. Create an alias IoT_Allowed_Services with the specific server IPs and ports IoT devices need. This makes it easy to add new devices without creating new rules.

Guest VLAN (No Trust)

# GUEST Interface Rules — TOTAL ISOLATION
#
# 1. Allow Guest → Internet only
IPv4 *  GUEST net  *  !RFC1918  *  →  ALLOW  — "GUEST: Internet only"
#
# 2. Allow Guest → pfSense DNS (DHCP-assigned)
IPv4 TCP/UDP  GUEST net  *  GUEST address  53  →  ALLOW  — "GUEST: DNS"
#
# 3. Block everything else
IPv4 *  *  *  GUEST net  *  →  DENY  — "GUEST: Complete isolation"
Enter fullscreen mode Exit fullscreen mode

Guests get internet. Nothing else. This is the simplest and most important rule set.

Services VLAN (Exposed Services)

# SERVICES Interface Rules
#
# 1. Allow Services → Servers (reverse proxy backends)
IPv4 TCP  SERVICES net  *  SERVERS net  80,443,8080,8123  →  ALLOW  — "SERVICES: Proxy to backends"
#
# 2. Allow Services → Internet (cert renewal, API calls)
IPv4 *  SERVICES net  *  !RFC1918  *  →  ALLOW  — "SERVICES: Internet access"
#
# 3. Block everything else
IPv4 *  *  *  SERVICES net  *  →  DENY  — "SERVICES: Block all other inbound"
Enter fullscreen mode Exit fullscreen mode

Services VLAN is the DMZ equivalent. It can reach backends on specific ports and the internet for Let's Encrypt/certbot renewals. It cannot reach management, IoT, or guest.


Advanced: pfSense Aliases for Zero-Trust Maintenance

One of the most underused features in pfSense is aliases — named groups of networks, hosts, or ports that make firewall rules readable and maintainable.

Firewall → Aliases:

Name: MGMT_Net        Type: Host(s)    Value: 10.0.10.0/24
Name: SERVERS_Net     Type: Host(s)    Value: 10.0.20.0/24
Name: IOT_Net         Type: Host(s)    Value: 10.0.30.0/24
Name: GUEST_Net       Type: Host(s)    Value: 10.0.40.0/24
Name: SERVICES_Net    Type: Host(s)    Value: 10.0.50.0/24
Name: RFC1918         Type: Network   Value: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
Name: IoT_API_Targets Type: Host(s)    Value: 10.0.20.50  (Home Assistant)
Name: Web_Ports       Type: Port(s)    Value: 80, 443, 8080
Name: IoT_Allowed     Type: Port(s)    Value: 8123, 1883, 5353
Enter fullscreen mode Exit fullscreen mode

Now your rules use human-readable names:

DENY  IOT_Net    →  RFC1918       —  *        —  "IOT: Block internal access"
ALLOW IOT_Net    →  IoT_API_Targets → IoT_Allowed —  "IOT: Allowed services only"
Enter fullscreen mode Exit fullscreen mode

When you add a new IoT device that needs to reach a different service, you update the alias — not the rule. This prevents rule sprawl, which is the #1 way zero-trust degrades over time.


Verification: Proving Your Segmentation Works

Setting up rules isn't enough. You need to verify they work. Here's how:

Test 1: IoT Cannot Reach Management

From an IoT device (or a laptop plugged into an IoT port):

# Should FAIL — blocked by firewall
nmap -p 22 10.0.10.1    # pfSense SSH
nmap -p 443 10.0.10.1   # pfSense WebUI
nmap -p 8006 10.0.10.5  # Proxmox WebUI

# Should SUCCEED — allowed
ping 1.1.1.1            # Internet
dig @10.0.30.1 example.com  # DNS
Enter fullscreen mode Exit fullscreen mode

Test 2: Guest Cannot Reach Any Internal Host

From a guest device:

# All should FAIL
ping 10.0.10.1    # Management
ping 10.0.20.1    # Servers
ping 10.0.30.1    # IoT
nmap 10.0.20.0/24 # Scan entire server VLAN

# Should SUCCEED
ping 1.1.1.1      # Internet
Enter fullscreen mode Exit fullscreen mode

Test 3: Servers Cannot Reach Management

From a server:

# Should FAIL
ssh admin@10.0.10.1     # pfSense
curl https://10.0.10.5:8006  # Proxmox

# Should SUCCEED
ping 10.0.20.1          # Servers gateway
curl https://example.com # Internet
Enter fullscreen mode Exit fullscreen mode

Test 4: pfSense Firewall Logs

Status → System Logs → Firewall:

Watch for denied packets between VLANs. If you see unexpected allowed traffic, your rules are wrong. If you see denied traffic that should be allowed, check your alias definitions.

Pro tip: Enable Log packets that are handled by this rule on every DENY rule. This gives you a complete audit trail of every attempted cross-VLAN connection.


WiFi Considerations

If you're running WiFi (and you should for IoT/mobile), the AP must support multiple SSIDs mapped to VLANs.

UniFi AP VLAN Configuration

SSID: "CommsNet-Home"     → VLAN 20 (Servers/Trusted devices)
SSID: "CommsNet-IoT"      → VLAN 30 (IoT only)
SSID: "CommsNet-Guest"    → VLAN 40 (Guest, rate-limited)
Enter fullscreen mode Exit fullscreen mode

Each SSID gets its own DHCP scope from pfSense, its own firewall rules, and complete L2 isolation. The AP tags frames with the appropriate VLAN ID; pfSense routes and enforces policy.

WiFi-Specific Firewall Additions

# Rate limit Guest WiFi
IPv4 *  GUEST net  *  *  *  →  ALLOW  —  "GUEST: Rate limited"
  ↑ Limit: 10 Mbps down, 5 Mbps up per client
  ↑ Connection limit: 100 concurrent per /32
Enter fullscreen mode Exit fullscreen mode

pfSense traffic shaping (limiter queues) can enforce per-client bandwidth caps on guest and IoT VLANs. This prevents one guest device from consuming your entire upstream.


Monitoring and Alerting

Zero-trust without monitoring is just wishful thinking. You need to know when segmentation fails.

pfSense Integration with Zabbix/Grafana

Install the pfSense Zabbix Agent package:

Package Manager → Available Packages → pfSense-zabbix-agent
Enter fullscreen mode Exit fullscreen mode

Monitor these key metrics:

Metric What It Tells You Alert Threshold
Firewall deny rate How many cross-VLAN attempts blocked Sudden spike = scanning/recon
Interface traffic per VLAN Normal traffic baseline IoT VLAN talking to server VLAN = breach
DHCP lease count per VLAN Device count per segment New device on Management VLAN = investigate
State table utilization Active connections >80% = possible flood or compromised host
pfSense CPU/memory Router health >80% sustained = capacity issue

Suricata IDS on pfSense

Enable Suricata on each VLAN interface for deep packet inspection:

Services → Suricata → Interfaces → Add
  Interface: VLAN_30 (IoT)
  Mode: IPS (Inline Prevention)
  Block offenders: Yes
  Alert only on new threats: Yes
Enter fullscreen mode Exit fullscreen mode

Suricata on the IoT VLAN catches:

  • IoT devices phoning home to unexpected IPs
  • Malware C2 beacon patterns
  • Known exploit signatures targeting IoT firmware

Common Mistakes and Fixes

Mistake 1: Forgetting to Disable VLAN 1

VLAN 1 is the default on every switch. Every port is in it. If you don't explicitly disable it, you have a shadow flat network running alongside your segmented one.

Fix: Create a VLAN 99 as the native VLAN on all trunk ports and move all unused ports to a dead VLAN.

! Move all unused ports to dead VLAN
interface range GigabitEthernet0/22 - 24
  switchport mode access
  switchport access vlan 99
  shutdown
Enter fullscreen mode Exit fullscreen mode

Mistake 2: Over-Allowing on Trunk Ports

switchport trunk allowed vlan all is lazy and dangerous. Only allow the VLANs that need to traverse each trunk.

Fix:

interface GigabitEthernet0/21
  switchport trunk allowed vlan 10,20,30,40,50
  ! NOT: switchport trunk allowed vlan all
Enter fullscreen mode Exit fullscreen mode

Mistake 3: pfSense Floating Rules Bypassing Interface Rules

Floating rules in pfSense apply globally and can bypass per-interface rules. If you use floating rules, make sure they don't accidentally allow cross-VLAN traffic.

Fix: Avoid floating rules for inter-VLAN policies. Use interface-specific rules. Use floating rules only for traffic shaping or QoS.

Mistake 4: No Logging on Deny Rules

If you don't log denied packets, you have no way to detect reconnaissance, failed intrusion attempts, or misconfigured devices.

Fix: Enable logging on every DENY rule. Set up a syslog server to aggregate and analyze firewall logs.


Cost Summary

Item Cost Notes
Cisco 2960G (used) $50 eBay, 24-port managed
pfSense (VM on Proxmox) $0 Already have hardware
Cat6 patch cables $15 Monoprice 10-pack
UniFi AP AC Lite (used) $40 Multi-SSID VLAN support
Total $105 One-time cost

No subscriptions. No per-device licensing. No cloud dependencies. This is infrastructure you own, understand, and control.


What's Next?

This article covers L2/L3 segmentation. In the next article in this series, we'll add:

  • WireGuard VPN for remote management VLAN access (never expose pfSense to the internet)
  • Cilium eBPF policies for micro-segmentation within the server VLAN (container-to-container)
  • pfSense CARP for high-availability firewall failover
  • Automated compliance checks — scripts that verify your firewall rules match your zero-trust policy

Key Takeaways

  1. Flat networks are the enemy — one compromised device becomes a pivot to everything
  2. VLANs + pfSense rules = zero-trust at homelab scale — no enterprise license required
  3. Deny by default, allow by exception — every inter-VLAN flow must be justified
  4. IoT is your biggest risk — isolate it to DNS + NTP + one API endpoint
  5. Guest gets internet only — no exceptions, no "just this once"
  6. Log every deny — visibility is how you prove zero-trust works
  7. Aliases keep rules maintainable — rule sprawl is how zero-trust dies
  8. Test your segmentation — if you haven't verified it, it's probably broken

CommsNet — Building infrastructure that respects your privacy and your intelligence.

Follow on Medium and Dev.to for more homelab, networking, and self-hosting content.

Top comments (0)