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.
Most guides to pfsense vlan setup for homelab use stop at “create the VLAN, assign it, add a pass-any rule”. That leaves you with four subnets and zero isolation, because pfSense evaluates rules per interface, first match wins, and a pass-any rule at the top of the IoT tab hands traffic to your NAS before any block rule is read. This post is the design layer under the click-by-click pfSense VLAN configuration guide: topology, address plan, rule order, discovery, and the tests that prove it.
The goal
Four segments on one pfSense box and one 802.1Q switch: trusted clients, homelab servers, IoT, guests. Trusted reaches everything. Servers reach the internet and answer trusted. IoT and guest get internet plus DNS from pfSense and nothing else. The pfSense GUI and the switch are managed from trusted only.
Topology
Router-on-a-stick: igc0 on WAN, igc1 as the LAN trunk. Netgate’s VLAN documentation lists the Intel em(4), igb(4) and ix(4) families as having hardware VLAN tagging and warns that some Realtek rl(4) parts “will not accept 802.1Q tagged frames at all”. The tag adds 4 bytes, so a tagged frame reaches 1522 bytes and a NIC without long-frame support has to run a lower MTU. The hardware requirements guide covers which boxes ship Intel.
ISP modem ── igc0 (WAN)
pfSense igc1 ── trunk, tagged 10,20,30,40 ── switch port 1 (USW-Pro-24-PoE, CRS328-24P, any 802.1Q switch)
switch port 2 ── trunk, tagged 10,30,40 ─── AP (SSID Home→10, IoT→30, Guest→40)
switch ports 3-8 ── access, PVID 20 ──────── Proxmox host, NAS
switch ports 9-24 ── access, PVID 10 ─────── desks
Stay off VLAN 1. Netgate’s VLANs and Security page notes switches send STP, VTP and CDP untagged over the native VLAN and says to treat VLAN 1 like a default-allow firewall policy: you have 2 through 4094 to pick from. Set the trunk PVID to an unused ID such as 999 so an untagged frame from a misconfigured port lands nowhere. If you want a break-glass path, assign the untagged parent igc1 as MGMT with exactly one switch access port.
Inter-VLAN traffic crosses the trunk twice, in on one tag and out on another, so every trusted-to-NAS flow shares that link with everything else. A 2.5GbE or 10GbE trunk is the fix; putting the workstation and NAS on the same VLAN is the cheap one.
If pfSense is a VM, the Proxmox network docs describe the VLAN-aware bridge (bridge-vlan-aware yes, bridge-vids 2-4094); leave the VM NIC’s VLAN tag empty so the tags reach vtnet1 and create the VLANs inside pfSense. The Proxmox bridge and VLAN guide covers the host side.
VLAN plan
| VLAN | Name | CIDR | Gateway | DHCP range | Inter-VLAN policy |
|---|---|---|---|---|---|
| 10 | TRUSTED | 10.10.10.0/24 | 10.10.10.1 | .100 to .199 | any |
| 20 | SERVERS | 10.10.20.0/24 | 10.10.20.1 | static mappings; .200 to .220 for new boxes | internet only, answers TRUSTED |
| 30 | IOT | 10.10.30.0/24 | 10.10.30.1 | .100 to .250 | internet, pfSense DNS and NTP only |
| 40 | GUEST | 10.10.40.0/24 | 10.10.40.1 | .100 to .250 | internet and pfSense DNS only |
Third octet equals VLAN ID; that one convention removes most “which subnet is this” mistakes. All three RFC 1918 blocks still go in one alias, because a 192.168.x device will turn up eventually.
Per VLAN: Interfaces > Assignments > VLANs, parent igc1, tag, description; then assign, enable, static IPv4 /24. Leave “Block private networks” and “Block bogon networks” unchecked on every VLAN interface. Netgate’s interface docs say the first is “typically only desirable on WAN type interfaces” and the second “can potentially block required local traffic”; on GUEST it blocks the guests themselves. Enable DHCP per interface with static mappings for anything a rule will name. ISC DHCP is deprecated; the Kea switch is under System > Advanced > Networking.
IPv6 needs the same per-VLAN plan. Netgate’s IPv6 Configuration Types describes both options: Track Interface assigns each VLAN a /64 from a delegated WAN prefix using a distinct Prefix ID, while Static IPv6 assigns an address from a unique routed prefix. Equivalent IPv6 firewall rules are required because the IPv4 RFC1918 alias does not match IPv6 traffic.
Firewall rules
Aliases first: RFC1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and MGMT_PORTS (22, 443).
Netgate’s rule methodology is the whole game: rules apply “always in the inbound direction on that interface”, processed until a match, stateful, and “outbound rules are never required”. Unmatched traffic is silently dropped. A NAS replying to a trusted client therefore needs no rule on SERVERS; the state created on TRUSTED carries the reply.
IOT tab, in apply order:
- Pass, TCP/UDP, source IOT net, destination IOT address, port 53.
- Pass, UDP, source IOT net, destination IOT address, port 123.
- Pass, ICMP echo request, source IOT net, destination IOT address.
- Reject, any, source IOT net, destination “This Firewall (self)”.
- Block, any, source IOT net, destination
RFC1918. - Pass, any, source IOT net, destination any.
Rule 4 matches every address on every pfSense interface, so IoT cannot reach the GUI via 10.10.10.1 or the WAN IP; Netgate’s management-restriction recipe says “reject is preferred on internal networks”. Rules 1 to 3 use “IOT address” rather than “This Firewall” so the only pfSense IP IoT can talk to is its own gateway.
Shadowing, in the order people hit it: rule 6 above rule 5 is a flat network with extra configuration. Rule 4 above rule 1 kills DNS. A floating rule with Quick set, or a rule on an Interface Group tab, runs before any of these; Netgate’s troubleshooting page is explicit that once one matches, “a block rule on an interface would have no chance to match”. A RESTRICTED group holding rules 4 and 5 for IOT and GUEST is tidy, but every per-VLAN exception then has to live in the group tab too.
GUEST: the same list minus rule 2. SERVERS: rules 1, 2, 4, 5, 6, with narrow passes above rule 5 where a server must initiate into IoT (a Home Assistant VM reaching a hub). TRUSTED: pass any, plus an explicit pass to “This Firewall” on MGMT_PORTS from an admin-hosts alias before you disable the anti-lockout rule.
Same troubleshooting page: an existing state is not cut off by a new block rule. After adding rule 5, reset states under Diagnostics > States, or the TV keeps talking to the NAS until its session times out.
DNS and discovery
Unbound’s access lists permit “networks residing on internal interfaces” by default, so every VLAN resolves against its gateway with no extra work. Devices hard-coded to 8.8.8.8 bypass that; Netgate’s DNS redirect recipe is a port forward on the interface with destination inverted, port 53, target 127.0.0.1, so “DNS requests from local clients to any external IP address will result in the query being answered by the firewall itself”. It cannot catch DNS over TLS or HTTPS; redirecting 853 helps with some clients.
mDNS is why IoT segmentation gets a bad name. RFC 6762 sends .local queries to 224.0.0.251 on UDP 5353 and defines the names as link-local, “meaningful only on the link where they originate”. A router does not forward them. The pfSense Avahi package fixes this by reflection: per the avahi-daemon.conf man page, enable-reflector makes the daemon “reflect incoming mDNS requests to all local network interfaces”. Allow TRUSTED and IOT, deny GUEST, and run exactly one reflector; two between the same networks loop.
Reflection only carries the advertisement. The unicast session that follows (Chromecast on TCP 8008/8009, AirPrint on 631) is opened from TRUSTED, which passes any, and the reply rides the state. You need a pass above the RFC1918 block only when the IoT device initiates. Enable IGMP snooping on the switch so multicast stops flooding every port, and leave pfSense’s IGMP proxy alone unless you need real multicast streams across VLANs. If the APs are UniFi, the SSID-to-VLAN mapping is the controller’s job; the UniFi VLAN setup guide covers that half.
Things to test before you call it done
From a laptop on the IoT SSID (10.10.30.x):
ping -c 3 10.10.30.1 # gateway answers (rule 3)
ping -c 3 10.10.10.1 # must fail (rule 4)
nc -vz -w 3 10.10.20.10 445 # NAS SMB, must fail (rule 5)
dig +short example.com @10.10.30.1 # answers (rule 1)
dig +short pfsense.home.arpa @8.8.8.8 # answers only if the DNS redirect works
curl -sI https://example.com | head -1 # 200 (rule 6)
From TRUSTED:
mtr -n -c 20 10.10.20.10 # one hop via 10.10.10.1, no loss
iperf3 -c 10.10.20.10 -P 4 -t 20 # inter-VLAN throughput across the trunk
avahi-browse -art | grep -i chromecast # reflected services from IOT
Then Diagnostics > States: filter on 10.10.30 and confirm nothing points at 10.10.10.0/24 or 10.10.20.0/24. Finally Status > System Logs > Firewall, where pfSense logs dropped traffic by default; a rule 5 hit from a bulb you never expected to see there is the first sign it is scanning your network.
Related across the network
- OPNsense VLAN Setup: Trusted, IoT, Guest, and Management — opnsenselab.com
- UniFi VLAN Setup Guide: Segment Your Network the Right Way — unifiguide.com
- Best Homelab Firewall in 2026: OPNsense, pfSense, UniFi, MikroTik — firewallcompare.com
- Firewalla vs pfSense: Appliance or DIY Firewall? — firewallcompare.com
- HAProxy vs nginx Reverse Proxy for a Home Firewall — firewallcompare.com
Sources
- Netgate Docs: Virtual LANs (VLANs)
- Netgate Docs: VLANs and Security
- Interface Configuration
- DHCP
- IPv6 Configuration Types
- Netgate Docs: Firewall Rule Processing Order
- Netgate Docs: Restrict Access to the Management Interface
- Netgate Docs: Troubleshooting Firewall Rules
- Netgate Docs: Redirecting Client DNS Requests
- DNS Resolver Access Lists
- Avahi package
- RFC 6762: Multicast DNS
- RFC 1918: Address Allocation for Private Internets
- Proxmox VE Wiki: Network Configuration
- avahi-daemon.conf(5) man page
Related
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.
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.
How to Install pfSense in a Proxmox VM: Step-by-Step Guide
A step-by-step walkthrough for how to install pfSense in a Proxmox VM, covering ISO upload, Linux bridges, VirtIO settings, and the checksum offload fix.