Digitized picture of a lock, floating between racks in a datacentre with digital electronic flows going through it.
OPNsense, keeping you secure.

OPNsense Part 2: Firewall Rules, NATs, and Traffic Flows

Learn how to configure OPNsense firewall rules, VLAN isolation, port forwarding, NAT mechanics, and advanced outbound egress filtering for your homelab.

Now that your OPNsense base deployment and hardware architecture are established and running from the Master OPNsense Hub, it's time to configure the heart of the firewall: Rules, Aliases, and NAT Flows.

OPNsense operates as a stateful packet filter. This means once a connection is allowed by a rule in one direction, returning traffic for that state is automatically permitted. In other words, it's already blocking everything inbound by default. In this guide, we break the setup into logical workflows and cover the essential firewall traffic patterns every homelab and small office network requires.

💥
A flat network is an insecure network. We will now use our OPNsense firewall to carve up our LAN into secure, isolated zones (VLANs) and subnets.

The Plan: Our Network Design

We will create the following VLANs. The IP scheme is a common pro-sumer setup: 10.10.X.1, where X is the VLAN ID number. You can use any class C address space really, 192.168.x.x, 172.16.x.x, or 10.0.x.x as I have done but the important part is to simply decide, and pick one now. No one outside your network will see or care about this IP space, and it can be changed later, although that's more difficult. Better to plan it properly from the start.

VLAN NameTag IDSubnetPurpose
LAN(Native)10.10.1.1/24Trusted Devices (Your PC, Phone)
MANAGEMENT1010.10.10.1/24IPMI, Proxmox Admin, Switches
GUEST2010.10.20.1/24Visitors (Internet Only)
IOT3010.10.30.1/24Smart Bulbs, Fridges (Internet Only)
CAMERAS4010.10.40.1/24Security Cams (No Internet)
DMZ5010.10.50.1/24Public facing servers

OPNsense Configuration Prerequisites

This guide assumes you have one piece of essential hardware: a VLAN-capable Managed Switch. A basic, unmanaged "dumb" switch cannot handle the VLAN tags we'll be creating. Popular brands include Ubiquiti UniFi, TP-Link Omada, Netgear, and Mikrotik. You don't need to have an expensive fancy switch, anything that is VLAN capable will do.

  • Some CAT5E or preferably, CAT6 or 6A cables
  • A computer of some kind with an RJ45 ethernet port to plugin to OPN, or to your switch and network so you can reach the firewall to perform configuration and validation.

Learning Path • Firewall & Defensive Architecture

Mastering OPNsense Firewall Architecture

Deploy enterprise-grade routing on bare metal, construct resilient alias hierarchies, enforce Layer 7 threat defence, and automate encrypted off-site disaster recovery.

Lesson 2 of 7 29% Complete
Difficulty Curve Intermediate
Beginner Advanced
Tested in production on bare-metal hardware
Core Lab Learning Track · Zero Tracking & Direct Implementation

Part 1: Network Segmentation & VLAN Creation

  1. Navigate to Interfaces -> Other Types -> VLAN.
  2. Click the + (Add) button.
  3. Parent: Select your primary LAN interface (e.g., em1 or igb1).
  4. VLAN Tag: 10
  5. Description: MANAGEMENT
  6. Click Save.
  7. Repeat for VLANs 20, 30, 40, 50.
A bird's-eye view of your segmented network. Here you can see the VLAN tags (ID) and their descriptions, all trunked off a single parent interface.
OPNsense Interfaces Devices VLAN screen displaying a list of created VLANs attached to parent lagg0.

Assign VLANs to New Interfaces

  1. Navigate to Interfaces -> Assignments.
  2. In the dropdown at the bottom, select a new VLAN (e.g., VLAN 10) and click +.
  3. It will appear as OPT1. Click on OPT1 to edit it.
  4. Enable Interface: Checked.
  5. Description: Rename to MANAGEMENT.
  6. IPv4 Configuration Type: Static IPv4.
  7. IPv4 Address: 10.10.10.1 and select /24 from the dropdown.
  8. Click Save.
  9. Repeat for all other VLANs.

Configure DHCP for Each VLAN

In the v25.x days, we used the old ISC DHCP service. As of OPNsense 27.2.x, Dnsmasq or Kea are the choices you have for DHCP, DNS and Router Advertisement (RA) provider. While you can install the ISC plugin for nostalgia, I strongly recommend moving to the modern stack which is what I did immediately.

📡
If you were using DNS via another service before on port 53, you will have to disable that first before turning this on!
  1. Navigate to: Services -> Dnsmasq DNS & DHCP -> General.
  2. Enable DHCP: Ensure "Enable Dnsmasq" is checked. Dnsmasq now handles both your DNS resolution and your DHCP leases in a unified interface. I chose to use Dnsmaq for both at Core Lab.
  3. Hit the Hosts tab and enter any static hosts you want to keep here, but you must have their MAC addresses as shown below 👇
DNSMasq hosts tab & config
DNSMasq hosts tab & config
DNSMasq hosts tab & config
Another view of it, different colour theme ;)
    1. This is also where you'd put in a DNS re-write if you want to access something internal like, your own website or an Aarr app being served by your reverse proxy. For me, I have a wildcard entry so that every time I try to reach corelab.tech from inside my own LAN, it's sent to my reverse proxy! You use a * in the host, domain.name in the Domain field, and the IP address pointed at your reverse proxy. 👨‍🍳
DNSMasq host settings to allow 'split' DNS
DNSMasq host settings to allow 'split' DNS
    1. Next up, and important ❗- Set your DHCP ranges for each interface (vlan!)
    2. This should match the subnet you assigned for each interface, in other words if your internal home LAN was /24 (255.255.255.0) you would ensure the net mask stays the same. You can start your DHCP range at 10 or 20 addresses in, if you want to keep some saved for static assignments etc...
DNSMasq DHCP pools overview
DNSMasq DHCP pools overview
Screenshot of DNSMasq DHCP pool configuration
DNSMasq DHCP pool configuration

Alternative (The Pro Path): If you want the new enterprise standard, navigate to Services -> Kea -> DHCPv4. Click the [+] to add a subnet.

    1. Subnet: 10.10.10.0/24
    2. Pool: 10.10.10.100 - 10.10.10.200
    3. Why Kea? It’s built on the new MVC/API framework, making it faster and more stable for high-automation environments.

Tagging Your Main LAN: Moving Off VLAN 1

As a security best practice: running "mixed mode" with both untagged (VLAN 1) and tagged traffic on the same trunk port is not ideal nor recommended by OPNsense. The "purest" and most secure setup is to have all your networks, including your primary trusted one, be tagged VLANs.

This is a bit advanced so if you want to skip this part for now, that's ok, it'll be here when you're ready but I strongly recommend tackling it from the beginning. It's harder to change later...

This guide will walk you through migrating your main LAN (which is untagged by default) to a new, tagged VLAN 8, which we will call HOME. You can name it anything you want and pick any number up to 4000 of course.

