Firewall sanity check

Hey everyone!

I bought this hardware months ago and was slowly setting things up at my desk without WAN while I was working. I was recently laid off, so I figured now was the best time to get everything setup and minimize downtime while my wife is working in the office. Ran into a bunch of silly issues trying to figure out the VLAN setup and the configuration on the switches. At this point I’ve wiped and started again multiple times and I could really do with another pair of eyes to see where I’ve made mistakes and gaps in my knowledge.

  1. Router (R) = GL.iNet GL-MT6000 (Flint 2), OpenWrt 25.12.1, 10.1.10.1
  2. Office switch = CRS310-8G+2S+, MikroTik SwOS 2.18, 10.1.10.2
  3. Living room switch = CSS610-8G-2S+, MikroTik SwOS Lite 2.21, 10.1.10.3

Here is a basic network diagram I made last week, it might be a little out of date, but it gets the general idea across

The goal is to have these VLANs configured:

  • Management: Used for router/switches
  • IoT: TV, Speakers, Hue Hub etc, untrusted devices
  • Guest: Guest Wifi, untrusted devices
  • Main: My computer, iPads/iPhones on wireless, trusted devices
  • Servers: I run services off an old Mac Mini running Proxmox, slowly moving everything to a newer Arch Linux server

My logic is…

  • IoT = devices should be able to access internet for software/firmware updates, but it shouldn’t be able to access my trusted devices, BUT I should be able to control the IoT devices from my Main or Server VLAN (turn lights on and off, play music from phone on speakers)
  • Guest = Access to the internet, can’t access anything on my network
  • Management = Should only be accessible from Main or Server VLAN
  • Main = I should be able to access anything without restriction, SSH into servers or networking equipment
  • Server = Similar to Main, I just wanted different IP ranges from Main

On the servers I run a few services with specific ports, for example Karakeep is a bookmarking app that I run in a Debian VM via Docker and I use the address 10.1.50.177:3000/dashboard/bookmarks to access it, this appears to be working. I have another container with 10.1.50.177:9091/transmission/web/ that I use for downloading ISOs :shushing_face: and I can’t seem to access that right now. I am assuming this is because I don’t have that specific port open on the firewall.

Honestly the end goal is to deprecate the Mac Mini Server and move to the Arch server, but I am sure I’ll run into the same problems and need to understand the networking as much as possible.

Can anyone please review my outputs and let me know if I am heading down the right track or if I am doing this all completely wrong?

I have been doing most of my setup via LuCi, so I might need a little hand holding if I need to make changes via CLI or help guiding me in LuCi.

root@OpenWrt:/etc/config# ubus call system board
{
"kernel": "6.12.74",
"hostname": "OpenWrt",
"system": "ARMv8 Processor rev 4",
"model": "GL.iNet GL-MT6000",
"board_name": "glinet,gl-mt6000",
"rootfs_type": "squashfs",
"release": {
"distribution": "OpenWrt",
"version": "25.12.1",
"firmware_url": "https://downloads.openwrt.org/",
"revision": "r32768-b21cfa8f8c",
"target": "mediatek/filogic",
"description": "OpenWrt 25.12.1 r32768-b21cfa8f8c",
"builddate": "1773711117"
}
}
root@OpenWrt:/etc/config# cat /etc/config/network

config interface 'loopback'
option device 'lo'
option proto 'static'
list ipaddr '127.0.0.1/8'

config globals 'globals'
option dhcp_default_duid '000478810932aadd495caa5e27da41ef45ca'
option ula_prefix 'fd85:3d2e:4447::/48'
option packet_steering '1'

config device
option name 'br-lan'
option type 'bridge'
list ports 'lan1'
list ports 'lan2'
list ports 'lan5'

config interface 'lan'
option device 'br-lan.10'
option proto 'static'
option ip6assign '60'
option multipath 'off'
list ipaddr '10.1.10.1/24'

config interface 'wan'
option device 'eth1'
option proto 'dhcp'

config interface 'wan6'
option device 'eth1'
option proto 'dhcpv6'

