Wi-Fi & Network
Inter-VLAN firewall rules done right
Once your VLANs exist, the firewall rules between them are where segmentation succeeds or quietly fails. The two things people get wrong are believing they need an 'allow established/related' rule, and getting rule order backwards so a broad allow shadows the block.
Who this is for
Home operators who've already created VLANs (trusted / IoT / guest) and now need the firewall rules between them to actually isolate the IoT VLAN — on UniFi Zone-Based Firewall, OPNsense, or pfSense — without breaking casting, printing, DHCP, or DNS.
Outcome
A correct, ordered inter-VLAN rule set: IoT can reach the internet and the gateway for DNS/DHCP but not your other subnets, specific trusted→IoT exceptions work, and you've dropped the unnecessary 'allow established/related' rule because these firewalls are stateful — with the per-platform ordering nuances understood.
Required inputs
- Existing VLANs and a firewall you administer: a UniFi gateway with Zone-Based Firewall (Network 9.0+, not Express/UXG-Lite), OPNsense, or pfSense.
- The list of legitimate cross-VLAN exceptions you actually need (e.g. trusted phone → Chromecast/printer on specific ports).
- Knowledge of which subnet/zone each VLAN is, and the gateway IP that serves DNS/DHCP.
- A way to test from each VLAN (a client or a laptop you can move between VLANs).
Step-by-step procedure
Drop the 'allow established/related' habit
Do: On UniFi ZBF, OPNsense, and pfSense, do NOT author an 'allow established/related' rule for inter-VLAN traffic. These are stateful: when your single directional allow matches a new connection, the state table lets the return packets back automatically. (UniFi's built-in 'Auto Allow Return Traffic' is the vendor-written exception you don't hand-author.)
Expected result: Your rule set has only connection-initiating-direction rules, no manual return rules.
If not: If you copied a two-rule 'allow established/related then block' recipe, remove the established rule — it's a stateless-era carryover that just adds noise.
Protect the gateway path (DNS/DHCP) first
Do: Ensure IoT can still reach the gateway for DNS (53) and DHCP (67/68). Never blanket-block the gateway zone/host — UniFi warns this disrupts DHCP and DNS, and it's true on all three platforms.
Expected result: IoT devices can lease an address and resolve names even after you isolate the VLAN.
If not: If IoT devices stop getting addresses or can't resolve after you add the block, you've blocked the gateway — carve the gateway allow above the block.
Place specific trusted→IoT exceptions ABOVE the block
Do: Author the allow rules for the exact cross-VLAN access you need (trusted device → Chromecast/printer IP on the needed ports), and place them above the broad block. Return traffic is automatic via state — no reverse rule needed.
Expected result: Casting/printing from trusted to IoT works, and you didn't write a matching reverse rule.
If not: If the exception doesn't work, it's almost certainly sitting below the broad block on a first-match platform — move it up.
Block IoT→other-subnets above the internet allow
Do: Add the isolation rule: block IoT → RFC1918 (10/8, 172.16/12, 192.168/16). On pfSense / OPNsense (quick) this must sit ABOVE the 'allow IoT → any (internet)' rule, or the broad allow matches first and the block is dead. Then add allow IoT → internet as the lowest user rule.
Expected result: IoT reaches the internet but cannot initiate to your other VLANs.
If not: If IoT can still reach your LAN, the block is below the internet allow (or, on UniFi, a higher custom allow overrules it) — fix the order.
Mind the per-platform order model
Do: pfSense interface rules are first-match top-to-bottom (most-permissive at the bottom). OPNsense is first-match for 'quick' rules (the default) but last-match for non-quick — don't assume 'first match always wins'. UniFi: custom policies outrank built-in ones; use Reorder so the specific allow sits above the broad block.
Expected result: Your ordering matches how your specific platform evaluates rules.
If not: If results seem random, check for a non-quick OPNsense rule or a UniFi built-in policy being overruled unexpectedly.
Test both directions and each VLAN
Do: From IoT, confirm internet works but a ping/connection to a trusted-VLAN host is blocked. From trusted, confirm the cast/print exception works. Remember UniFi policies are directional — blocking A→B while allowing B→A still blocks one way.
Expected result: IoT is isolated from your LAN, exceptions work, DNS/DHCP work, and the directions behave as intended.
If not: If a watched flow is wrong, re-check rule order first, then the netmask (a /24 where you meant /32 silently widens a rule).
Commands and settings paths
Prove IoT isolation from a client
From an IoT-VLAN device: ping <trusted-host> and curl https://example.com
Where: On a device connected to the IoT VLAN.
Expected: Internet (curl) works; the trusted-host ping/connection is blocked.
Failure means: If IoT can reach the trusted host, the block is ordered below the internet allow or overruled.
Safe next step: Move the block IoT→RFC1918 rule above the allow-to-internet rule and re-test.
Prove the trusted→IoT exception
From a trusted device: reach the Chromecast/printer IP on its port (e.g. curl/telnet to the port)
Where: On a device on the trusted VLAN.
Expected: The specific allowed service responds; no reverse rule was needed.
Failure means: A failed exception usually means it sits below the broad block on a first-match platform.
Safe next step: Move the exception above the block; confirm you didn't also add an unneeded reverse rule.
Confirm DHCP/DNS still work on IoT
On an IoT client: check it has a DHCP lease and run nslookup example.com
Where: On an IoT-VLAN device.
Expected: The device has an address and resolves names via the gateway.
Failure means: No lease / no resolution means the gateway path got blocked.
Safe next step: Add/raise the allow IoT→gateway (DNS/DHCP) rule above the block.
Evidence to record
- The final ordered rule list per VLAN (gateway allow, trusted→IoT exceptions, block IoT→RFC1918, allow IoT→internet).
- That no manual 'allow established/related' rule exists (statefulness handles return).
- Platform + version (UniFi Network/gateway model, or OPNsense/pfSense) and whether any OPNsense rule is non-quick.
- Test results: IoT→internet OK, IoT→LAN blocked, trusted→IoT exception OK, DHCP/DNS OK.
Common mistakes
- Writing an 'allow established/related' rule — unnecessary on these stateful platforms; the state table handles return traffic.
- Placing the block IoT→RFC1918 below the allow-to-internet rule, so a first-match platform never reaches the block.
- Putting a trusted→IoT exception below the broad block, so casting/printing silently fails.
- Blanket-blocking the gateway zone/host, which kills DHCP and DNS for the VLAN.
- Assuming 'first match always wins' — true on pfSense and OPNsense quick rules, but OPNsense non-quick rules are last-match.
Stop points
- Stop before applying a broad block if you haven't first carved the gateway (DNS/DHCP) allow — you'll knock the VLAN offline.
- Stop and check the netmask (/24 vs /32) before widening a rule hunt — a slipped mask is a common 'rule too broad' cause.
Last reviewed
2026-06-02
Source-backed checks
HomeTechOps turns official docs and conservative safety rules into a shorter runbook. These links are the source trail for the page direction.