🚨🚨 CRITICAL WARNING: HIGH RISK OF LOCKOUT 🚨🚨

This is the most complex step in this guide, and you WILL 100% LOCK YOURSELF OUT of the OPNsense GUI if you perform these steps incorrectly or out of order.

You are about to change the "address" of the very interface you are using to access the GUI.

BEFORE YOU BEGIN, YOU MUST:
  • Have a Backup: Go to System -> Configuration -> Backups and DOWNLOAD a backup of your OPNsense config.
  • Know Your Switch: Be logged into your managed switch's web GUI in a separate browser tab. You must know how to change VLAN assignments on its ports.
  • Have a Plan: Read this entire section before you click a single button. The order of operations between OPNsense and your switch is critical.
  • Be Patient: After you apply the final changes, your computer must get a new IP address. You will need to unplug/replug your network cable or force a DHCP release/renew.

The Goal

Our goal is to change your network from this:

  • OPNsense igb1 Port:
    • LAN (Untagged, 10.10.1.1/24)
    • IOT (Tagged VLAN 30)
    • GUEST (Tagged VLAN 20)
  • Switch Trunk Port:
    • Native VLAN: 1 (for LAN)
    • Tagged VLANs: 20, 30

To this:

  • OPNsense igb1 Port:
    • HOME (Tagged VLAN 8, 10.10.1.1/24)
    • IOT (Tagged VLAN 30)
    • GUEST (Tagged VLAN 20)
  • Switch Trunk Port:
    • Native VLAN: None (or a "black hole" VLAN)
    • Tagged VLANs: 8, 20, 30

Notice that we are moving all the LAN settings (IP, DHCP, firewall rules) to a new tagged interface, HOME.

Step 1: Create the New HOME VLAN (OPNsense)

First, we just define the new VLAN tag if you haven't created one you want to use already, in the above steps.

  1. Navigate to Interfaces -> Other Types -> VLAN.
  2. Click + (Add).
  3. Parent: Select your physical LAN interface (e.g., igb1, em1, lan).
  4. VLAN Tag: 8 or whatever VLAN # you choose.
  5. Description: HOME
  6. Save and Apply Changes.

Step 2: Re-Assign the LAN Interface (The "Point of No Return")

This is the most critical step. We are telling OPNsense that its LAN interface is no longer on the physical port (igb0/igb1), but is now on the virtual VLAN 8 we just created.

  1. Navigate to Interfaces -> Assignments.
  2. You will see your LAN interface, likely assigned to your physical port (e.g., igb1).
  3. In the dropdown menu for the LAN interface, change the "Device" from the physical port (e.g., igb1) to the new VLAN you just created (VLAN 8 on igb1 (HOME)).
  4. Click Save.
  5. YOU WILL BE IMMEDIATELY DISCONNECTED AND LOCKED OUT. This is normal. Your browser will spin, and the OPNsense GUI will be unreachable. Do not panic.

Step 3: Re-Configure Your Managed Switch (The "Recovery")

Your OPNsense firewall is now only sending LAN traffic on VLAN 8 (Tagged). Your computer and switch are still on VLAN 1 (Untagged). We must fix this.

  1. Go to your Managed Switch's web GUI (which you already have open in another tab, right?).
  2. Create VLAN 8: Go to your switch's VLAN settings and create VLAN 8 (Name: HOME).
  3. Configure Your PC's Access Port:
    • Find the switch port that your PC is plugged into.
    • Change its port profile.
    • Set its Native / Untagged VLAN to 8 (HOME).
    • Make sure it is not passing any other tagged VLANs (it should be an "access" port, not a trunk).
    • Save/Apply.
  4. Configure the OPNsense Trunk Port:
    • Find the switch port that your OPNsense firewall is plugged into.
    • Change its port profile (the "Trunk" profile).
    • Native / Untagged VLAN: Change this from 1 (LAN) to None (or a "dummy" black hole VLAN like 999 if your switch requires one. Do NOT use 1 or 8).
    • Tagged VLANs: Add VLAN 8 (HOME) to the list of allowed tagged VLANs. The list should now include 8, 10, 20, 30, 40, 50... all your VLANs.
    • Save/Apply. In Unifi it should look something like this -

Note: You can "Allow All" VLANs, or tag them with the custom option - the choice is yours. To be more secure, technically you should lock it down with "Custom" and select each VLAN that you need. Example VLAN in this pic is 7, yours might be 8 like in the guide, or 888.

Step 4: Reconnect and Verify

  1. Your switch is now configured. Go back to your PC.
  2. Force a DHCP Renew: Your PC is still holding its old IP. The easiest way to fix this is to unplug your PC's network cable, wait 5 seconds, and plug it back in.
    • (Alternatively, for Windows: ipconfig /release then ipconfig /renew. For Mac: Renew DHCP in Network Settings.)
  3. Your PC should now request an IP. The switch will tag this request as VLAN 8, send it to OPNsense. OPNsense's LAN interface (now on VLAN 8) will receive it and its DHCP server (which was already configured for LAN) will respond.
  4. You should get an IP address in your 10.10.1.x range.
  5. Try to access your OPNsense GUI at 10.10.1.1 (or whatever its IP is).
  6. Success! You are now accessing your firewall over a fully tagged network.

How to Configuring "Router on a Stick" Trunk Port in OPNsense

A "router on a stick" is a very common and efficient configuration where a single physical interface on your OPNsense firewall (like its only RJ45 port) is used to manage and route traffic for multiple, isolated VLANs.

Instead of needing a separate physical port for your LAN, IoT, and Guest networks, you create virtual sub-interfaces on that single OPNsense port, one for each VLAN tag (e.g., 10, 20, 30). This port is then connected via a single cable to a "trunk" port on your managed switch. The switch handles tagging traffic from your end devices (like a camera on VLAN 40) before sending it "up the stick" to OPNsense. OPNsense applies your firewall rules to this tagged traffic - blocking or allowing it—and then sends it right back down the same cable to the switch to be routed to its final destination, whether that's another VLAN or out to the internet.

  • You can set up a LAGG under Interfaces->Devices->LAGG
    • Step 1: Hit the + to create a new LAGG, and select your parent interfaces you want to be part of it.
    • Step 2: Select the protocol, you want LACP!
Screenshot of OPNsense LAGG configuration showing 2 Intel interfaces selected, ign1 and ign2.
OPNsense LAGG interface config
    • Decide on your hash layer of choice. This is important and will have to be compatible with the switch you are up-linking too. If you're not sure, you can leave "nothing" and leave it completely to the switch.

If you will connect all your VLANs to your network via this method, expand this toggle and read it. If you will use separate interfaces off OPNsense for each LAN you created (VLAN), skip it!

🚨 CRITICAL WARNING: RISK OF LOCKOUT 🚨

This is the single most common place where users lock themselves out of their firewall. Read this section twice before changing any settings.

