Bridges isolation with bridge filtering (firewall)

Hello!

I want to achieve a complete L2 & L3 isolation between 3 different bridges in hAP AC.

The 3 different bridges have assigned 3 different private prefixes to them. Also, the 3 bridges have all their ports set as access ports for 3 different VLANs.

  1. How should I set the bridge firewall, so that all traffic originating from any given bridge can get ONLY to the same bridge (i.e. prevent cross-bridge traffic) AND if needed to be NAT-ed via masquerade in the IP firewall?

  2. What is the most efficient way to forcefully filter traffic between the 3 networks in the bridges, i.e. IP firewall (let’s leave the routing table out for now)?

Currently, Bridge 1 (B1) has IP 192.168.100.1 and it can successfully ping Bridge 2 (B2, 192.168.200.1). More so, all bridges are with different PVID and VLAN filtering enabled. Shouldn’t be this not possible with VLAN isolation event without the firewall?

All ideas are welcome while I upload my sample configuration and possibly, some diagrams.

Z

One bridge
Use Vlans for L2 separation
Use FW for L3 separation
(forward chain)

  • default rules (fast track, allow established,related drop invalid packets etc.)
  • user rules (allow vlans to internet for example)
    -LAST RULE IMPORTANT
    add action=drop chain=forward comment="Drop all else)

Any traffic not explicitly allowed is dropped including any vlan to vlan traffic (in terms of the router trying to route between them).
If you do not use VLANS for L2 separation but having subnets on different bridges accomplishes L2 separation then the same LAST rule also applies
So all you need to do is add the last rule…

Done!!!

Let’s assume that ports on your router has a following addresses for three different subnets

subnet 1 ->192.168.100.0/24
subnet 2 ->192.168.200.0/24
subnet 3 ->192.168.250.0/24

Just add those addresses to address list a name it “MySubnets”

/ip firewall address-list
add address=192.168.100.0/24 list=MySubnets
add address=192.168.200.0/24 list=MySubnets
add address=192.168.250.0/24 list=MySubnets

now add a firewall rule

/ip firewall filter
add action=drop chain=forward dst-address-list=MySubnets src-address-list=MySubnets


That should do the job if I understood your question correctly…

regards

Maybe some more fundamental aspects before designing your security:

