Port based network separation

I have a Mikrotik HEX RouterOS device and several WiFi access points that are not VLAN aware. I would like to connect one access point to port 2 and one access point to port 3, and separate the networks but share the internet connection from port 1 (WAN).

From what I can find online, I have 2 options, I listed them below and included some config:

Use the physical ports to create 2 subnets (1 per port) and configure the firewall so the networks cannot access each other, something like:

/interface ethernet set 
[ find default-name=ether1 ] name=WANset 
[ find default-name=ether2 ] name=AP1set 
[ find default-name=ether3 ] name=AP2
/ip address
add address=192.168.88.1/24 interface=AP1 comment="Subnet AP1"
add address=192.168.99.1/24 interface=AP2 comment="Subnet AP2"
/ip pool
add name=poolAP1 ranges=192.168.88.10-192.168.88.254
add name=poolAP2 ranges=192.168.99.10-192.168.99.254
/ip dhcp-server
add name=dhcpAP1 interface=AP1 address-pool=poolAP1 lease-time=1h
add name=dhcpAP2 interface=AP2 address-pool=poolAP2 lease-time=1h
/ip dhcp-server network
add address=192.168.88.0/24 gateway=192.168.88.1 dns-server=192.168.88.1
add address=192.168.99.0/24 gateway=192.168.99.1 dns-server=192.168.99.1
/ip firewall nat
add chain=srcnat out-interface=WAN action=masquerade
/ip firewall filter
add chain=forward src-address=192.168.88.0/24 dst-address=192.168.99.0/24 action=drop
add chain=forward src-address=192.168.99.0/24 dst-address=192.168.88.0/24 action=drop
add chain=forward in-interface=AP1 out-interface=WAN action=accept
add chain=forward in-interface=AP2 out-interface=WAN action=accept
add chain=forward action=drop

Or create 2 port-based VLANS separated by firewall rules, like:

/interface ethernet
set [ find default-name=ether1 ] name=WAN
set [ find default-name=ether2 ] name=AP1
set [ find default-name=ether3 ] name=AP2
/interface bridge
add name=br-lan vlan-filtering=yes
/interface bridge port
add bridge=br-lan interface=ether2 pvid=88 comment="AP1 -> VLAN88"
add bridge=br-lan interface=ether3 pvid=99 comment="AP2 -> VLAN99"
/interface vlan
add interface=br-lan name=vlan88 vlan-id=88
add interface=br-lan name=vlan99 vlan-id=99
/ip address
add address=192.168.88.1/24 interface=vlan88 comment="Subnet AP1"
add address=192.168.99.1/24 interface=vlan99 comment="Subnet AP2"
/ip pool
add name=pool88 ranges=192.168.88.10-192.168.88.254
add name=pool99 ranges=192.168.99.10-192.168.99.254
/ip dhcp-server
add name=dhcp88 interface=vlan88 address-pool=pool88 lease-time=1h
add name=dhcp99 interface=vlan99 address-pool=pool99 lease-time=1h
/ip dhcp-server network
add address=192.168.88.0/24 gateway=192.168.88.1 dns-server=192.168.88.1
add address=192.168.99.0/24 gateway=192.168.99.1 dns-server=192.168.99.1
/ip firewall nat
add chain=srcnat out-interface=WAN action=masquerade
/ip firewall filter
add chain=forward src-address=192.168.88.0/24 dst-address=192.168.99.0/24 action=drop comment="Block VLAN88 -> VLAN99"
add chain=forward src-address=192.168.99.0/24 dst-address=192.168.88.0/24 action=drop comment="Block VLAN99 -> VLAN88"
add chain=forward in-interface=vlan88 out-interface=WAN action=accept comment="VLAN88 → internet"
add chain=forward in-interface=vlan99 out-interface=WAN action=accept comment="VLAN99 → internet"
add chain=forward action=drop comment="Drop other forward traffic"

Would both options work, and which option would you prefer?

Basically yes. The two solutions don't differ significantly from a logical standpoint. Vlan-based segmentation is always more extensible and configurable. Most people find the vlan-less version easier to set up. So my suggestion is that if you're willing to go down the vlan path, do it; if you want to expend the least effort, go ahead with the other one