The Multi-Port Safety Net If you have a quad-port Intel NIC, manage OPNsense from igb0 (the default) while selecting igb1 and igb2 as members. Test uplinking to the switch until everything is working just right before making final changes.

Understanding the Lockout Risk

You are currently accessing your OPNsense GUI using your LAN interface (e.g., at 10.10.1.1). This traffic resides on your default, untagged network (often called VLAN 1), while the new VLANs you just created (IOT, CAMERAS, etc.) send tagged traffic.

You are about to configure the same physical port on your managed switch to accept both untagged LAN traffic and tagged VLAN traffic:

  • The Risk: If you configure the switch port incorrectly (such as forgetting to allow untagged VLAN 1 or setting the wrong Native VLAN), the switch will immediately stop passing LAN traffic, disconnecting and locking you out of your OPNsense GUI.
  • Recovery: The only way to recover is to plug a computer directly into a different OPNsense port (if available) or connect via the console port to revert your settings.

What You've Accomplished Thus Far

What you've built is a classic router-on-a-stick. Your single physical LAN port on OPNsense now acts as a "trunk" that carries multiple networks:

  • Sends untagged traffic for your main LAN (VLAN 1).
  • Sends tagged traffic for MANAGEMENT (VLAN 10), GUEST (VLAN 20), IOT (VLAN 30), etc.

You don't actually configure a "trunk port" inside OPNsense—you've already done the underlying work:

  1. Created VLANs (Tags 10, 20, 30...) and assigned their Parent to your physical LAN interface.
  2. Assigned those VLANs to new interfaces (MANAGEMENT, GUEST, IOT).

By completing these steps, OPNsense is now sending tagged traffic out of the physical LAN port. The firewall side is complete; the rest of the configuration happens on your switch.

The Managed Switch Side (The Real Work)

Log in to your managed switch (UniFi, TP-Link Omada, Netgear, etc.). Terminology varies by vendor, but the steps remain identical:

  1. Navigate to Switch Port Settings: Find the list of physical ports on your switch.
  2. Identify the Trunk Port: Select the single port where your OPNsense LAN interface is connected.
  3. Edit the Port Profile: Change the mode from a simple "Access" port to a "Trunk" port.
  4. Configure VLANs on the Port:
    • Native VLAN (PVID / Untagged VLAN): Set this to your main LAN's VLAN ID (VLAN 1 by default). This tells the switch that untagged traffic (like your OPNsense GUI connection) belongs to VLAN 1. This step prevents lockouts.
    • Tagged VLANs (Allowed / Trunked VLANs): Add all newly created tagged VLANs (10, 20, 30, 40, 50) to the allowed list for this port.
  5. Save and Apply: Commit the changes to your switch.

Vendor Configuration Examples

UniFi Switch

  • Port Profile: Edit the port and set:
    • Native VLAN: LAN (1)
    • Tagged VLANs: MANAGEMENT (10), GUEST (20), IOT (30), CAMERAS (40), DMZ (50)

TP-Link Omada Switch

  • Port Profile Type: All (or Custom)
    • Native Network: LAN (1)
    • Tagged Networks: Select the checkboxes for MANAGEMENT (10), GUEST (20), IOT (30), CAMERAS (40), DMZ (50)

After applying these switch settings, your "router-on-a-stick" connection is complete. Your untagged LAN traffic will continue to function normally, and your switch will route tagged traffic for your remaining VLANs to and from OPNsense.


Part 2: Rule Engine Fundamentals & Aliases Strategy

Understanding Packet Direction: In vs. Out

Before writing a single rule, get this one mental model right, it resolves most of the early confusion. We will use the "Invert Match" logic for a clean, fail-safe ruleset. If a setting is not explicitly specified below, that means leave it to "default". Example, Direction: In, is usually the default when creating a new rule.

In OPNsense, firewall rules are evaluated on the interface where traffic enters the firewall. "In" means traffic entering that interface; "Out" means traffic leaving it. The direction is always relative to the interface itself, not some global sense of "coming from the internet" or "coming from your LAN."

Concretely: traffic arriving from the internet is WAN In. Traffic originating from an internal device is LAN In (or MANAGEMENT In, IoT In, and so on, for whichever interface it entered on). This is why almost every rule you'll write in this guide is filtered on the In direction of the interface closest to the traffic's source, not on some downstream "Out" interface.

Let's step this up a notch... Enforce a digital "moat". We do this by subscribing to IP blocklists using Aliases. An Alias is just a dynamic list of IPs that OPNsense can automatically update.

To keep your firewall configuration scalable and easy to audit, never write rules using raw IP addresses or individual port numbers. Always wrap your assets into Aliases.

💥
A flat network is an insecure network. We will now use our OPNsense firewall to carve up our LAN into secure, isolated zones (VLANs).

🧱 Example 1: WAN ➡️ LAN (Incoming Connection)

flowchart LR
    subgraph INTERNET ["🌐 Internet (Untrusted)"]
        A["Remote Host (1.2.3.4)"]
    end

    subgraph OPNsense ["🧱 OPNsense Firewall"]
        B["WAN Interface"]
        C["Packet Filter"]
        D["LAN Interface"]
    end

    subgraph LAN ["🏠 Internal Network"]
        E["Home PC (192.168.7.10)"]
    end

    A -->|"Inbound packet to WAN"| B
    B -->|"WAN rules checked 🔍"| C
    C -->|"Allowed if passes (e.g. port forward + stateful rule)"| D
    D -->|"Forwarded to LAN"| E

    %% Blocklist example
    B -.->|"🧾 FireHOL Blocklist\n(Drops known bad IPs)"| C

🚀 Example 2: LAN ➡️ WAN (Outbound Connection)

flowchart LR
    subgraph LAN ["🏠 Internal Network"]
        A["Home PC (192.168.7.10)"]
    end

    subgraph OPNsense ["🧱 OPNsense Firewall"]
        B["LAN Interface"]
        C["Packet Filter"]
        D["WAN Interface (NAT out)"]
    end

    subgraph INTERNET ["🌐 Internet (Untrusted)"]
        E["Remote Server (1.2.3.4)"]
    end

    A -->|"Outbound packet (Inbound to Opn)\n(from LAN host)"| B
    B -->|"LAN rules checked 🔍"| C
    C -->|"Pass if allowed (default allow LAN→WAN)"| D
    D -->|"Translated via NAT"| E

    %% Blocklist example
    D -.->|"🧾 FireHOL Blocklist\n(Drops bad destinations)"| E

Why "Blocked by Default" Isn't the Whole Story🤯

Default Firewall Behavior on New VLANs

When you create new interfaces in OPNsense (such as GUEST, IOT, or CAMERAS), the firewall creates the interfaces but adds no Pass rules to them. Because OPNsense uses an implicit "Default Deny" security model:

  • WAN Traffic: Nothing from the internet can initiate connections into those VLANs.
  • Internal & Outbound Traffic: Devices on the new VLAN cannot reach anything - not the internet, and not other local subnets.

