pfSense VLAN Configuration: Segment IoT, Guest, and Trusted
This pfSense VLAN configuration guide covers trusted, IoT, and guest networks, plus DHCP, firewall rules, switch tagging, DNS access, and tests.
Proper network segmentation prevents your smart TV from talking to your NAS. This guide covers creating VLANs in pfSense and the firewall rules that make segmentation actually work. It assumes you already have a working WAN+LAN box; if not, start with the pfSense initial setup guide and come back here to segment.
A reality check before you start: VLANs only isolate traffic if all three of these are correct — the pfSense VLAN sub-interfaces are tagged properly, your managed switch trunks/accesses those VLANs properly, and the firewall rules on each VLAN interface actually block inter-VLAN traffic. A VLAN with a permissive “allow any” rule and no block rule is just a flat network with extra configuration. You also need a switch that supports 802.1Q tagging and an AP that maps SSIDs to VLANs (or trunks them). A dumb unmanaged switch cannot enforce any of this — it will pass tagged frames around blindly.
VLANs are also the standard answer to “how many network ports does my firewall need”, because one trunked port can carry every segment. That works, at the cost of sharing one physical link’s bandwidth and one failure domain across all of them. If you would rather give a DMZ or an IoT segment its own physical port, decide that before you buy the box: the pfSense hardware requirements guide covers port count and chipset choice, and sealed fanless appliances generally cannot accept an extra card later.
Design: Three-VLAN baseline
| VLAN ID | Name | Subnet | Purpose |
|---|---|---|---|
| 10 | TRUSTED | 192.168.10.0/24 | Workstations, servers, phones you control |
| 20 | IOT | 192.168.20.0/24 | Smart home devices, printers, cameras |
| 30 | GUEST | 192.168.30.0/24 | Guest Wi-Fi — internet only |
Step 1: Create VLANs
Interfaces → Assignments → VLANs tab → Add:
- Parent interface: your LAN NIC (e.g.,
igb1) - VLAN tag: 10
- Description: TRUSTED
Repeat for VLAN 20 (IOT) and VLAN 30 (GUEST).
Step 2: Assign interfaces
Interfaces → Assignments → select each new VLAN from the drop-down → Add. Then:
- Click each new interface (OPT1, OPT2, OPT3)
- Enable interface ✓
- Set IPv4 Configuration Type: Static IPv4
- Assign IPv4 address: e.g.,
192.168.10.1 /24for TRUSTED - Save & Apply Changes
Enable DHCP server for each: Services → DHCP Server → select interface → Enable → set a range inside the subnet (keep the .1 gateway and any static hosts outside the pool). Set the DNS server for the scope to the pfSense VLAN IP if you want per-VLAN DNS filtering through pfBlockerNG DNSBL. Apply, then check Status → DHCP Leases to confirm clients on that VLAN actually receive addresses — no scope means no automatic addressing on that segment.
A common ordering gotcha: assign and enable the interface before configuring its DHCP scope. pfSense won’t let you bind a DHCP server to an interface that has no static IPv4, and a freshly added VLAN interface defaults to “none” until you set Static IPv4 and save.
Step 3: Firewall rules
IoT VLAN — block all inter-VLAN, allow internet
On the IOT interface (Firewall → Rules → IOT):
Rule 1 — Block IoT → RFC1918:
Action: Block
Protocol: Any
Source: IOT subnets
Destination: 192.168.0.0/8
Description: Block IoT to private ranges
Rule 2 — Allow IoT → internet:
Action: Pass
Protocol: Any
Source: IOT subnets
Destination: Any
Description: Allow IoT internet access
Rules are evaluated top-down, first match wins, and pfSense applies rules on the interface where traffic enters. The block rule must sit above the allow rule, or the allow-any will pass inter-VLAN traffic before the block is evaluated. The single most common reason “my isolation isn’t working”: the block destination only covers 192.168.0.0/8 while another segment lives in 10.x or 172.16–31.x. Fix this properly with an alias: Firewall → Aliases → add a network alias (e.g., RFC1918) containing 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16, then use that alias as the block destination on every restricted VLAN.
Also note pfSense’s implicit default-deny: anything not explicitly passed on an interface is dropped — but each interface needs its own ruleset. Rules are not inherited between VLANs.
Don’t lock out DNS/NTP to the firewall
If clients use the pfSense VLAN IP for DNS, the broad RFC1918 block will also kill DNS to the firewall itself. Add a narrow pass rule above the block: source = that VLAN’s subnet, destination = “This Firewall”, port = 53 (TCP/UDP, plus 853 for DoT if used). Do the same for NTP (UDP 123) if devices sync time from pfSense. Decide deliberately whether a VLAN may reach the pfSense GUI at all — for IoT/guest, it generally should not, so do not pass 80/443 to “This Firewall” from those segments.
Guest VLAN — internet only, block RFC1918
Same pattern as IoT, applied to the GUEST interface. Consider also enabling the “Block private networks” and “Block bogon networks” options, and rate-limiting or captive-portal’ing guests if appropriate.
Trusted VLAN — full access
Allow all by default (or lock down as needed for your threat model). Even here, an explicit pass rule is required — there is no implied “trusted = open” in pfSense.
Step 4: Test segmentation
From an IoT device, confirm:
ping 192.168.10.1 # Should fail (blocked by firewall rule)
curl https://example.com # Should succeed
If even the gateway ping fails, suspect switch tagging before the firewall — check the next section.
Managed switch tagging
This is where most VLAN setups actually break. The switch port to pfSense must be a trunk carrying VLANs 10/20/30 tagged. Device-facing ports are access ports with PVID set to the device’s VLAN; the switch tags on ingress and strips on egress so the device sees untagged Ethernet. The pfSense parent NIC is the trunk; the VLAN sub-interfaces handle each tag.
Two recurring switch-side gotchas:
- Native/untagged VLAN mismatch. If the switch passes a VLAN untagged on the trunk that pfSense expects tagged, traffic leaks onto the wrong segment. Set the trunk’s native VLAN to an unused ID and never place trusted hosts on VLAN 1.
- AP uplink trunking. The AP uplink is also a trunk. Each SSID must be mapped to its VLAN on the AP; a “guest” SSID that isn’t actually tagged onto VLAN 30 lands on the native VLAN and silently bypasses all isolation.
Verify at the switch: its VLAN membership table should show the pfSense port tagged for all three VLANs and each access port untagged on exactly one.
Running UniFi APs? See UniFiGuide for SSID-to-VLAN mapping in the Network Application.
When VLAN segmentation is the wrong tool
VLANs give you layer-2 separation enforced by the firewall at layer 3. They’re ideal for keeping untrusted device classes (IoT, guests, cameras) off your trusted hosts, but they do not protect devices on the same VLAN from each other and are not a substitute for host hardening. Once a guest or IoT VLAN exists, it’s the natural interface to point an IDS/IPS engine like Snort or Suricata at, rather than inspecting every segment. If you have a handful of devices and a basic switch, the operational overhead of VLANs may exceed the benefit — a single well-firewalled LAN plus a separate guest network on the router can be enough. Reach for VLANs when distinct trust tiers genuinely must share switching and Wi-Fi infrastructure.
For more context, Docker homelab tutorials covers related topics in depth.
Related across the network
- VLAN Filtering on RouterOS Bridges Without Lockout — mikrotikguide.com
Related on this site
Related
pfSense VLAN Setup for Homelab: Design, Rules, and Tests
pfSense VLAN setup for homelab: trunk layout, a four-VLAN plan, firewall rules in apply order, mDNS reflection, DNS pinning, and the tests that prove it.
pfSense Port Forwarding Not Working? Fix It Step by Step
Nine ordered checks for a pfSense port forward that passes nothing: rule destination, private or CGNAT WAN address, target gateway, reflection.
pfSense GeoIP Blocking with pfBlockerNG and MaxMind
Add a MaxMind license key for GeoLite2 country blocks, choose inbound or outbound actions, then add Emerging Threats, Spamhaus and Abuse.ch feeds.