config bridge-vlan
option device 'br-lan'
option vlan '10'
list ports 'lan1:t'
list ports 'lan2:t'
list ports 'lan5:u*'

config bridge-vlan
option device 'br-lan'
option vlan '20'
list ports 'lan1:t'
list ports 'lan2:t'

config bridge-vlan
option device 'br-lan'
option vlan '30'
list ports 'lan1:t'
list ports 'lan2:t'

config bridge-vlan
option device 'br-lan'
option vlan '40'
list ports 'lan1:t'
list ports 'lan2:t'

config bridge-vlan
option device 'br-lan'
option vlan '50'
list ports 'lan1:t'
list ports 'lan2:t'

config interface 'IoT'
option proto 'static'
option device 'br-lan.20'
option ipaddr '10.1.20.1'
option netmask '255.255.255.0'
option multipath 'off'

config interface 'Guest'
option proto 'static'
option device 'br-lan.30'
option ipaddr '10.1.30.1'
option netmask '255.255.255.0'
option multipath 'off'
option type 'bridge'

config interface 'Main'
option proto 'static'
option device 'br-lan.40'
option ipaddr '10.1.40.1'
option netmask '255.255.255.0'
option multipath 'off'

config interface 'Servers'
option proto 'static'
option device 'br-lan.50'
option ipaddr '10.1.50.1'
option netmask '255.255.255.0'
option multipath 'off'

root@OpenWrt:/etc/config# cat /etc/config/wireless

config wifi-device 'radio0'
option type 'mac80211'
option path 'platform/soc/18000000.wifi'
option band '2g'
option channel '1'
option htmode 'HE20'
option country 'US'
option cell_density '0'

config wifi-iface 'default_radio0'
option device 'radio0'
option network 'lan'
option mode 'ap'
option ssid 'REDACTED 2.4GHz'
option encryption 'sae-mixed'
option key 'REDACTED'
option ocv '0'

config wifi-device 'radio1'
option type 'mac80211'
option path 'platform/soc/18000000.wifi+1'
option band '5g'
option channel '36'
option htmode 'HE80'
option country 'US'
option cell_density '0'

config wifi-iface 'default_radio1'
option device 'radio1'
option network 'lan'
option mode 'ap'
option ssid 'REDACTED 5GHz'
option encryption 'sae-mixed'
option key 'REDACTED'
option ocv '0'

config wifi-iface 'wifinet2'
option device 'radio1'
option mode 'ap'
option ssid 'REDACTED Guest'
option encryption 'sae-mixed'
option key 'REDACTED'
option ocv '0'
option network 'Guest'

config wifi-iface 'wifinet3'
option device 'radio0'
option mode 'ap'
option ssid 'REDACTED IoT'
option encryption 'sae-mixed'
option key 'REDACTED'
option ocv '0'
option network 'IoT'

root@OpenWrt:/etc/config# cat /etc/config/dhcp

config dnsmasq
option domainneeded '1'
option boguspriv '1'
option filterwin2k '0'
option localise_queries '1'
option rebind_protection '1'
option rebind_localhost '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option nonegcache '0'
option cachesize '1000'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
option nonwildcard '1'
option localservice '1'
option ednspacket_max '1232'
option filter_aaaa '0'
option filter_a '0'

config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'
option dhcpv6 'server'
option ra 'server'
list ra_flags 'managed-config'
list ra_flags 'other-config'
option ra_preference 'medium'

config dhcp 'wan'
option interface 'wan'
option ignore '1'

config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/odhcpd.leases'
option leasetrigger '/usr/sbin/odhcpd-update'
option loglevel '4'
option piodir '/tmp/odhcpd-piodir'
option hostsdir '/tmp/hosts'

config dhcp 'IoT'
option interface 'IoT'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'

config dhcp 'Guest'
option interface 'Guest'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'

config dhcp 'Main'
option interface 'Main'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'

config dhcp 'Servers'
option interface 'Servers'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'

root@OpenWrt:/etc/config# cat /etc/config/firewall

config defaults
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'REJECT'
option synflood_protect '1'

config zone
option name 'lan'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
list network 'lan'