While inter-VLAN traffic is blocked by default, it is only because the new VLAN is completely isolated from sending any traffic at all. To make a VLAN usable, you must explicitly define allowed traffic paths.

The "Internet-Only" VLAN Challenge

Suppose you want to configure your GUEST VLAN (Tag 20) so that devices can reach the internet, but are strictly prevented from reaching your main LAN or other internal VLANs.

The "Lazy" Approach (Less Secure)

A common mistake is adding a simple "allow all" rule to the GUEST interface:

  • Action: Pass
  • Source: GUEST net
  • Destination: any

Why this is risky: Setting the destination to any permits internet access, but it also explicitly allows traffic destined for your internal subnets. While traffic might still get dropped by default deny rules on receiving interfaces, relying on this creates an unsafe security posture. If you later add an incoming rule on another interface, guest devices could suddenly gain access to internal hosts.

The "Correct" Approach (Inverted RFC1918 Rule)

To safely restrict a network to internet-only access, create a pass rule using an inverted destination targeting all private IPv4 space:

Action: Pass
Interface: GUEST
Source: GUEST net
Destination: !RFC1918 (Check "Invert destination" ✅)
Description: Allow Internet Access, Block Inter-VLAN

(Note: RFC1918 refers to an Alias containing the standard private IP ranges: 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16.)

Why This Rule Works

  • Allows Internet: Public internet IP addresses fall outside RFC1918 space. Because the destination rule is inverted (NOT RFC1918), outbound internet traffic matches the rule and is allowed.
  • Blocks Inter-VLAN Traffic: When a device on the GUEST network attempts to reach an internal IP (like 10.10.1.5), the destination is an RFC1918 address. The rule does not match, execution falls through to the bottom of the rule list, and the default deny rule drops the traffic.

You can read about the Direction right here, from the official docs:

Rules — OPNsense documentation

The Three Core Alias Types Every Lab Needs

Navigate to Firewall → Aliases and set up these foundational groups:

Alias Name Type Content / Subnets Purpose
RFC1918_Subnets Network 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 Matches all private local subnets. Essential for inter-VLAN isolation rules.
Reverse_Proxy_Ports Port 80, 443 Standard HTTP/HTTPS ports for ingress web services.
Local_DNS_Servers Host 192.168.1.1 (or local AdGuard/Pi-hole IPs) Target hosts for redirection and explicit access rules.
Rule Processing Order: Rules are evaluated from top to bottom, and the first matching rule wins. Floating rules take precedence over interface rules unless Quick processing is unchecked.

Create the RFC1918 Alias (The "Private" List)

This alias allows us to easily define "Internal Networks" in a single rule. This implements a "default-deny" stance between your internal networks (VLANs) and ensures only devices using valid private IP addresses from your network can initiate connections to the internet. This is incredibly efficient, effective and easy to implement! This will ensure each of your newly created VLANs is kept out of each other and secure. Your IoT devices even if they were breached, won't allow an attacker to now instantly pivot into your home LAN network!

  1. Navigate to Firewall -> Aliases.
  2. Click + (Add).
  3. Name: RFC1918_Networks
  4. Type: Network(s)
  5. Content:
    • 10.0.0.0/8
    • 172.16.0.0/12
    • 192.168.0.0/16
  6. Description: "All RFC1918 Private Network Ranges".
  7. Save.

Part 3: Typical Firewall Flows & NATs Needed in a Homelab

A well-architected firewall setup relies on four primary traffic patterns. This is what gets you operating with a proper functioning and secure homelab. Part 3 below, are advanced rulesets that lock things down even further.

flowchart TD
    subgraph F1[1. Ingress Flow]
        direction LR
        WAN1[WAN] -->|Port Forward / Tunnel| RP[Reverse Proxy]
    end
    subgraph F2[2. Inter-VLAN Flow]
        direction LR
        MGMT1[MANAGEMENT] -->|Admin Initiated| IOT1[IoT Subnet]
    end
    subgraph F3[3. Egress Flow]
        direction LR
        LAN1[LAN] -->|Policy Route| VPN1[VPN Gateway]
    end
    subgraph F4[4. DNS Redirect Flow]
        direction LR
        IOT2[IoT] -->|Force UDP 53 to Unbound| DNS1[Local DNS]
    end

    classDef flow fill:#001a12,stroke:#00ff88,color:#00ff88,stroke-width:2px
    class WAN1,RP,MGMT1,IOT1,LAN1,VPN1,IOT2,DNS1 flow

Navigate to Firewall->Rules. You’ll notice a clean grid-based view. This isn't just a coat of paint compare to older versions of OPN; it’s an API-driven system that allows for much faster rule processing and easier searching.

You need to repeat rules creation or clone the rules on the rules tab for each of your internal interfaces (LAN, IOT, CAMERAS, etc.).

Flow Set 1: Inter-VLAN Isolation (LAN to LAN, or not)

The goal of VLAN segmentation is preventing untrusted subnets (like IoT or Guest networks) from initiating connections into sensitive administrative networks (LAN / MANAGEMENT). We'll configure your OPNsense to do this by default.

The Stateful Rule Matrix

Source Interface Action Source Port Destination Port Description
MANAGEMENT / LAN Pass MANAGEMENT net * IoT net * Allow Admin to initiate access into IoT network.
IoT Pass IoT net * Local_DNS_Servers 53 Allow IoT to query designated local DNS servers only.
IoT Block IoT net * RFC1918_Subnets * Block all IoT access to other internal private subnets.
IoT Pass IoT net * * * Allow IoT general outbound internet access.
Why Stateful Filtering Matters: Because OPNsense tracks connection states, your admin PC on MANAGEMENT can open a web interface on an IoT device. The firewall remembers the request and allows the response back through automatically, even though IoT is explicitly blocked from reaching MANAGEMENT!

What MGMT actually needs, at minimum: beyond the admin-initiated access above, your MANAGEMENT interface itself needs a handful of baseline allow rules to function: outbound DNS (to your resolver), outbound NTP (time sync, package signature verification depends on accurate clocks), and outbound HTTPS (firmware/plugin updates). Everything else inbound to MANAGEMENT should stay denied by default, this is the one VLAN where the default-deny posture matters most.

Go to Firewall -> Rules[new] -> Top drop down to your LAN.

  1. Allow Inter-VLAN Access (Specific Holes):
    • If you need LAN to reach IOT, add that HERE, above the internet rule.
    • Action: Pass | Source: LAN net | Destination: IOT net
  2. Allow Internet (Default Deny Internal to internal):
    • Action: Pass
    • Source: LAN net
    • Destination: RFC1918_Networks
    • Invert Match: CHECK THIS BOX (!).
      • Note: In the new GUI, the "Invert" checkbox is more clearly labelled. This rule tells OPNsense: "If the traffic is NOT headed for my private internal networks, let it go to the internet."
    • Description: "Allow LAN to Internet (Block Inter-VLAN)"
    • Note: This single rule allows you to access Google, but blocks you from accidentally accessing the DMZ or Guest network unless you explicitly allowed it in rule #2.

