Network Segmentation with VLANs: Isolating Traffic on Your Homelab and Beyond
A flat network — where every device can talk to every other device — is fine when you have three things plugged in. Once you add smart TVs, IoT sensors, work laptops, servers, a NAS, and guest devices, a flat network becomes a liability. If any device is compromised, an attacker has unrestricted access to everything else. VLANs are the solution: a way to logically divide one physical network into multiple isolated segments without buying extra switches.
This guide covers VLANs from first principles through practical configuration on managed switches, pfSense/OPNsense, and Linux.
What a VLAN Is (and What It Isn’t)
A VLAN (Virtual Local Area Network) is a layer-2 broadcast domain that’s logically separated from other VLANs. Devices in VLAN 10 can’t talk to devices in VLAN 20 unless traffic passes through a layer-3 device (a router or firewall) that explicitly permits it.
The mechanism is simple: Ethernet frames are tagged with a 4-byte 802.1Q header that includes a 12-bit VLAN ID (1–4094). Switches read these tags and either:
- Forward the frame to ports that belong to the same VLAN
- Drop the frame if the destination port doesn’t belong to that VLAN
Normal Ethernet Frame:
┌──────────┬──────────┬────────┬─────────┐
│ Dst MAC │ Src MAC │ EtherType │ Payload │
└──────────┴──────────┴────────┴─────────┘
802.1Q Tagged Frame:
┌──────────┬──────────┬──────────┬────────┬─────────┐
│ Dst MAC │ Src MAC │ 802.1Q │ EtherType │ Payload │
│ │ │ Tag (4B) │ │ │
└──────────┴──────────┴──────────┴────────┴─────────┘
│
┌────┴────┐
│ VLAN ID │ (12 bits = VIDs 1–4094)
│ PCP │ (3 bits = priority)
│ DEI │ (1 bit = drop eligible)
└─────────┘
VLANs vs Physical Separation
VLANs are not as secure as physical separation. A misconfigured switch, a VLAN hopping attack (double-tagging), or a vulnerability in the switch firmware can theoretically bridge VLANs. For the most sensitive isolation (payment systems, industrial control networks) use physical separation. For homelab, SMB, and typical enterprise security, VLANs provide excellent segmentation when properly configured.
Port Types: Access vs Trunk
Understanding these two port modes is fundamental.
Access Port
An access port belongs to exactly one VLAN. Frames entering an access port are untagged (the device plugged in doesn’t know about VLANs). The switch assigns the configured VLAN ID internally, and strips the tag before forwarding to the destination access port.
PC ──────── [Access Port, VLAN 10] ──── Switch ──── [Access Port, VLAN 10] ──── Server
(untagged traffic) (untagged traffic)
Use access ports for: end devices — computers, servers, phones, printers, IoT devices, APs (when each AP serves only one SSID/VLAN).
Trunk Port
A trunk port carries traffic from multiple VLANs simultaneously, distinguished by 802.1Q tags. The devices connected to trunk ports must understand VLAN tags.
Switch A ──── [Trunk Port] ──── Switch B
(tagged: VLAN 10, 20, 30)
Use trunk ports for: uplinks between switches, connections to routers/firewalls, connections to hypervisors (ESXi, Proxmox), connections to APs serving multiple SSIDs, connections to servers hosting multiple VMs.
Native VLAN
On a trunk port, one VLAN is designated the “native VLAN” (default is VLAN 1). Traffic on the native VLAN is sent untagged on the trunk. This is a common misconfiguration source — if your native VLAN is VLAN 1 and you haven’t disabled it, untagged traffic leaks into it.
Best practice: Set the native VLAN to an unused VLAN ID (e.g., VLAN 999) and put nothing on it. Tag everything explicitly.
Planning Your VLAN Layout
Before touching a switch, map out what you need. A typical homelab segmentation:
| VLAN ID | Name | Subnet | Purpose |
|---|---|---|---|
| 10 | TRUSTED | 192.168.10.0/24 | Trusted devices: personal PCs, laptops |
| 20 | SERVERS | 192.168.20.0/24 | Home servers, NAS, media server |
| 30 | IOT | 192.168.30.0/24 | Smart TVs, bulbs, thermostats, cameras |
| 40 | GUEST | 192.168.40.0/24 | Guest Wi-Fi — internet only |
| 50 | MANAGEMENT | 192.168.50.0/24 | Switch management, AP management |
| 60 | DMZ | 192.168.60.0/24 | Internet-facing services |
| 99 | NATIVE | (unused) | Trunk native VLAN — no hosts |
Traffic Rules Between VLANs
Draw out the allowed flows before configuring your firewall:
TRUSTED → SERVERS ✓ (access NAS, Plex, etc.)
TRUSTED → IOT ✗ (block — one-way only needed)
IOT → TRUSTED ✗ (block — IoT shouldn't initiate to trusted)
SERVERS → IOT ✓ (Home Assistant, monitoring)
GUEST → * ✗ (internet only, no LAN)
DMZ → SERVERS ✗ (DMZ can't reach internal servers)
SERVERS → DMZ ✓ (pull configs, push deployments)
* → MANAGEMENT limited (admin stations only)
Planning this before touching hardware saves enormous reconfiguration time.
Managed Switch Configuration
You need a managed switch to use VLANs. Unmanaged switches forward all traffic to all ports — they have no concept of VLANs. Budget managed switches start around $30-50 (TP-Link TL-SG108E, Netgear GS308E); enterprise options (Cisco, HP/Aruba, Juniper) offer more features and reliability.
TP-Link Easy Smart / TL-SG108E
One of the most popular budget managed switches for homelabs. Configured via web UI.
802.1Q VLAN Setup:
- Log into the switch web UI (default:
192.168.0.1) - Navigate to VLAN → 802.1Q VLAN
- Enable 802.1Q VLAN mode
For each VLAN, define which ports are Tagged (trunk) or Untagged (access):
| VLAN | Port 1 (pfSense) | Port 2 (PC) | Port 3 (Server) | Port 4 (IoT) | Port 5 (AP) |
|---|---|---|---|---|---|
| VLAN 10 | Tagged | Untagged | — | — | Tagged |
| VLAN 20 | Tagged | — | Untagged | — | Tagged |
| VLAN 30 | Tagged | — | — | Untagged | Tagged |
| VLAN 99 | Tagged | — | — | — | Tagged |
Then set the PVID (Port VLAN ID) for each port — this is the VLAN assigned to untagged ingress traffic:
| Port | PVID |
|---|---|
| Port 1 (pfSense) | 99 (native, trunk) |
| Port 2 (PC) | 10 |
| Port 3 (Server) | 20 |
| Port 4 (IoT) | 30 |
| Port 5 (AP) | 99 (trunk) |
Cisco IOS (Enterprise/Lab Switches)
# Enter global config
Switch# configure terminal
# Create VLANs
Switch(config)# vlan 10
Switch(config-vlan)# name TRUSTED
Switch(config-vlan)# vlan 20
Switch(config-vlan)# name SERVERS
Switch(config-vlan)# vlan 30
Switch(config-vlan)# name IOT
Switch(config-vlan)# vlan 40
Switch(config-vlan)# name GUEST
Switch(config-vlan)# vlan 99
Switch(config-vlan)# name NATIVE
Switch(config-vlan)# exit
# Configure access port (port for a PC on VLAN 10)
Switch(config)# interface GigabitEthernet0/2
Switch(config-if)# switchport mode access
Switch(config-if)# switchport access vlan 10
Switch(config-if)# spanning-tree portfast
Switch(config-if)# exit
# Configure trunk port (uplink to pfSense or another switch)
Switch(config)# interface GigabitEthernet0/1
Switch(config-if)# switchport mode trunk
Switch(config-if)# switchport trunk encapsulation dot1q
Switch(config-if)# switchport trunk native vlan 99
Switch(config-if)# switchport trunk allowed vlan 10,20,30,40,99
Switch(config-if)# exit
# Disable unused ports (security best practice)
Switch(config)# interface range GigabitEthernet0/6-8
Switch(config-if-range)# shutdown
Switch(config-if-range)# switchport mode access
Switch(config-if-range)# switchport access vlan 999
Switch(config-if-range)# exit
# Save config
Switch# write memory
Juniper EX Series
# Set VLAN definitions
set vlans TRUSTED vlan-id 10 l3-interface irb.10
set vlans SERVERS vlan-id 20 l3-interface irb.20
set vlans IOT vlan-id 30
set vlans NATIVE vlan-id 99
# Access port
set interfaces ge-0/0/2 unit 0 family ethernet-switching
set interfaces ge-0/0/2 unit 0 family ethernet-switching interface-mode access
set interfaces ge-0/0/2 unit 0 family ethernet-switching vlan members TRUSTED
# Trunk port
set interfaces ge-0/0/1 unit 0 family ethernet-switching
set interfaces ge-0/0/1 unit 0 family ethernet-switching interface-mode trunk
set interfaces ge-0/0/1 unit 0 family ethernet-switching vlan members [TRUSTED SERVERS IOT NATIVE]
set interfaces ge-0/0/1 unit 0 family ethernet-switching native-vlan-id 99
commit
HP/Aruba ProCurve (Web UI / CLI)
# Create VLANs
switch(config)# vlan 10
switch(vlan-10)# name "TRUSTED"
switch(vlan-10)# exit
# Assign ports to VLANs
switch(config)# vlan 10
switch(vlan-10)# untagged 2 # Access port - port 2
switch(vlan-10)# tagged 1 # Trunk port - port 1
switch(vlan-10)# exit
# Set native VLAN on trunk
switch(config)# vlan 99
switch(vlan-99)# untagged 1 # Native (untagged) on trunk port 1
switch# write memory
pfSense VLAN Configuration
pfSense is the open-source firewall/router that sits between your VLANs and controls inter-VLAN traffic. The setup flow: create VLANs → create interfaces → assign IPs → configure DHCP → configure firewall rules.
1. Create VLANs on the LAN Interface
Interfaces → Assignments → VLANs → + Add
| Parent Interface | VLAN Tag | Description |
|---|---|---|
| em1 (LAN) | 10 | TRUSTED |
| em1 (LAN) | 20 | SERVERS |
| em1 (LAN) | 30 | IOT |
| em1 (LAN) | 40 | GUEST |
| em1 (LAN) | 50 | MANAGEMENT |
2. Assign VLAN Interfaces
Interfaces → Assignments → + Add for each VLAN:
- Available network port: select
em1.10→ Add → rename toOPT1→ rename in interface settings toTRUSTED - Repeat for each VLAN
3. Configure Each Interface
Interfaces → TRUSTED:
- Enable: checked
- IPv4 Configuration Type: Static IPv4
- IPv4 Address:
192.168.10.1 /24
Repeat for each VLAN with its respective gateway IP.
4. Configure DHCP for Each VLAN
Services → DHCP Server → TRUSTED:
- Enable: checked
- Range:
192.168.10.100to192.168.10.200 - DNS Server:
192.168.10.1(or your preferred DNS)
Repeat for each VLAN.
5. Configure Firewall Rules
This is where the security model lives. Navigate to Firewall → Rules.
IOT VLAN — Internet access only, no LAN:
# Allow IoT to reach DNS on pfSense
Action: Pass
Interface: IOT
Protocol: UDP
Source: IOT net
Destination: IOT address (192.168.30.1)
Dest Port: 53
# Allow IoT internet access
Action: Pass
Interface: IOT
Protocol: TCP/UDP
Source: IOT net
Destination: !RFC1918 (not private addresses)
Dest Port: any
# Block IoT from everything else (private addresses)
Action: Block
Interface: IOT
Protocol: any
Source: IOT net
Destination: RFC1918
GUEST VLAN — Internet only:
Action: Pass
Interface: GUEST
Protocol: any
Source: GUEST net
Destination: !RFC1918
Action: Block
Interface: GUEST
Protocol: any
Source: GUEST net
Destination: any
TRUSTED → SERVERS (allow all):
Action: Pass
Interface: TRUSTED
Protocol: any
Source: TRUSTED net
Destination: SERVERS net
Block SERVERS → TRUSTED (servers don’t initiate to workstations):
Action: Block
Interface: SERVERS
Protocol: any
Source: SERVERS net
Destination: TRUSTED net
Floating rule — anti-spoofing:
Action: Block
Interface: any (floating)
Direction: in
Protocol: any
Source: !VLAN own subnet (traffic from VLAN with wrong source IP)
6. Inter-VLAN DNS
Run Unbound DNS on pfSense for each VLAN, or configure per-VLAN DNS servers. For internal hostnames:
Services → DNS Resolver:
- Enable: checked
- Network Interfaces: add each VLAN interface
- Outgoing Network Interfaces: WAN
Add host overrides for internal services:
nas.home→192.168.20.10homeassistant.home→192.168.20.20
OPNsense VLAN Configuration
OPNsense is the more actively developed fork of pfSense with a modern UI. The flow is nearly identical.
1. Create VLANs
Interfaces → Other Types → VLANs → + Add
- Device:
em1 - VLAN tag:
10 - Description:
TRUSTED
2. Assign Interfaces
Interfaces → Assignments → + Add for each VLAN device.
3. Configure Interfaces
Interfaces → [TRUSTED]:
- Enable interface: checked
- IPv4 Configuration Type: Static IPv4
- IPv4 address:
192.168.10.1 / 24
4. DHCP
Services → DHCPv4 → [TRUSTED]:
- Enable: checked
- Range:
.100to.200
5. Firewall Rules
OPNsense rules work identically to pfSense. Navigate to Firewall → Rules → [interface].
A useful OPNsense-specific feature: Aliases for grouping subnets:
# Create an alias for all RFC1918 space
Firewall → Aliases → + Add
Name: RFC1918
Type: Network
Networks:
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
Then use RFC1918 in rules instead of repeating all three networks.
Linux VLAN Configuration
Linux can participate in VLAN-tagged networks without any additional hardware.
Using ip (iproute2) — Temporary
|
|
Using systemd-networkd — Persistent
|
|
|
|
|
|
|
|
Using NetworkManager — Desktop/Server
|
|
Using netplan (Ubuntu)
|
|
|
|
Wi-Fi and VLANs: Multiple SSIDs
A wireless access point can present multiple SSIDs, each mapped to a different VLAN — so your guests connect to “Guest-WiFi” and land on VLAN 40, while your phone connects to “Home” and lands on VLAN 10.
The AP connects to the switch via a trunk port carrying all the VLANs. The AP maps each SSID to a VLAN tag.
Ubiquiti UniFi
UniFi is the most common managed AP system for homelabs. Configuration is done in the UniFi Controller (or UniFi Network Application):
-
Create Networks: Settings → Networks → Create New Network
- Name:
IoT, VLAN:30, DHCP: enabled or handled by pfSense - Repeat for each VLAN
- Name:
-
Create Wi-Fi SSIDs: Settings → WiFi → Create New WiFi
- Name:
Home-IoT - Network: select
IoT(VLAN 30) - Security: WPA2/WPA3
- Name:
-
Trunk the AP port on the switch:
- The switch port connected to the UniFi AP must be configured as a trunk carrying all VLANs used by SSIDs on that AP
OpenWRT (DIY/flexible APs)
|
|
Practical IoT Isolation Example
This is the most immediately valuable use of VLANs for most homelabs. IoT devices are notorious for:
- Shipping with poor/no security updates
- Phoning home to manufacturer servers
- Being recruited into botnets
- Having default credentials that are rarely changed
Putting them on an isolated VLAN with no LAN access and monitored outbound traffic eliminates most of this risk.
The IoT VLAN Design
IoT VLAN (192.168.30.0/24)
│
├── Smart bulbs (192.168.30.10-19)
├── Thermostat (192.168.30.20)
├── IP cameras (192.168.30.30-39)
├── Smart TV (192.168.30.40)
└── Robot vacuum (192.168.30.50)
│
└──→ pfSense/OPNsense firewall rules:
├── ALLOW: 192.168.30.0/24 → internet (port 80, 443, NTP)
├── ALLOW: 192.168.30.0/24 → DNS (192.168.30.1:53)
├── BLOCK: 192.168.30.0/24 → 192.168.0.0/8 (all private)
└── ALLOW: 192.168.20.5 (Home Assistant) → 192.168.30.0/24
Home Assistant (on the SERVERS VLAN) can reach IoT devices to control them, but IoT devices can’t initiate connections to the trusted network.
Blocking Specific IoT Telemetry (Optional)
Use pfBlockerNG (pfSense) or AdGuard Home on a separate VLAN to block known telemetry domains:
# pfBlockerNG DNSBL categories to enable for IoT traffic:
# - Tracking and Telemetry
# - Advertising
# Per-VLAN DNS override in pfSense pointing IoT VLAN to a filtered DNS
Troubleshooting VLANs
“I configured VLANs but nothing works”
|
|
“Inter-VLAN routing doesn’t work”
|
|
“VLAN hopping / unexpected traffic between VLANs”
|
|
Useful Diagnostic Commands
|
|
Security Hardening Checklist
Switch Security:
□ Change default switch management password and username
□ Disable unused ports (put them in an unused VLAN and shut down)
□ Disable CDP/LLDP on user-facing ports (hides network topology)
□ Enable BPDU Guard on access ports (prevents STP attacks)
□ Disable VLAN 1 as native VLAN — use an unused VLAN (e.g., 999)
□ Restrict management VLAN access to admin IPs only
□ Enable port security (MAC address limiting) on access ports
□ Use a dedicated management VLAN for switch/AP access
Firewall Rules:
□ Default deny on all inter-VLAN traffic, explicit allow only
□ Block RFC1918 on IoT and Guest VLANs
□ Enable anti-spoofing rules
□ Log blocked traffic for analysis
□ Rate-limit new connections from untrusted VLANs
Wi-Fi:
□ Separate SSIDs for each security zone
□ WPA3 or WPA2-AES (not TKIP) on all SSIDs
□ Client isolation on Guest and IoT SSIDs
□ 802.11r (fast roaming) only if needed — disable if not
□ Management Wi-Fi on separate SSID (or wired only)
Quick Reference: VLAN Concepts
802.1Q IEEE standard for VLAN tagging
VLAN ID (VID) 12-bit identifier, range 1–4094
Native VLAN Untagged traffic on a trunk port (use unused VID)
Access Port Connects end devices — one VLAN, untagged
Trunk Port Carries multiple VLANs — tagged frames
PVID Port VLAN ID — VLAN assigned to untagged ingress
Inter-VLAN routing Routing between VLANs — requires L3 (router/firewall)
VLAN hopping Attack exploiting misconfigured native VLANs
ip link add link eth0 name eth0.10 type vlan id 10 # Linux VLAN
switchport mode access / trunk # Cisco port mode
switchport access vlan 10 # Cisco access VLAN
switchport trunk allowed vlan 10,20,30 # Cisco trunk VLANs
switchport trunk native vlan 99 # Cisco native VLAN
A well-segmented network built on VLANs doesn’t just improve security — it makes your network easier to reason about. When a compromised device can only reach the internet and your DNS server, the blast radius of that compromise is contained. When your smart TV can’t talk to your NAS, you don’t lose sleep about its firmware update cadence. The hour spent planning and configuring VLANs pays dividends every day afterward.
Comments