config zone
option name 'wan'
list network 'wan'
list network 'wan6'
option input 'REJECT'
option output 'ACCEPT'
option forward 'DROP'
option masq '1'
option mtu_fix '1'

config forwarding
option src 'lan'
option dest 'wan'

config rule
option name 'Allow-DHCP-Renew'
option src 'wan'
option proto 'udp'
option dest_port '68'
option target 'ACCEPT'
option family 'ipv4'

config rule
option name 'Allow-Ping'
option src 'wan'
option proto 'icmp'
option icmp_type 'echo-request'
option family 'ipv4'
option target 'ACCEPT'

config rule
option name 'Allow-IGMP'
option src 'wan'
option proto 'igmp'
option family 'ipv4'
option target 'ACCEPT'

config rule
option name 'Allow-DHCPv6'
option src 'wan'
option proto 'udp'
option dest_port '546'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-MLD'
option src 'wan'
option proto 'icmp'
option src_ip 'fe80::/10'
list icmp_type '130/0'
list icmp_type '131/0'
list icmp_type '132/0'
list icmp_type '143/0'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-ICMPv6-Input'
option src 'wan'
option proto 'icmp'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
list icmp_type 'router-solicitation'
list icmp_type 'neighbour-solicitation'
list icmp_type 'router-advertisement'
list icmp_type 'neighbour-advertisement'
option limit '1000/sec'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-ICMPv6-Forward'
option src 'wan'
option dest '*'
option proto 'icmp'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
option limit '1000/sec'
option family 'ipv6'
option target 'ACCEPT'

config rule
option name 'Allow-IPSec-ESP'
option src 'wan'
option dest 'lan'
option proto 'esp'
option target 'ACCEPT'

config rule
option name 'Allow-ISAKMP'
option src 'wan'
option dest 'lan'
option dest_port '500'
option proto 'udp'
option target 'ACCEPT'

config zone
option name 'GuestZone'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'Guest'

config rule
option src 'GuestZone'
option name 'Guest DNS & DHCP'
option dest_port '53 67 68'
option target 'ACCEPT'

config rule
option src 'IoTZone'
option name 'IoT DNS & DHCP'
option dest_port '53 67 68'
option target 'ACCEPT'

config rule
option src 'IoTZone'
option name 'Main DNS & DHCP'
option dest_port '53 67 68'
option target 'ACCEPT'

config rule
option src 'IoTZone'
option name 'Servers DNS & DHCP'
option dest_port '53 67 68'
option target 'ACCEPT'

config forwarding
option src 'GuestZone'
option dest 'wan'

config zone
option name 'IoTZone'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'IoT'

config forwarding
option src 'IoTZone'
option dest 'wan'

config forwarding
option src 'lan'
option dest 'IoTZone'

config zone
option name 'MainZone'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
list network 'Main'

config forwarding
option src 'MainZone'
option dest 'IoTZone'

config forwarding
option src 'MainZone'
option dest 'lan'

config forwarding
option src 'MainZone'
option dest 'wan'

config forwarding
option src 'lan'
option dest 'MainZone'

config zone
option name 'ServersZone'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
list network 'Servers'

config forwarding
option src 'ServersZone'
option dest 'IoTZone'

config forwarding
option src 'ServersZone'
option dest 'lan'

config forwarding
option src 'ServersZone'
option dest 'MainZone'

config forwarding
option src 'ServersZone'
option dest 'wan'

config forwarding
option src 'lan'
option dest 'ServersZone'

config forwarding
option src 'MainZone'
option dest 'ServersZone'

Let me know if you need anything else

You're on the right track overall — your VLAN design and segmentation make sense :+1:

However, regarding this:

I can’t access 10.1.50.177:9091 and assume the port is blocked by the firewall

That’s most likely not the issue.

Since you already allow forwarding from Main → Servers, the router firewall should not be blocking that traffic. You typically do not need to open specific ports on the OpenWrt firewall for traffic between internal zones when forwarding is allowed.