GUEST / IOT / DMZ Inter-VLAN Rules (Untrusted - Internet Only)

Go to Firewall -> Rules[new] -> GUEST. We only need ONE rule here!

  1. Allow Internet (Block Internal):
    • Action: Pass
    • Direction: IN
    • Source: GUEST net
    • Destination: RFC1918_Networks
    • Invert Match: CHECK THIS BOX (!).
    • Description: "Allow GUEST to Internet (Block Inter-VLAN)"

You can leave IPV6 out if not using or enabling it.

Repeat this exact rule for the IOT and DMZ interfaces. At the end you'll have created a rule like this for each VLAN you have created looking like this:

The critical checkbox. Ensuring "Invert" is checked transforms this rule from "Allow traffic TO private networks" (Bad!) into "Allow traffic TO anything that is NOT a private network" (Good!).
OPNsense firewall rule edit screen highlighting the Destination Invert checkbox enabled for the RFC_1918_LANs alias.

CAMERAS/IOT Rule (Isolated - No Internet)

Go to Firewall -> Rules -> CAMERAS.

  1. Block Everything:
    • Action: Block
    • Source: CAMERAS net
    • Destination: any
    • Description: "Block all traffic from CAMERAS"
      • If you want to allow them out to the internet but NOT to any of your LANs, make the rule similar to step 5.2!

Flow Set 2: Ingress Flows (Port Forwarding to a Reverse Proxy)

Exposing internal lab services (e.g., Home Assistant, Jellyfin) to the internet can be handled via traditional Port Forwarding to your reverse proxy, or Zero-Trust Tunnels.

flowchart TD
    NET[Public Internet]
    WAN["OPNsense WAN IP"]
    RP["Reverse Proxy<br/>Nginx / NPM"]
    SVCA[Service A]
    SVCB[Service B]

    NET --> WAN
    WAN -->|Port Forward: 80, 443| RP
    RP --> SVCA
    RP --> SVCB

    classDef edge fill:#000000,stroke:#00ff88,color:#00ff88,stroke-width:2px
    classDef firewall fill:#001a12,stroke:#00ff88,color:#00ff88,stroke-width:3px
    classDef core fill:#001f1a,stroke:#00ffaa,color:#00ffaa,stroke-width:2px
    classDef vlan fill:#0a0a0a,stroke:#666,color:#999,stroke-dasharray: 3 3
    class NET edge
    class WAN firewall
    class RP core
    class SVCA,SVCB vlan

Setting Up a Safe Ingress Port Forward

  1. Navigate to Firewall → NAT → Destination NAT.
  2. Add a new rule:
    • Interface: WAN
    • TCP/IP Version: IPv4
    • Protocol: TCP
    • Destination: WAN address
    • Destination Port Range: Reverse_Proxy_Ports (Alias)
    • Redirect Target IP: 192.168.20.10 (Your Reverse Proxy Host)
    • Redirect Target Port: HTTP or HTTPS
    • Filter Rule Association: Register Rule for simplicity, or Manual and you go make the associated rule on the proper interface 'manually'. This ensures you go to the interface your reverse proxy lives in, and create a rule allowing WAN to -> Reverse proxy on port 443 say. It'll feel like a bit of duplication at first, but it's all about granular control & rule processing order.
Where does the "associated" rule land relative to my WAN blocklists? Choosing Register Rule (rather than writing the WAN allow rule by hand) inserts it at the position of the NAT entry itself, which is evaluated in the same top-to-bottom pass as your manually-written rules. If you're layering in static WAN blocklists (see Part 3's blocklist section below), keep the blocklist Block rule above this associated rule so a blocklisted source gets denied before it ever reaches your port-forward, not after!
Deep Dive Available: For exposed services where port lockdown and HTTP header analysis are required, consult our companion guide: Perimeter Hardening & Security Through Obscurity →

Flow Set 3: Egress & Source NAT Mechanics

By default, OPNsense operates in Automatic Outbound NAT mode, which creates translate rules for all internal subnets out the WAN interface.

Hybrid Source (Outbound) NAT vs. Automatic Mode

To route specific subnet traffic through an encrypted VPN gateway (such as WireGuard or AirVPN) or apply custom translation IPs, switch to Hybrid Outbound NAT:

  1. Navigate to Firewall → NAT → Source NAT.
  2. Select Hybrid Outbound NAT rule generation and click Save.
  3. Add a high-priority rule above the automatic entries to policy-route traffic:
    • Interface: VPN_GATEWAY
    • Source: IoT_Subnet
    • Translation / target: Interface Address

This simply allows the system to (still) create automatic NAT rules, and you to make custom ones. This is how I've run OPN for a long time.

Flow Set 4: Local DNS Redirection (The "No Rogue DNS" Flow)

Smart home devices and TVs often ignore local DHCP DNS options and use hardcoded public DNS servers (like 8.8.8.8 or 1.1.1.1) over port 53 or 853. You can forcefully capture and redirect this traffic back to your local DNS infrastructure.

flowchart LR
    DEV["IoT Device<br/>Hardcoded 8.8.8.8:53"]
    NAT["OPNsense NAT<br/>Catch Rule"]
    DNS[Local Unbound DNS]

    DEV --> NAT --> DNS

    classDef vlan fill:#0a0a0a,stroke:#666,color:#999,stroke-dasharray: 3 3
    classDef firewall fill:#001a12,stroke:#00ff88,color:#00ff88,stroke-width:3px
    classDef core fill:#001f1a,stroke:#00ffaa,color:#00ffaa,stroke-width:2px
    class DEV vlan
    class NAT firewall
    class DNS core

Implementing the DNS Intercept Rule

  1. Navigate to Firewall → NAT → Destination NAT.
  2. Add a new capture rule:
    • Interface: LAN / IoT (Select all local user subnets)
    • Protocol: TCP/UDP
    • Source: ANY
    • Destination: NOT Local_DNS_Servers (Invert Destination check box)
    • Destination Port Range: 53 (DNS)
    • Redirect Target IP: 127.0.0.1 (or local Pi-hole/AdGuard IP)
    • Redirect Target Port: 53

Additional Common Homelab/Selfhosted Firewall Rules

Now that we have established a "Default Deny" posture between our VLANs, you will inevitably find something that breaks. You might need your Plex server to talk to your Apple TV, or your Home Assistant instance to talk to a smart plug.

Cross-VLAN Smart Device Control (LAN vs. IoT)

When inter-VLAN traffic is blocked by default, managing smart home devices (like Meross lights, Google Nest, or smart TVs) from a primary phone or computer on the LAN interface relies on one of two communication models:

Method 1: Cloud-Based Control (Works Automatically)

Most commercial smart home ecosystems (Google Home, Amazon Alexa, Meross, Tuya, Smart Life) utilize external cloud infrastructure by default.