You will have to refine your firewall further in both cases. I would suggest using the WAN and LAN interface lists and add another one (GUEST? IOT? DMZ?) for your new subnet. Usually people want the additional subnet to have different access (e.g. to the router's admin interfaces?) than the other.

If this observation regarding different levels of access is a correct guess, make this requirement explicit. It will help you and anyone trying to assist to have it written down.

Thanks, I kept the firewall rules very basic deliberately, will probably work with the default ruleset and expand with this custom setup. Regarding access to webfig, I could probably configure the WWW service (and probably SSH) to be only available from one of the subnets/VLANS.

The default firewall is not at all bad. I was also suggesting to just expand it.

Adding another interface list besides LAN will help you. Otherwise you'll have to put both internal subjets into LAN, and use additional rules.

By default, all internal services are exposed to LAN, so you'll have to restrict each one individually.

So e.g. if this was a guest network, I would add the GUEST interface list and add the following firewall rules:

# Allow ICMP
add chain=input action=accept in-interface-list=GUEST protocol=icmp
# Allow DNS, both UDP and TCP
add chain=input action=accept in-interface-list=GUEST protocol=udp dst-port=53
add chain=input action=accept in-interface-list=GUEST protocol=tcp dst-port=53
# And nothing else
add chain=input action=drop in-interface-list=GUEST

# Allow forwarding to WAN
add chain=forward action=accept in-interface-list=GUEST out-interface-list=WAN
# And nowhere else
add chain=forward action=drop in-interface-list=GUEST

This sort of ruleset is much better than walling off piece-by-piece what we don't allow, and makes it simple to list the things we actually want to permit instead.

Thanks for the suggestion! I will receive a spare Mikrotik shortly to play around with and test the config. Other than the firewall config, the VLAN config looks good in your opinion? I lean towards that one, but am still curious what others would prefer.

You have aptly described the two approaches. The choice is yours, use vlans or dont use vlans.
In your case, it would depend! It depends on if the APs are smart APs or dumb APs.
If they cannot read vlan tags then dont bother with the vlan filtering bridge approach.

Vlan filtering would be the no-brainer approach for smart APs, because one can apply vlans to the different wlans/ssids, so one could have a vlan for smart devices, one for cameras, one for guests, one for home etc...... Max flex. It does not appear to be the case, however where i differe is my firewall approach.
As per lurker separate trusted and untrusted from access to config the router.

/interface list
add name=WAN
add name=LAN
add name=TRUSTED
/interface list members
add interface=ether1 list=WAN
add interface=AP1set list=LAN comment="home users"
add interface=AP2 list=LAN comment="guest users"
add interface=AP1set list=TRUSTED
/ip firewall filter
{ default rules to keep }
add action=accept chain=input connection-state=established,related,untracked
add action=drop chain=input connection-state=invalid
add action=accept chain=input protocol=icmp
add action=accept chain=input dst-address=127.0.0.1
(admin rules)
add action=accept chain=input comment="admin access" in-interface-list=TRUSTED
add action=accept chain=input comment="users to services" in-interface-list=LAN \
dst-port=53,123 protocol=udp
add action=accept chain=input comment="users to services" in-interface-list=LAN \
dst-port=53 protocol=tcp
add action=drop chain=input comment="drop all else"  { put rule here but last of all rules }
++++++++++++++++++++++++++++++++++++++++++++++++
{ default rules to keep }
add action=fasttrack-connection chain=forward connection-state=established,related
add action=accept chain=forward connection-state=established,related,untracked
add action=drop chain=forward connection-state=invalid
(admin rules)
add action=accept chain=forward comment="internet traffic" in-interface-list=LAN \
out-interface-list=WAN
add action=accept chain=forward comment="Allow port forwarding" \
    connection-nat-state=dstnat disabled=yes  { enable or remove if not required }
add action=drop comment="drop all else" 
/ip neighbor discovery-settings
set discover-interface-list=TRUSTED
/tool mac-server
set allowed-interface-list=none
/tool mac-server mac-winbox
set allowed-interface-list=TRUSTED

Thank you! They are not smart, but I am planning to connect one access point to one port / VLAN and create a SSID, and add the other access point with a different SSID to another port / VLAN. This way the access points wouldn’t need to be able to understand VLANS as all the logic would be in the Mikrotik, right?

Exactly correct. For these situations you don't need vlans. They can be used in exactly the way you describe in your initial post.

The usual assumption is that people want the same AP ti broadcast both SSIDs, which most APs are capable of (even consumer ones.) This is not your scenario so you can go either way.

Received my new Mikrotik today so I was able to set up a lab. After a few hours of fiddling it looks like I have a working setup. I took your suggestions in consideration. Let me know what you think!
In this case, rest (vlan 88) is trusted, apt (vlan 99) untrusted.

/interface bridge
add name=bridge-vlan vlan-filtering=yes

/interface vlan
add interface=bridge-vlan name=vlan88 vlan-id=88
add interface=bridge-vlan name=vlan99 vlan-id=99

/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
add comment="restaurant interfaces" name=rest
add comment="appartment interfaces" name=apt

/ip pool
add name=pool88 ranges=192.168.88.10-192.168.88.254
add name=pool99 ranges=192.168.99.10-192.168.99.254

/ip dhcp-server
add address-pool=pool88 interface=vlan88 lease-time=1h name=dhcp88
add address-pool=pool99 interface=vlan99 lease-time=1h name=dhcp99

/interface bridge port
add bridge=bridge-vlan comment="VLAN 88 Restaurant" frame-types=admit-only-untagged-and-priority-tagged interface=ether2 pvid=88
add bridge=bridge-vlan comment="VLAN 88 Restaurant" frame-types=admit-only-untagged-and-priority-tagged interface=ether3 pvid=88
add bridge=bridge-vlan comment="VLAN 99 Appartment" frame-types=admit-only-untagged-and-priority-tagged interface=ether4 pvid=99
add bridge=bridge-vlan comment="VLAN 99 Appartment" frame-types=admit-only-untagged-and-priority-tagged interface=ether5 pvid=99

/ip neighbor discovery-settings
set discover-interface-list=LAN

/interface bridge vlan
add bridge=bridge-vlan tagged=bridge-vlan untagged=ether2,ether3 vlan-ids=88
add bridge=bridge-vlan tagged=bridge-vlan untagged=ether4,ether5 vlan-ids=99
add bridge=bridge-vlan untagged=bridge-vlan vlan-ids=1

/interface list member
add comment=defconf interface=ether1 list=WAN
add interface=vlan88 list=rest
add interface=vlan88 list=LAN
add interface=vlan99 list=LAN
add interface=vlan99 list=apt

/ip address
add address=192.168.88.1/24 comment="subnet rest" interface=vlan88 network=192.168.88.0
add address=192.168.99.1/24 comment="subnet apt" interface=vlan99 network=192.168.99.0

/ip dhcp-client
add comment=defconf interface=ether1

/ip dhcp-server network
add address=192.168.88.0/24 dns-server=192.168.88.1 gateway=192.168.88.1
add address=192.168.99.0/24 dns-server=192.168.99.1 gateway=192.168.99.1

/ip dns
set allow-remote-requests=yes

/ip dns static
add address=192.168.88.1 comment=defconf name=router.lan type=A

/ip firewall filter
add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=accept chain=input comment="custom: allow mgmt from restaurant" in-interface-list=rest
add action=accept chain=input comment="custom: allow DNS/NTP from appartment" dst-port=53,123 in-interface-list=apt protocol=udp
add action=accept chain=input comment="custom: allow DNS from appartment" dst-port=53 in-interface-list=apt protocol=tcp
add action=drop chain=input comment="custom: drop all else"
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related hw-offload=yes
add action=accept chain=forward comment="defconf: accept established,related, untracked" connection-state=established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=forward comment="custom: internet traffic" in-interface-list=LAN out-interface-list=WAN
add action=drop chain=forward comment="custom: drop all else"

/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" ipsec-policy=out,none out-interface-list=WAN

/tool mac-server
set allowed-interface-list=none

/tool mac-server mac-winbox
set allowed-interface-list=rest

/interface bridge
add name=bridge-vlan vlan-filtering=yes  frame-types=admit-only-vlan-tagged

/interface vlan
add interface=bridge-vlan name=vlan88 vlan-id=88
add interface=bridge-vlan name=vlan99 vlan-id=99

/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
add comment="trusted users" name=TRUSTED

/ip pool
add name=pool88 ranges=192.168.88.10-192.168.88.254
add name=pool99 ranges=192.168.99.10-192.168.99.254

/ip dhcp-server
add address-pool=pool88 interface=vlan88 lease-time=1h name=dhcp88
add address-pool=pool99 interface=vlan99 lease-time=1h name=dhcp99

/interface bridge port
add bridge=bridge-vlan comment="VLAN 88 Restaurant" frame-types=admit-only-untagged-and-priority-tagged interface=ether2 pvid=88
add bridge=bridge-vlan comment="VLAN 88 Restaurant" frame-types=admit-only-untagged-and-priority-tagged interface=ether3 pvid=88
add bridge=bridge-vlan comment="VLAN 99 Appartment" frame-types=admit-only-untagged-and-priority-tagged interface=ether4 pvid=99
add bridge=bridge-vlan comment="VLAN 99 Appartment" frame-types=admit-only-untagged-and-priority-tagged interface=ether5 pvid=99

/ip neighbor discovery-settings
set discover-interface-list=TRUSTED

/interface bridge vlan
add bridge=bridge-vlan tagged=bridge-vlan untagged=ether2,ether3 vlan-ids=88
add bridge=bridge-vlan tagged=bridge-vlan untagged=ether4,ether5 vlan-ids=99

/interface list member
add comment=defconf interface=ether1 list=WAN
add interface=vlan88 list=LAN
add interface=vlan99 list=LAN
add interface=vlan88 list=TRUSTED

/ip address
add address=192.168.88.1/24 comment="subnet rest" interface=vlan88 network=192.168.88.0
add address=192.168.99.1/24 comment="subnet apt" interface=vlan99 network=192.168.99.0

/ip dhcp-client
add comment=defconf interface=ether1

/ip dhcp-server network
add address=192.168.88.0/24 dns-server=192.168.88.1 gateway=192.168.88.1
add address=192.168.99.0/24 dns-server=192.168.99.1 gateway=192.168.99.1

/ip dns
set allow-remote-requests=yes server=1.1.1.1,9.9.9.9

/ip firewall filter
add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=accept chain=input comment="admin access" in-interface-list=TRUSTED
add action=accept chain=input comment="users to services" dst-port=53,123 \
 in-interface-list=LAN protocol=udp
add action=accept chain=input comment="users to services" dst-port=53 \
 in-interface-list=LAN protocol=tcp
add action=drop chain=input comment="custom: drop all else"
++++++++++++++++++++++++++++++++++++++++++++++++
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related hw-offload=yes
add action=accept chain=forward comment="defconf: accept established,related, untracked" connection-state=established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=forward comment="custom: internet traffic" in-interface-list=LAN out-interface-list=WAN
add action=drop chain=forward comment="custom: drop all else"

/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" ipsec-policy=out,none out-interface-list=WAN

/tool mac-server
set allowed-interface-list=none

/tool mac-server mac-winbox
set allowed-interface-list=TRUSTED
  • Only one extra list is required
  • All users need access to DNS for internet, not just apt.
  • the only change I would make for myself is to create a list of firewall addresses for the devices in the Restaurant subnet that were admin devices ( static leases for wired, and same for wifi (and ensuring IOS setup was native mac, not rotating random mac ). Then my rule would look like.
add action=accept chain=input comment="admin access" in-interface-list=TRUSTED \
  src-address-list=Authorized

where
add address=192.168.88.X list=Authorized
add address=192.168.88.Y list=Authorized
add address=192.168.88.Z list=Authorized

If you have a public IP I would also consider adding wireguard VPN to be able to access the router for config purposes from anywhere. If no public IP, you could still use BTH. Just let us know if thats a possibility.

Seems good. This will probably work nicely for a long time.

If it was me, I'd restrict mgmt access to selectively allow only the types of management I want or need. When allowing access to everything, you grant access to services that you may not even be aware of (api/rest api/ftp etc.) and those may also have security issues. I would add protocol=tcp and dst-port=22,80,8291 to only allow ssh, unencrypted webfig and winbox.

  • Only one extra list is required
  • All users need access to DNS for internet, not just apt.

Right now, this rule should take care of that:

add action=accept chain=input comment="custom: allow mgmt from restaurant" in-interface-list=rest

But I agree that this might be narrowed down to a few IP’s/services as @lurker888 suggested as wel. I will also look into VPN access, probably using Tailscale as I have a Tailnet setup already. Thanks for your ideas!

Edit: Tailscale implementation seems a little experimental. Will look into Wireguard instead as a static public IP should be available at the location.

There are lots of ways to spread butter on the bread, when I can I use less butter :slight_smile: