OPNsense Rule & Alias Recipe Generator
Pick a goal — isolate an IoT VLAN, guest-WiFi internet-only, force all DNS to Pi-hole, WireGuard road-warrior, block a country, a safe port-forward — fill a few names and subnets, and get an ordered, copy-pasteable OPNsense rule plan in the exact UI terms, with the reason for every line and an inline lint.
1. Pick a goal
2. Fill the details
IoT devices reach the internet but cannot touch LAN. An mDNS repeater carries AirPlay/Chromecast discovery between the two VLANs so LAN clients still find IoT devices.
3. Your rule plan
Aliases to create first
Firewall ▸ Aliases. Create these before the rules so you can reference them by name.
RFC1918 type: Network(s) Ordered rule plan
Create in this order. Each row shows where in the OPNsense UI, the rule, and why it exists.
- 1 [Config] Services > mDNS Repeater
Install os-mdns-repeater (System > Firmware > Plugins), enable it, and select only LAN and IOT_VLAN20
Why: mDNS/Bonjour discovery (UDP 5353, multicast 224.0.0.251) is link-local multicast (RFC 6762) and is never routed between VLANs, so no pass rule can carry it. The repeater re-sends discovery records between the selected interfaces; it is what lets a LAN phone see an IoT Chromecast. It does not open the discovered service ports. - 2 [Pass] Firewall > Rules > IOT_VLAN20
Pass proto UDP src 192.168.20.0/24 dst 224.0.0.251 dst port 5353 (IoT mDNS to the repeater)
Why: Lets IoT announcements reach the repeater on the firewall. The destination is the multicast group, not 192.168.1.0/24: link-local multicast never matches a LAN-subnet destination, and the repeater, not this rule, carries discovery across. No IoT-to-LAN hole is opened. - 3 [Block] Firewall > Rules > IOT_VLAN20
Block proto any src 192.168.20.0/24 dst alias RFC1918 (block IoT to all private nets)
Why: Everything else inbound to any internal subnet is denied. Using the RFC1918 alias also covers other VLANs, not just LAN. - 4 [Pass] Firewall > Rules > IOT_VLAN20
Pass proto any src 192.168.20.0/24 dst any (allow IoT to internet)
Why: After the private-net block, anything left is internet-bound — IoT devices still phone home and get firmware updates. - 5 [Pass] Firewall > Rules > LAN
Pass proto UDP src 192.168.1.0/24 dst 224.0.0.251 dst port 5353 (LAN mDNS to the repeater)
Why: LAN queries reach the repeater the same way. A default LAN allow-to-any rule already covers this; add it explicitly if your LAN ruleset is locked down. Once a LAN client has discovered a device through the repeater, it connects to the device's service ports, which your LAN rules must allow.
How to read this & honest caveats
OPNsense applies floating rules (those with quick) before per-interface rules,
and within an interface it is first-match-wins, top to bottom. NAT is evaluated
before the filter, which is why a port-forward's matching firewall rule references the
internal IP and port, not the external one. The plan above is ordered so a naive top-to-bottom
paste behaves correctly; the inline lint flags the three mistakes that break these recipes most often:
an any → any allow that shadows everything below it, a NAT port-forward with no associated pass
rule, and floating-vs-interface ordering.
OPNsense is stateful: a pass rule automatically permits the return traffic, so these recipes
deliberately do not add separate "reply" rules — adding them is a common source of confusion. The
WireGuard recipe explicitly includes the interface-assignment step because without it the
Firewall ▸ Rules ▸ <wg> tab does not exist at all.
Recipes, parameters and lint conditions live in src/data/opnsense-recipes.json
(model v1.0.0). This produces a plan to apply by hand on a current OPNsense release — it is
not a config import and does not know your existing ruleset. Always review every rule before
Apply, and test from the affected VLAN, not just from LAN.