[Phone on LAN] ---> (Outbound HTTPS) ---> [ Cloud Service ]
|
[IoT Device] <--- (Inbound Outbound) <-- [ Firewall WAN ]

  • How it works: The control app on your phone sends commands out to the manufacturer's internet cloud servers. The cloud then relays those instructions down through your firewall's WAN to the device on the IoT VLAN.
  • Why it bypasses the block: Communication never attempts to cross directly from LAN -> IoT internally. Because both networks are allowed outbound access to the internet, no special inter-VLAN rules are required for cloud-based control to function.

Method 2: Local Network Control (Requires Specific Configuration)

Protocols that discover or control hardware locally (such as Apple HomeKit, Matter over Thread/Wi-Fi, Chromecast, or local API tools) bypass cloud relays entirely.

  • The Problem: Local discovery relies on layer-2 broadcast/multicast protocols like mDNS (UDP 5353 / Bonjour) or SSDP (UDP 1900 / UPnP). Multicast packets do not naturally cross subnet boundaries, and your default-deny policy will block direct unicast control traffic.
  • The Result: Local discovery fails, and apps report devices as "Offline" even when connected.

Solution: Enabling Local Cross-VLAN Control

To allow local discovery and control without opening your entire primary network to IoT risks:

1. Implement Multicast/Broadcast Helpers

Install an mDNS proxy or repeater plugin in OPNsense to reflect discovery packets across subnets:

  • os-mdns-repeater: Relays Multicast DNS (UDP 5353) queries and responses between selected interfaces.
  • os-udpbroadcastrelay: Handles custom ports (e.g., SSDP on UDP 1900 for Sonos/Roku, or non-standard discovery tools).

2. Create Targeted LAN Pass Rules

Add specific pass rules on the originating interface (LAN) allowing control traffic to the destination (IoT VLAN or specific IP addresses):

Action: Pass
Interface: LAN
Protocol: TCP/UDP
Source: LAN net (or specific Phone IP)
Destination: IoT net (or specific Smart Device IP)
Port: [Required Control Ports, e.g., 80, 443, 8000, 8080, 5353]
Description: Allow LAN Controller to IoT Device

Troubleshooting Tip: If local control fails, inspect firewall drops in real-time under Firewall -> Log Files -> Live View. Filter by your phone's IP address to quickly identify blocked destination ports and create the precise pass rules needed.

Here are the three most common "Allow" rules you will create. Crucially, these must be placed at the TOP of your rule list, above the !RFC1918 Internet rule!

Scenario A: The "God Mode" Rule (1 IP to Whole Subnet) Use Case: You want your personal Desktop PC to be able to access ANY device on the IoT network (to configure them).

  • Action: Pass
  • Interface: LAN
  • Source: Single Host or Network -> 10.10.1.50 (Your PC IP)
  • Destination: IOT net
  • Description: "Allow Admin PC to access all IOT devices"

Scenario B: The "Server to Server" Rule (1 IP to 1 IP) Use Case: Your Plex Server (on LAN) needs to talk to your NAS (on MANAGEMENT) for file storage.

  • Action: Pass
  • Interface: LAN
  • Source: Single Host or Network -> 10.10.1.10 (Plex IP)
  • Destination: Single Host or Network -> 10.10.10.5 (NAS IP)
  • Description: "Allow Plex to access NAS"

Scenario C: The "Surgical" Rule (1 IP to 1 IP on Specific Port) Use Case: Your Home Assistant (on LAN) needs to control a specific Smart Plug (on IoT) via MQTT (Port 1883), but shouldn't access anything else.

  • Action: Pass
  • Interface: LAN
  • Source: Single Host or Network -> 10.10.1.20 (Home Assistant IP)
  • Destination: Single Host or Network -> 10.10.30.55 (Smart Plug IP)
  • Destination Port Range: 1883 (from) to 1883 (to)
  • Description: "Allow HA to Smart Plug on MQTT"

Part 3: Static IP Reputation Blocklists (FireHOL & Spamhaus)

Before reaching for anything dynamic, the cheapest layer of defense is a static, community-maintained list of known-bad IP ranges. This won't catch anything novel (new), but it silently drops a large volume of automated scanning and known botnet traffic before it ever touches a firewall rule you had to think about.

Known conflict: this can silently break other apps/installs. A broad WAN blocklist can end up blocking IP ranges that belong to raw.githubusercontent.com or similar code-hosting CDNs. If you've deployed these blocklists and then a completely unrelated install, like SWAG's fail2ban or CrowdSec module fetch, fails partway through with no obvious network error, check whether your blocklists are the actual cause before assuming the other software is broken. Outbound-adjacent blocklists like this are powerful but can be overkill; scope them deliberately rather than enabling every list available.

Create Dynamic Blocklist Aliases

Navigate to Firewall -> Aliases. Click the + (Add) button for each one.

  1. FireHOL Level 1 (WAN Inbound ONLY):
    • Name: Blocklist_FireHOL_L1
    • Type: URL Table (IPs)
    • Refresh Freq.: 1 (Days)
    • Content: https://iplists.firehol.org/files/firehol_level1.netset
    • Description: "FireHOL L1 - Use for WAN INBOUND only. Contains bogons/private IPs."
    • Save.
Creating the FireHOL Level 1 alias. Note the warning in the description - this list contains private IPs and bogons, so it must NEVER be used on a LAN interface rule, or you'll block yourself!Creating the FireHOL Level 1 alias.
Creating the FireHOL Level 1 alias. Note the warning in the description - this list contains private IPs and bogons, so it must NEVER be used on a LAN interface rule, or you'll block yourself!Creating the FireHOL Level 1 alias.
  1. FireHOL Level 2 (Inbound & Outbound):
    • Name: Blocklist_FireHOL_L2
    • Type: URL Table (IPs)
    • Refresh Freq.: 1 (Days)
    • Content: https://iplists.firehol.org/files/firehol_level2.netset
    • Description: "FireHOL L2 - Safe for WAN IN and LAN OUT."
    • Save.
  2. FireHOL Level 3 (Inbound & Outbound):
    • Name: Blocklist_FireHOL_L3
    • Type: URL Table (IPs)
    • Refresh Freq.: 1 (Days)
    • Content: https://iplists.firehol.org/files/firehol_level3.netset
    • Description: "FireHOL L3 - Safe for WAN IN and LAN OUT."
    • Save.
🤔
Why Spamhaus and FireHol lists? I personally noticed that although there's much crossover of IPs & ranges, some slip through FireHol and are caught by SpamHuas!
  1. Spamhaus+Others DROP (WAN & LAN):
    • Name: Blocklist_Spamhaus or BL_KnownBaddies
    • Type: URL Table (IPs)
    • Refresh Freq.: 4 (Hours, do it at least once every 24hrs)
    • Content: https://www.spamhaus.org/drop/drop.txt
      • OPTIONAL - I have a pile more as well that I added, as shown below.
    • Description: "Spamhaus DROP List - Safe for WAN IN and LAN IN."
    • Save.