L2 / “within the bridge” level : Devices within L2 communicate and see everybody on that network.
(this is for instance all the clients and computers/devices you see on the same Wifi network).
All these can do pretty much what they want and each of them are also aware what device there are within the bridge.
This was not that much of an issue before (many devices had not a real IP stack and needed dedicated “applications” to
to be installed on your PC or mobile to make them work. That is over now…
Nowadays they all are full network devices, which means you do not know what they do and they communicate to remote servers without
you knowing about it!
→ make sure you keep trusted devices (= important) only in the same L2 network with other trusted devices.
And ensure those devices on that network don’t “share” disks or folders without passwords at least!

L3: IP level: This level of connection does not care if its in the cloud, your home network, within a router or over 2 or more routers etc.
Devices have IP addresses and can try to connect to any other IP address in the world. Some (limited) security comes with NAT
(outside world does know what IP is used behind NAT). (I skip here IP4 versus IP6 etc.)
The router “routes” all these IP packets. So your IP on bridge 1 can talk to another IP on bridge 2 etc as router by default is supposed to make the talk!
The router also routes (connects) data from your bridge into the internet if he thinks the IP is located there.

Firewall:
Before the router does the “routing”, you have the option to tell him via the firewall:

  • what to accept already


  • What not to accept (=drop)


  • At the end of the firewall, any packet not dropped or accepted will then be routed (=accepted)


  • You can do much more but I keep it simple

Now ROS is really incredible as it has firewall that does not only allow IP address, but also interfaces, interface list and many more things to base your filter
decision (accept/drop) on it. In your case you could allow by adress space, by bridge , interface or interface list.

Example (this is not real code but should tell you how to do):

  • Chain forward: accept source interface: BRIDGE1, destination interface list: WAN
  • Chain forward: accept source interface list WAN, destination interface BRIDGE 1
    this for each BRIDGE 1 (you can refine with connection state etc…)
    Do this for every bridge, then do a drop all on forward chain and you see you wont be able to ping from one bridge to another anymore.

Hope it helps.
I don’t want to give a simple command line to copy.
Its important you think about what you do and what to achieve and how to do it
and by doing so you learn more about it…

Long winded Post but in a nutshell

  1. To isolate subnets at Layer 2 use:
    a. vlans (I prefer these)
    b. bridges (for example one subnet on one bridge, one subnet not on the bridge OR a subnet on one bridge and the other subnet on another bridge etc.)

  2. To isolate subnets at Layer 3 use firewall rules.
    ***Disagree with the above approach.
    Much cleaner and simpler to only allow traffic desired and use ONE RULE to drop all else as last rule.
    Further, I don’t like the idea of having the router pass anything through that I dont know about. (Default to accept IMHO is not best security practices)

  3. I do concur that the router is extremely flexible in that there are many ways to define groups of users or groups of interfaces (interface list, firewall address lists etc…)

Anav,

I just explained how Firewall works. If you put a “drop all” at the end it drops it. If not it does not!
It’s important to understand that what ever is not processed within firewall gets accepted at the end…

I did not talk about what or what not to allow, but how to do the rule.
Fully agree, allow only what you want and drop all the rest. But what do you want/need :wink:?

Also important is L2/VLAN does not give you much security if you have insecure devices sitting in there
and you do not isolate or protect them further.

Ahh okay, if the intent was to state that without the last Drop Rule in place, the router will by default allow any unmatched packets to that point to be forwarded and thus RISKY, then we are on the same page!! :slight_smile:

Not sure what you mean by insecure devices? However, its true that L2 separation by bridges and vlans is only half the story as the ROUTER will route between subnets unless the configuration prevents it - hence DROP rule.

Take two subnets A and B.
If I want to stop L3 in the forward chain I could…
action drop subnet A to B
action drop subnet B to A.
OR
Action drop Last rule.

It becomes clearer when using multiple bridges or vlans etc that one rule is less messy/bloated and also less complex to manage overall.

Hello and thanks for the insights!

Let’s try and address them all one thing at a time.

What satman1w said looks quite elegant for L3 filtering. I’m extensively using lists but for some reason I totally forgot about the IP firewall ones… :cry:

What anav said is basically what I was saying with a touch of flavor. :slight_smile: Guys, remember - this is posted in ‘Beginner Basics’, i.e. some more reasoning and explanation are rather welcome.
And to continue this train of thought, what I totally agree with what WeWiNet said, esp. the last paragraph. Gheez, how does one multi-quote in this forum? :laughing:

Here is the config I was using for experiments:

/interface bridge
add frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes \
    name=MGMT pvid=11 vlan-filtering=yes
add frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes \
    name=Trusted-LAN pvid=22 vlan-filtering=yes
add frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes \
    name=Untrusted-LAN pvid=33 vlan-filtering=yes
/interface bonding
add mode=802.3ad name=dot3ad slaves=ether1,ether2 transmit-hash-policy=\
    layer-3-and-4
/interface list
add name=WAN_List
add name=Untrusted-LAN-List
add name=Trusted-LAN-List
add name=MGMT_List
/ip dhcp-server option
add code=43 name=microsoft-disable-netbios-option value=0x010400000002
/ip dhcp-server option sets
add name=microsoft-disable-netbios-option-set options=\
    microsoft-disable-netbios-option
/ip pool
add name=TRUSTED-LAN-DHCP-POOL ranges=192.168.111.2-192.168.111.254
add name=UNTRUSTED-LAN-DHCP-POOL ranges=192.168.222.2-192.168.222.254
/ip dhcp-server
add address-pool=TRUSTED-LAN-DHCP-POOL dhcp-option-set=\
    microsoft-disable-netbios-option-set disabled=no interface=Trusted-LAN \
    name=TRUSTED-LAN-DHCP
add address-pool=UNTRUSTED-LAN-DHCP-POOL dhcp-option-set=\
    microsoft-disable-netbios-option-set disabled=no interface=Untrusted-LAN \
    name=UNTRUSTED-LAN-DHCP
/interface bridge filter
add action=drop chain=input in-bridge=MGMT in-interface-list=!MGMT_List log=yes \
    log-prefix=bad-MGMT-login
add action=drop chain=forward in-bridge=MGMT out-bridge=!MGMT
add action=drop chain=forward in-bridge=Untrusted-LAN out-bridge=\
    !Untrusted-LAN
add action=drop chain=forward in-bridge=Trusted-LAN out-bridge=!Trusted-LAN
/interface bridge port
add bpdu-guard=yes bridge=OMC broadcast-flood=no edge=yes frame-types=\
    admit-only-untagged-and-priority-tagged ingress-filtering=yes interface=\
    ether4 pvid=999 tag-stacking=yes
add bridge=Untrusted-LAN frame-types=admit-only-untagged-and-priority-tagged \
    ingress-filtering=yes interface=wlan1 pvid=222 tag-stacking=yes
add bridge=Trusted-LAN frame-types=admit-only-untagged-and-priority-tagged \
    ingress-filtering=yes interface=QNAP-dot3ad pvid=111 tag-stacking=yes
add bridge=Trusted-LAN frame-types=admit-only-untagged-and-priority-tagged \
    ingress-filtering=yes interface=wlan2 pvid=111 tag-stacking=yes
/interface bridge settings
set use-ip-firewall=yes use-ip-firewall-for-pppoe=yes \
    use-ip-firewall-for-vlan=yes
/ip neighbor discovery-settings
set discover-interface-list=MGMT_List
/ip settings
set rp-filter=strict
/interface bridge vlan
add bridge=MGMT untagged=ether5 vlan-ids=999
add bridge=Trusted-LAN untagged=ether1,ether2,wlan2 vlan-ids=111
add bridge=Untrusted-LAN untagged=wlan1 vlan-ids=222
/interface list member
add interface=sfp1 list=WAN_List
add interface=wlan1 list=Untrusted-LAN-List
add interface=wlan2 list=Trusted-LAN-List
add interface=ether4 list=OMC_List
add interface=ether1 list=Trusted-LAN-List
/ip address
add address=192.168.199.1/24 interface=MGMT network=192.168.199.0
add address=192.168.111.1/24 interface=Trusted-LAN network=192.168.111.0
add address=192.168.222.1/24 interface=Untrusted-LAN network=192.168.222.0
/ip dhcp-client
add disabled=no interface=sfp1 use-peer-dns=no use-peer-ntp=no
/ip dhcp-server network
add address=192.168.111.0/24 comment=TRUSTED-LAN dhcp-option=\
    microsoft-disable-netbios-option dns-server=1.1.1.1,1.0.0.1 gateway=\
    192.168.111.1
add address=192.168.222.0/24 comment=UNTRUSTED-LAN dns-server=1.1.1.1,1.0.0.1 \
    gateway=192.168.222.1
/ip dns
set servers=1.1.1.1,1.0.0.1
/ip firewall filter
add action=accept chain=input comment="Accept Established" connection-state=\
    established
add action=accept chain=input comment="Accept Related" connection-state=\
    related
add action=drop chain=input comment="Drop All Unwanted on WAN" \
    in-interface-list=WAN_List
add action=drop chain=forward in-interface=MGMT log=yes log-prefix=\
    omc-fwd-drop out-interface=!MGMT
add action=drop chain=forward in-interface=Untrusted-LAN log=yes log-prefix=\
    untr-fwd-drop out-interface=!Untrusted-LAN
add action=drop chain=forward comment="Drop All Invalid on Forward" \
    connection-state=invalid log=yes log-prefix=invalid
add action=drop chain=forward in-interface=Trusted-LAN out-interface=\
    !Trusted-LAN
/ip firewall nat
add action=masquerade chain=srcnat out-interface-list=WAN_List

With this config I can ping IPs between bridges, although I was expecting not to, due to the forward chain filtering within the bridges. Now, MikroTik states in their wiki that the forward chain is used only for forwarding between the different ports within a bridge, so that explains why I still won’t filter the ping.
When I just swap the forward chain with the output chain in the bridge firewall rules, ROS complains that the output chain doesn’t carry an input address, so it can’t filter based on that.

I guess the way I’ve set up the VLANs in these bridges should effectively prevent L2 traffic spilling outside each respective bridge, yes? How can I test this?

Also, any other thoughts?