The problem is more likely on the server side. A few things to check:

  • Make sure the container is actually exposing port 9091 (e.g. -p 9091:9091)

  • Verify the service is listening on 0.0.0.0:9091 and not just 127.0.0.1

  • Check if there is a firewall running inside the Debian VM (e.g. ufw or iptables)

  • Confirm that Transmission's web UI is enabled and bound to the correct port

Also, one important security note:

Your ServersZone is currently very permissive (input/forward ACCEPT and allowed to initiate connections to other zones). This is not recommended. Servers should generally not be able to initiate connections to Main, LAN, or IoT.

A better approach would be:

  • Allow Main → Servers

  • Block Servers → Main / LAN / IoT unless explicitly needed

This follows the principle of least privilege and reduces risk if a service is compromised.

So in short: your network design is good, but the issue with port 9091 is almost certainly on the container/VM side, not the OpenWrt firewall.

Why do you use SwOS on the MikroTik CRS310-8G+2S+ when it supports RouterOS ?

Hey @ncompact

This was super helpful

I couldn’t get on Proxmox VE because the gateway was set to the router and not the VLAN ip (i.e. 10.1.10.1 when it should be 10.1.50.1)

For the 9091 issue, I needed to change the docker compose to this
- LOCAL_NETWORK=10.1.0.0/16

As for the ServerZone Firewall rules… does this look closer to what you are suggesting?

I still want to be able to connect to the servers via SSH from Main so I can maintain them. I am also thinking about Plex and will this cause issues with communicating with an Apple TV that might be on Main?

root@OpenWrt:~# cat /etc/config/firewall

config defaults
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option synflood_protect '1'

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'lan'

config zone
        option name 'wan'
        list network 'wan'
        list network 'wan6'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'DROP'
        option masq '1'
        option mtu_fix '1'

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

config rule
        option name 'Allow-Ping'
        option src 'wan'
        option proto 'icmp'
        option icmp_type 'echo-request'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'

config zone
        option name 'GuestZone'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'Guest'

config rule
        option src 'GuestZone'
        option name 'Guest DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config rule
        option src 'IoTZone'
        option name 'IoT DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config rule
        option src 'IoTZone'
        option name 'Main DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config rule
        option src 'IoTZone'
        option name 'Servers DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config forwarding
        option src 'GuestZone'
        option dest 'wan'

config zone
        option name 'IoTZone'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'IoT'

config forwarding
        option src 'IoTZone'
        option dest 'wan'

config forwarding
        option src 'lan'
        option dest 'IoTZone'

config zone
        option name 'MainZone'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'Main'

config forwarding
        option src 'MainZone'
        option dest 'IoTZone'

config forwarding
        option src 'MainZone'
        option dest 'lan'

config forwarding
        option src 'MainZone'
        option dest 'wan'

config forwarding
        option src 'lan'
        option dest 'MainZone'

config zone
        option name 'ServersZone'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'Servers'

config forwarding
        option src 'ServersZone'
        option dest 'lan'

config forwarding
        option src 'ServersZone'
        option dest 'MainZone'

config forwarding
        option src 'ServersZone'
        option dest 'wan'

config forwarding
        option src 'MainZone'
        option dest 'ServersZone'

Hey @tomtom

I was trying to keep the configuration between the CSS610 and CRS310 as similar as possible, the CSS610 can’t run RouterOS.

I might use it in the future, but I couldn’t see the benefits right now while I was trying to get the network up and running.

You’re definitely moving in the right direction :+1:

However, your ServersZone is still more permissive than what I was suggesting. If your goal is proper segmentation and least-privilege, I would recommend tightening it a bit more.

A cleaner and safer approach would be:

  • input = REJECT

  • output = ACCEPT

  • forward = REJECT

This means:

  • The router itself won’t accept unsolicited connections from the Servers VLAN

  • Servers can still reach the internet (updates, downloads, etc.)

  • Servers cannot initiate connections to other internal networks


About DHCP / DNS / NTP

If your servers are not using static IPs, you should explicitly allow:

  • DHCP (ports 67/68)

  • DNS (port 53)

  • (optionally) NTP (port 123)