https://www.spamhaus.org/drop/drop.txt
http://cinsscore.com/list/ci-badguys.txt
http://lists.blocklist.de/lists/all.txt
https://feodotracker.abuse.ch/downloads/ipblocklist_aggressive.txt
https://www.binarydefense.com/banlist.txt
https://raw.githubusercontent.com/stamparm/ipsum/master/ipsum.txt
http://blocklist.greensnow.co/greensnow.txt
https://www.stopforumspam.com/downloads/toxic_ip_cidr.txt
https://reputation.alienvault.com/reputation.generic

My list of baddies

OPNsense Alias Edit screen for BL_KnownBaddies showing URL Table type and multiple blocklist URLs like Spamhaus and CINS Score.
OPNsense Alias Edit screen for BL_KnownBaddies showing URL Table type and multiple blocklist URLs like Spamhaus and CINS Score

At the end you should have something like this:

Verify your ammo supply. Ensure your Aliases are populated with IPs (the numbers on the right) and that you've noted which ones are for WAN only versus LAN.
OPNsense Aliases list showing created blocklists FireHOL 1, 2, 3 and KnownBaddies with their IP entry counts and descriptions.

Part 4 - Floating Rules & Advanced Rulesets Utilizing Dyanmic Alias & Blocklists

Outbound Traffic Control

Why We Filter Outbound Traffic (Egress Filtering)

Earlier in this guide we created aliases for block-lists. Now, let's create more robust and maintainable outbound block rules using the Floating rules feature & tab. This prevents potentially compromised devices on any of your internal networks from "phoning home" to known malicious servers. We'll start by grouping our internal interfaces together.

💥
Remember the Rules Processing Order: Floating Rules are processed BEFORE individual interface / LAN rules!

Basically, floating rules apply across interfaces, or alias groups of interfaces. An example would be making an alias of your internal LANs and making a rule allowing all of those LANs to reach your Adguard/PiHole server for DNS.

You can achieve this across all your interfaces or an interface group as a floating rule, if you like, but uncheck "quick match" if you do. It is very important that you uncheck "Quick". This means that your floating rules allow your VLAN-to-WAN rules to take processing/order precedence and will be processed after all your other "quick" rules, by default.

Since OPNsense allows all traffic to leave the firewall by default (outbound over WAN) this makes sense to move rules from each interface such as LAN/IOT/CAMs etc, to a floating outbound rule.

Rules — OPNsense documentation

Verify Your Aliases

Go to Firewall -> Aliases. Ensure you have the aliases created for lists like:

  • Blocklist_FireHOL_L2
  • Blocklist_FireHOL_L3
  • Blocklist_Spamhaus / BL_KnownBaddies
  • (And any others from the list in our previous discussion, like CINS Army, Feodo, etc.)
  • Crucially, ensure Blocklist_FireHOL_L1 is present but will NOT be used in this OUTBOUND rule.
  • Ensure there's a count on the alias page showing that these lists have items and are being updated. If you set them to update every 4 hrs per part 1 (scroll way up!) the date should be recent (today!).

Creating Interface Groups for Granular Control

Grouping your internal interfaces (LAN, IOT, Cameras, etc.) allows you to apply rules to all of them at once, simplifying management.

  1. Navigate to Interfaces -> Groups.
  2. Click the + (Add) button in the top right.
  3. Group Name: Give it a descriptive name, like Internal_Networks or LAN_Group. (Avoid spaces and special characters). I called mine My_Nets
  4. Group Members: In the "Available members" list on the left, select all your internal network interfaces (e.g., LAN, IOT, CAMERAS, GUEST). Do NOT select WAN or Loopback. What's nice is you can always go back and add more VLANs/interfaces here as you grow your homelab!
  5. Click the > arrow to move the selected interfaces into the "Members" box on the right.
  6. Description: Add a helpful description, like "Group containing all trusted internal LANs and VLANs".
  7. Save.

Implementing Floating Block Rules

Now, we'll apply our blocklists to this group. Here's mine for reference:

  1. Navigate to Firewall -> Rules -> Floating.
  2. Click + (Add) or find and edit your existing outbound block rule.
  3. Action: Block
  4. Quick: Check this box (essential for Floating rules to ensure immediate action).
  5. Interface: Click in the field and select your newly created interface group (e.g., Internal_Networks).
  6. Direction: out
  7. Protocol: any
  8. Source: any (meaning any device on the interfaces within the selected group).
  9. Destination: Click in the field. Start typing and add all your blocklist aliases EXCEPT Blocklist_FireHOL_L1❗ (e.g., Blocklist_FireHOL_L2, Blocklist_FireHOL_L3, Blocklist_Spamhaus, CINS Army, etc.).
  10. Log: Check this box to see what's being blocked.
  11. Description: "Block outbound traffic from Internal_Networks group to known malicious IPs (Excl. L1)".
  12. Save.
  13. Apply Changes.
📡
Reminder - Rule Order & Effect: Floating rules are processed before interface-specific rules.

Because we checked Quick, if traffic matches this rule (outbound from any interface in your Internal_Networks group to a bad IP), it will be blocked immediately. This rule now neatly applies to all your internal segments without needing to list each one individually. If you add a new internal VLAN later, just add it to the Interface Group, and this rule will automatically cover it!

References: OPNsense official docs & steps on outbound block rules.

Configure Spamhaus DROP — OPNsense documentation

Advanced Inbound Traffic Control (LAN Blocking)

This rule is explicitly defined so you're extra careful. This prevents things in your network from 'dialing home'. Scenario, your kid invites a friend over after school and they bring their tablet or laptop to play with yours. Cool, you hook them up and voila - they have internet AND - their device is infected with malware, dialed home to a botnet C & C server and is downloading a crypto-locker worm to encrypt all the devices it can find on your network! 🤯 You won't have joined them to your internal private LAN anyway right? Because you made a GUEST vlan right?

🎯
But just in case... ☔ Gotta prepare for when the rain comes!
  1. The INBOUND Block Rule (LAN Interface):
    • Go to Firewall -> Rules -> LAN.
    • Click + (Add).
    • Action: Block
    • Quick: Check this box.
    • Interface: LAN
    • Direction: in
    • Protocol: any
    • Source: any
    • Destination: Click in the field, start typing, and select each of these aliases one by one:
      • ⚠️DO NOT add FireHol1 here‼️😨 Notice it's MISSING from the list below (on purpose!)
      • Blocklist_FireHOL_L2
      • Blocklist_FireHOL_L3
      • Blocklist_Spamhaus/BL_KnownBaddies
    • Log: Check this box.
    • Description: "Block internal clients from phoning home to bad IPs"
    • Save.
  2. Apply Changes & Re-order: A new rule on the LAN interface may require you to move it. On the LAN rules tab, this new Block rule must be ABOVE the default "Allow LAN to !RFC_1918" rule. Use the arrow buttons to re-order your rules so it looks like this:
    1. Block internal clients from phoning home...
    2. Default allow LAN to !RFC_1918_LANs rule

Every time you add a new blocklist or deny traffic rule, you'll want to keep adding it above your allow rules for the blocks to function.

Additional Warning: This might be overkill for you and may require tweaks. When I first started using it, it was blocking Github entirely. This is because a lot of attacks / bots / script kiddies make web calls to Github and 'abuse' their system, so IP addressing from them gets placed on 'naughty' lists frequently. I temp disabled the rule while I did my Github work.

WAN Overkill Block Rules

Go to Firewall -> Rules -> WAN. 🏹You want these rules at the TOP of your WAN ruleset and it would look something like:

I kept mine in separate rules so I could log them separately but you can totally put them in one.

⁉️
Why would we use this if by default, OPNsense blocks all inbound traffic otherwise not explicitly allowed?
  1. Because if you publicly expose services with a reverse proxy, to say, host your own blog, maybe jellyseerr/overseerr, or anything you opened to the WAN, your firewall will let ANY IP IN to touch that and;
  2. To enhance visibility & insight into what is actually hitting you.
Default 'deny' rule will show you, but you won't know at a glance, if this is a known bad actor, a bot, or just random internet traffic otherwise. By making a clearly defined list & rule, you see when it's actually malicious traffic or not.

A critical warning: IP blocklists are not all the same. Using the wrong list on the wrong rule can block your entire network. We will use a safe, layered approach

  1. Block Known Bad IPs:
    • Action: Block
    • Quick: Checked.
    • Source: Blocklist_FireHOL_L1, Blocklist_FireHOL_L2, Blocklist_FireHOL_L3, Blocklist_Spamhaus, all other Blocklists
    • Direction: in
    • Destination: any
    • Description: "Block all known-bad IPs & bogons on WAN IN"
    • Log: Check this box.

What you should have now is a rule containing the block lists for everything on WAN, and all lists LESS FireHol1 on LAN.

TEST. 🧩Browse the internet, make sure things are functional. Often the trip up happens by incorrectly applying the BL's in the proper order, most importantly, FireHol level 1 blocking on WAN INBOUND ONLY! If you have issues, disable blocks on outbound and test again, troubleshoot from there.

If all goes well, you should see some good info like this (I removed Destinations to protect my WAN IP):

Victory in real-time. The Live Log view confirms that our new rules are actively dropping malicious traffic from the internet before it can probe our network.
OPNsense Firewall Live Log View showing blocked traffic on the WAN interface matching the FireHOL blocklists.

Visibility with Hostwatch & The New Dashboard

One of my favourite additions in the 26.1 release is Hostwatch (Interfaces -> Neighbors -> Automatic Discovery). This service sits silently in the background and maps out every device that touches your network!

  • Why it matters: It populates your New Dashboard widgets with real device names instead of just MAC addresses, giving you instant situational awareness if a new "Smart Bulb" suddenly starts talking to a server in Eastern Europe.

OPNsense Rule Best Practices

  1. Avoid Hairpin NAT (NAT Reflection): Instead of bouncing local traffic out to your WAN IP and back in through NAT reflection, use Split-Horizon DNS via Unbound or DNSMasq etc... Map your domain name (app.yourdomain.com) directly to the local LAN IP of your reverse proxy inside local DNS overrides.
  2. Logically plan your rules: Ensure you do some "pre-thinking" of how your traffic flows and what you're trying to do with it. A good example is the inverse rule we created earlier, allowing traffic out to anything EXCEPT to other VLANs. Logically simple rules like this are very often easier for the firewall to process.
  3. Remember Rule Order: If you make some new rules and things aren't working the way you planned, review the rules order and what is processed first. Top to bottom, and floating rules first!

Clean Up Legacy DHCP Dependencies: Ensure your rules reflect modern host bindings if you have upgraded from ISC DHCP to Kea DHCP or DNSMasq DHCP.

Configuration Guide: Need help configuring modern dynamic leases? Read our Kea DHCP & Dnsmasq Upgrade Guide →

Result & Conclusion🎯:

Traffic between your VLANs is now blocked by default by the final rule on each interface. You must create specific Pass rules above it to allow necessary inter-VLAN communication.

  • Only traffic originating from devices within a specific VLAN's subnet (Source: <VLAN> net) is allowed to go out to the internet (Destination: not RFC1918_Networks).
  • This is a massive leap forward in your security posture!
  • Don't forget to configure your managed switch with those VLANs now! There's a small guide above in the Section 3, Step 3.4: "Router on a Stick" if you missed, it, expand the warning toggle.

Next Steps: Moving to Advanced Config & Threat Protection

With your foundational rules, inter-VLAN matrices, and NAT flows successfully operating, your core network traffic is well structured. Next, step up your defence-in-depth security posture.

Don't forget to check the OPNsense change logs before you patch 😉

💬 Report Success - Hell Yeah I Set this up!

🎉 Lab Task Complete!

Did you survive the configuration? Let the world know!


❓ Frequently Asked Questions (FAQ)

Why is traffic blocked by default between VLANs in OPNsense?

OPNsense operates on a default-deny policy for internal interfaces. You must explicitly create 'Pass' rules to allow traffic to flow between segmented networks like LAN and IoT.

What is a Floating Rule in OPNsense?

A Floating Rule applies across multiple interfaces simultaneously. It is highly useful for applying global policies, such as blocking outbound traffic to malicious IPs across all internal VLANs.

How does Port Forwarding work with WAN rules?

When creating a NAT Port Forward in OPNsense, selecting 'Add associated filter rule' automatically generates the required WAN pass rule to allow the inbound traffic.

How many VLANs do I actually need for a homelab firewall?

It depends on how much you want to segment your traffic, but a common practical baseline separates trusted devices (LAN), untrusted/IoT devices, guest access, and cameras into their own VLANs at minimum — each with its own firewall rule set so a compromise in one segment can't freely reach the others.

What's the "Router on a Stick" trunk port setup?

It's a configuration where a single physical interface on your firewall carries multiple VLANs' traffic simultaneously, tagged appropriately, rather than dedicating one physical port per VLAN. It's the standard way to extend VLAN segmentation to a managed switch without running a cable for every network segment.

Why do the firewall rules need to be configured per-VLAN interface?

Because OPNsense evaluates rules per-interface, not globally - a rule on your LAN interface has no effect on traffic entering through your GUEST or IOT interface. Configuring rules individually per VLAN (LAN trusted, GUEST/IOT/DMZ untrusted-internet-only, CAMERAS fully isolated) is what actually enforces the segmentation you set up.

What are IP blocklist aliases used for in OPNsense?

Aliases (like the RFC1918 "private" list or dynamically updated public blocklists) let you group IP ranges or known-bad addresses into a single reusable object, then reference that one alias across multiple firewall rules, instead of manually retyping IP ranges everywhere, and making it easy to update the whole blocklist in one place later.

Written by

Core Lab Joe
Core Lab Joe
Dad, IT guy, Self-Hosting Evangelist! https://www.reddit.com/r/corelabtech/
corelab.tech
Facebook
Mastodon

On this page

What's Next?