from ServersZone to the router (this zone).

Also, small note — I noticed this rule:

This looks like a copy/paste mistake. You already have a rule allowing DNS/DHCP for IoT, so this one is effectively redundant.

If your intention was to allow DNS/DHCP for the Servers VLAN, then src should be ServersZone. Otherwise, it can be safely removed to keep the configuration clean.


About SSH from Main → Servers

This will still work :white_check_mark:

Because you already have:

MainZone → ServersZone

Connection tracking allows the return traffic automatically, so you do not need to allow Servers → Main.


Important: Forwardings to remove

In my opinion, these should be removed:

config forwarding
    option src 'ServersZone'
    option dest 'lan'

config forwarding
    option src 'ServersZone'
    option dest 'MainZone'

In most setups, servers do not need to initiate connections toward user devices or management networks.

It’s usually the opposite:

clients (Main) → servers (SSH, web UI, Plex, etc.)

And that is already allowed in your config.


Summary:

  • Keep: Main → Servers

  • Remove: Servers → MainZone / lan

  • Lock down ServersZone (input + forward = REJECT)

  • Add DHCP/DNS/NTP rules if needed

This way, even if a server gets compromised, it won’t be able to move laterally across your network.

I don’t have a Plex server to test this 100%, so I can’t guarantee it with absolute certainty. However, since traffic from MainZone → ServersZone is already allowed in your firewall configuration, I don’t think you’ll need to open any additional ports internally for Plex to communicate with an Apple TV on the Main network.

For reference, Plex lists the ports it uses here: Plex Ports Documentation. Most of these are for remote access or discovery, which usually isn’t required for internal LAN communication.

So in your setup, the Apple TV on MainZone should be able to connect to Plex on ServersZone without changing the firewall rules.


If you want to keep the Plex server in ServersZone while the Apple TV is in MainZone, it should still work for normal streaming because MainZone → ServersZone traffic is already allowed.

The only limitation is automatic device discovery (Bonjour/mDNS, DLNA/SSDP), which typically uses UDP ports like 5353 (mDNS) and 1900 (SSDP), plus Plex discovery ports 32410–32414. These multicast protocols don’t cross VLANs/firewall by default.

If you notice that your Apple TV doesn’t automatically see the Plex server, you could add specific firewall rules to allow these ports from ServersZone → MainZone without opening everything. Otherwise, direct access via the Plex app using the server IP will work fine.


Optional Firewall Rules for Plex Discovery Across VLANs (Apple TV doesn’t automatically see the Plex server)

If automatic device discovery (Bonjour/mDNS, DLNA/SSDP) doesn’t work, you can add these rules:

# Allow mDNS (Apple TV discovery)
config rule
    option src 'ServersZone'
    option dest 'MainZone'
    option proto 'udp'
    option dest_port '5353'
    option target 'ACCEPT'
    option name 'Plex mDNS Discovery'

# Allow SSDP (DLNA discovery)
config rule
    option src 'ServersZone'
    option dest 'MainZone'
    option proto 'udp'
    option dest_port '1900'
    option target 'ACCEPT'
    option name 'Plex SSDP Discovery'

# Optional Plex discovery ports (32410–32414)
config rule
    option src 'ServersZone'
    option dest 'MainZone'
    option proto 'udp'
    option dest_port '32410-32414'
    option target 'ACCEPT'
    option name 'Plex Discovery Ports'

Notes:

  • These rules are only needed for automatic discovery. Regular streaming via the Plex app using the server IP works without them.

  • Keep ServersZone → MainZone forwarding blocked otherwise for security.

I noticed these three rules in your firewall configuration:

From the way they are written, it looks like there might have been a copy/paste or configuration mistake. All three rules have src 'IoTZone' but the names suggest they are intended for different zones (IoT, Main, Servers).

Most likely, the only rule that should exist for IoTZone is the one allowing DNS/DHCP for IoT itself. The other two rules probably don’t do what you intended, and could be removed or corrected to reference the proper source zone (MainZone or ServersZone) if needed.

Cleaning these up will make your firewall configuration clearer and avoid any unexpected behavior.

Thanks @ncompact

I followed your advice regarding the ServersZone and I think we’re good outside of a few hiccups I am seeing, would love your input.

I have Ollama running on my primary Mac that is on .40 Main. I also currently host Open WebUI on the old Mac Mini server (10.1.50.99) and noticed it can no longer see the Ollama models.

Would I need to add a similar rule as the Plex ones you suggested?

`http://10.1.40.227:11434`

Thinking about my network diagram and the rest of my IoT devices…

  • Apple TV ethernet keep on Main (40)
  • Hue Hub ethernet move to IoT (20)
  • Aura Frame WiFi move to IoT SSID (20)
  • HomePod x2 WiFi move to IoT SSID (20)
  • LG CX TV WiFi move to IoT SSID (20)

With Apple Home, the Apple TV is the “Hub” for the other devices (light bulbs, speakers). With my current configuration, will I need to setup similar rules for the IoT VLAN so I can continue to control my lights and speakers?

Here is my config with the IoTZone rule cleanup, I think it was a copy and paste mistake when I was adding the other rules. I put the Arch Server on a static IP and the Mac Mini was already on static, so no need for the rules for the ServerZone.

root@OpenWrt:~# cat /etc/config/firewall

config defaults
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option synflood_protect '1'

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'lan'

config zone
        option name 'wan'
        list network 'wan'
        list network 'wan6'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'DROP'
        option masq '1'
        option mtu_fix '1'

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

config rule
        option name 'Allow-Ping'
        option src 'wan'
        option proto 'icmp'
        option icmp_type 'echo-request'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'

config zone
        option name 'GuestZone'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'Guest'

config rule
        option src 'GuestZone'
        option name 'Guest DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config rule
        option src 'IoTZone'
        option name 'IoT DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config rule
        option src 'MainZone'
        option name 'Main DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config forwarding
        option src 'GuestZone'
        option dest 'wan'

config zone
        option name 'IoTZone'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'IoT'

config forwarding
        option src 'IoTZone'
        option dest 'wan'

config forwarding
        option src 'lan'
        option dest 'IoTZone'

config zone
        option name 'MainZone'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'Main'

config forwarding
        option src 'MainZone'
        option dest 'IoTZone'

config forwarding
        option src 'MainZone'
        option dest 'lan'

config forwarding
        option src 'MainZone'
        option dest 'wan'

config forwarding
        option src 'lan'
        option dest 'MainZone'

config zone
        option name 'ServersZone'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'Servers'

config forwarding
        option src 'ServersZone'
        option dest 'wan'

config forwarding
        option src 'MainZone'
        option dest 'ServersZone'

Hi @robalees,

Thanks for sharing your setup and configuration. Regarding your questions:

Ollama / Open WebUI access from Mac Mini (10.1.50.99) to your Mac on MainZone (.40):
Since your ServersZone → MainZone traffic is blocked (forwarding = REJECT), the Mac Mini cannot initiate connections to devices in MainZone. Unlike Plex, which we discussed previously, Ollama/Open WebUI traffic is likely using standard HTTP/HTTPS (or a specific port like 11434 as you mentioned).

There are two approaches:

  1. Add a dedicated firewall rule for this traffic:
    You can allow the specific port from ServersZone → MainZone to make this work, for example:
config rule
    option src 'ServersZone'
    option dest 'MainZone'
    option proto 'tcp'
    option dest_port '11434'
    option target 'ACCEPT'
    option name 'Open WebUI Access'

This is safer than opening all forwarding, because it limits traffic to only what you need.

  1. Or move the service to MainZone:

    If you host Ollama/Open WebUI on a device in MainZone, no special rules are needed — the Mac Mini can access it directly without adjusting firewall rules.


IoT devices and Apple Home / Hue / HomePod / LG TV:

Your Apple Home setup relies on the Apple TV (MainZone) as a hub. Since the other IoT devices (Hue Hub, Aura Frame, HomePods, LG TV) are moving to IoTZone, VLAN separation can block the hub from reaching them, because IoTZone → MainZone forwarding is currently rejected.

You have two options:

  1. Add selective rules for the required ports/protocols:

    • Bonjour / mDNS (UDP 5353) for device discovery

    • SSDP / DLNA (UDP 1900) if needed

    • Any custom ports your IoT devices require

Example:

# Allow mDNS (Apple Home discovery)
config rule
    option src 'IoTZone'
    option dest 'MainZone'
    option proto 'udp'
    option dest_port '5353'
    option target 'ACCEPT'
    option name 'IoT → Main mDNS'

# Allow SSDP (optional)
config rule
    option src 'IoTZone'
    option dest 'MainZone'
    option proto 'udp'
    option dest_port '1900'
    option target 'ACCEPT'
    option name 'IoT → Main SSDP'
  1. Keep everything in MainZone:

    If you want to avoid firewall adjustments, the Apple TV and dependent IoT devices can stay in MainZone. This simplifies connectivity but reduces network segmentation.


Summary / Recommendation:

  • For Ollama/Open WebUI, either add a dedicated rule for the port or move the service to MainZone.

  • For Apple Home / IoT, either add mDNS/SSDP rules to allow the hub to reach IoT devices across VLANs, or keep critical devices in MainZone to avoid cross-VLAN traffic issues.

  • Avoid broad forwarding from IoTZone → MainZone; only allow what is strictly necessary to maintain segmentation.

This approach keeps your VLAN segmentation effective while still allowing the services you need.

Awesome, thanks again @ncompact

The Open WebUI Access rule worked perfectly.

I setup the rules for the IoT → Main mDNS & SSDP, but I haven’t flipped the ports of the Hue Hub and SSID of the speakers yet, I want to avoid having no lights tonight lol.

But I’ll give it a try tomorrow and see if I can still communicate with the Apple Home devices.

Any tips on how I can test to see if any other rules are needed?

I’m going to look up the Aura Frame (will need to upload photos still) and Hue Hub ports requirements to make sure I’m not missing anything else.

I’ll likely install Plex on the Arch server as well and test the Plex rules, my Plex LXC on the Mac Mini is not happy with all the ip changes. So I’ll move Plex to the new server tomorrow and start fresh.

root@OpenWrt:~# cat /etc/config/firewall

config defaults
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option synflood_protect '1'

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'lan'

config zone
        option name 'wan'
        list network 'wan'
        list network 'wan6'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'DROP'
        option masq '1'
        option mtu_fix '1'

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

config rule
        option name 'Allow-Ping'
        option src 'wan'
        option proto 'icmp'
        option icmp_type 'echo-request'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'

config zone
        option name 'GuestZone'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'Guest'

config rule
        option src 'GuestZone'
        option name 'Guest DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config rule
        option src 'IoTZone'
        option name 'IoT DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config rule
        option src 'MainZone'
        option name 'Main DNS & DHCP'
        option dest_port '53 67 68'
        option target 'ACCEPT'

config forwarding
        option src 'GuestZone'
        option dest 'wan'

config zone
        option name 'IoTZone'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'IoT'

config forwarding
        option src 'IoTZone'
        option dest 'wan'

config forwarding
        option src 'lan'
        option dest 'IoTZone'

config zone
        option name 'MainZone'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'Main'

config forwarding
        option src 'MainZone'
        option dest 'IoTZone'

config forwarding
        option src 'MainZone'
        option dest 'lan'

config forwarding
        option src 'MainZone'
        option dest 'wan'

config forwarding
        option src 'lan'
        option dest 'MainZone'

config zone
        option name 'ServersZone'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'Servers'

config forwarding
        option src 'ServersZone'
        option dest 'wan'

config forwarding
        option src 'MainZone'
        option dest 'ServersZone'

config rule
        option src 'ServersZone'
        option dest 'MainZone'
        option name 'Open WebUI Access'
        list proto 'tcp'
        option dest_port '11434'
        option target 'ACCEPT'

config rule
        option src 'IoTZone'
        option dest 'MainZone'
        option name 'IoT -> Main mDNS'
        list proto 'udp'
        option dest_port '5353'
        option target 'ACCEPT'

config rule
        option src 'IoTZone'
        option dest 'MainZone'
        option name 'IoT -> Main SSDP'
        list proto 'udp'
        option dest_port '1900'
        option target 'ACCEPT'

Hi! :blush:

Perfect, I’m glad the Open WebUI rule worked without any issues!

Regarding your IoT devices and Apple Home, I’d suggest proceeding carefully: keep the Hue Hub and speakers on the current network until you’re sure the new rules are fully working, so you don’t end up without lights tonight.

To check if additional rules are needed, you can do the following:

  1. Check the firewall logs

    • Enable logging for the specific zone by adding, for example, in the IoTZone or MainZone section of /etc/config/firewall:
    option log '1'
    
  • Then monitor blocked packets with: logread -f | grep -E "reject|drop"
  1. This will show if any necessary packets are being blocked.
  2. Test the devices using their apps
    • Use Apple Home, Hue, Aura Frame, or Plex to see if devices can communicate correctly.

    • If something doesn’t work, you likely need additional rules for specific ports.

  3. Manually test ports
    • From a device on the IoT VLAN, you can test connections to MainZone using nc or telnet. For example:

      nc -vz 192.168.<MainZone_IP> 5353   # Test mDNS
      nc -vz 192.168.<MainZone_IP> 1900   # Test SSDP/UPnP
      

      This confirms whether your mDNS and SSDP rules are working as intended.

In general, only add rules for the specific services you need (mDNS, SSDP, device ports), avoiding opening all traffic between VLANs. This keeps segmentation effective and your network secure (based on the choices you make).

Hi @robalees,

I wanted to suggest a small improvement for even better security: instead of just opening the ports between VLANs (e.g., for WebUI, mDNS, SSDP), you could also limit access to specific device IPs.

For example, instead of:

option src 'ServersZone'
option dest 'MainZone'
option dest_port '11434'
option target 'ACCEPT'

you could specify the destination IP of the Mac hosting the WebUI:

option src 'ServersZone'
option dest 'MainZone'
option dest_ip '192.168.x.y'
option dest_port '11434'
option target 'ACCEPT'

This way, only the intended device can be reached, reducing the attack surface in case any ServersZone device gets compromised. The same approach could be applied to mDNS and SSDP rules for IoT devices.

It keeps your VLAN segmentation effective while improving security without losing functionality.

What do you think about this approach?

Hey @ncompact

I like this approach and did this for the Open WebUI rule, I just needed to put my Mac on a static IP so I could define the rule.

config rule
        option src 'ServersZone'
        option dest 'MainZone'
        option name 'Open WebUI Access'
        list proto 'tcp'
        option dest_port '11434'
        option target 'ACCEPT'
        list dest_ip '10.1.40.40'

For the mDNS and SSDP rules, would I need to put the other devices on static IPs or will it configure the IP based on the MAC in case the IP changes due to DHCP?

Good question :+1:

The best approach here is to use DHCP static leases based on MAC addresses. This way, each device always gets the same IP, and you can safely restrict your firewall rules using dest_ip for better security.

For most IoT devices (Hue Hub, speakers, etc.), the MAC address is stable, so this works perfectly and is the recommended setup.

However, if you have devices that use randomized MAC addresses (some phones or newer clients do this), then DHCP reservations won’t be reliable. In those cases you have a couple of options:

  • either disable MAC randomization on those devices (if possible), so you can still use static leases

  • or avoid strict dest_ip rules and allow access based on ports/protocols only (less secure, but more flexible)

For mDNS and SSDP specifically, keep in mind they rely on multicast, so IP-based filtering can be limiting depending on how discovery is working across VLANs.

So in short:

  • static DHCP leases + dest_ip → best and most secure option

  • dynamic MAC devices → fall back to broader rules or adjust the client configuration

That’s usually the best balance between security and reliability.

Just to add some useful references in case you go deeper into mDNS/SSDP across VLANs:

This might be helpful if you run into discovery issues between VLANs.

I reckon you should start tagging which ones of your posts include LLM responses.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.