Layer 3 isolation of 2 bridges

I am trying to figure out the easiest way to do layer 3 isolation across 2 bridges. They seem to be isolated doing nothing but my understanding is that having 2 bridges only guarantees isolation at layer 2. I’ve seen some other posts addressing this but frankly they were over my head. Basically I have Ether1 configured as the WAN with internet access. Ether 2 is on one bridge and has WAN access, DHCP server. Ports 4&5 are on a second bridge. They are part of an isolated LAN that should have no internet access (essentially air gapped). I have an IP assigned to the second bridge so that the isolated network has access to an NTP server I have configured in the router.

I have pasted the whole config of my router below. I have tried 2 methods but none of them seem to do anything and the networks seem isolated whether they’re there or not. Any help appreciated.

Method 1: Raw filter

/ip firewall raw
add action=drop chain=prerouting dst-address=172.16.0.0/16 src-address=\
    192.36.253.0/24
add action=drop chain=prerouting dst-address=192.36.253.0/24 src-address=\
    172.16.0.0/16

Method 2: Route Rule

/ip route rule
add action=unreachable dst-address=172.16.0.0/16 src-address=192.168.36.0/24

Complete export:

# jul/22/2025 13:20:12 by RouterOS 6.49.19
# software id = WS82-ZMAK
#
# model = 951G-2HnD
# serial number = 845108356857
/interface bridge
add admin-mac=CC:2D:E0:5E:CF:A1 auto-mac=no comment=defconf name=bridge
add name=ncr_bridge
/interface wireless
set [ find default-name=wlan1 ] band=2ghz-b/g/n channel-width=20/40mhz-XX \
    distance=indoors frequency=auto installation=indoor mode=ap-bridge ssid=\
    MikroTik-5ECFA5 wireless-protocol=802.11
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/ip pool
add name=default-dhcp ranges=192.168.88.10-192.168.88.254
add name=pool1 ranges=10.0.0.10-10.0.0.254
/ip dhcp-server
add address-pool=default-dhcp interface=bridge lease-time=30m name=defconf
add address-pool=pool1 disabled=no interface=bridge lease-time=30m name=\
    server1
/interface bridge port
add bridge=bridge comment=defconf interface=ether2
add bridge=bridge comment=defconf interface=ether3
add bridge=ncr_bridge comment=defconf hw=no interface=ether4
add bridge=ncr_bridge comment=defconf hw=no interface=ether5
add bridge=bridge comment=defconf interface=wlan1
/ip neighbor discovery-settings
set discover-interface-list=LAN
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
/ip address
add address=172.16.1.99/16 interface=ether1 network=172.16.0.0
add address=10.0.0.1/8 interface=bridge network=10.0.0.0
add address=192.36.253.68/24 interface=ncr_bridge network=192.36.253.0
/ip dhcp-server network
add address=10.0.0.0/8 dns-server=10.0.0.1 gateway=10.0.0.1 netmask=8
/ip dns
set allow-remote-requests=yes servers=8.8.8.8,1.1.1.1
/ip dns static
add address=10.0.0.1 comment=defconf name=router.lan
/ip firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=accept chain=input comment="Allow Winbox" dst-port=8291 protocol=\
    tcp
add action=accept chain=input comment="Allow Access to NTP server" dst-port=\
    123 protocol=udp
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=drop chain=input comment="defconf: drop all not coming from LAN" \
    in-interface-list=!LAN
add action=drop chain=forward in-interface=ncr_bridge out-interface-list=WAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
    ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
    ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related
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=drop chain=forward comment=\
    "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
    connection-state=new in-interface-list=WAN
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN
/ip firewall raw
add action=drop chain=prerouting dst-address=172.16.0.0/16 src-address=\
    192.36.253.0/24
add action=drop chain=prerouting dst-address=192.36.253.0/24 src-address=\
    172.16.0.0/16
/ip firewall service-port
set ftp disabled=yes
/ip route
add distance=1 gateway=172.16.1.1
/ip route rule
add action=unreachable dst-address=172.16.0.0/16 src-address=192.168.36.0/24
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
/system clock
set time-zone-name=America/Chicago
/system identity
set name=EE_Dept
/system ntp client
set enabled=yes primary-ntp=216.239.35.4 secondary-ntp=216.239.35.0
/system ntp server
set enabled=yes multicast=yes
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN

Two simple forward rules would suffice:

/ip firewall filter
add action=drop chain=forward in-interface=bridge out-interface=ncr_bridge
add action=drop chain=forward in-interface=ncr_bridge out-interface=bridge

If you want the isolation air-gapped, as you expressed yourself, just use the ncr_bridge as only in-interface, resp. out-interface selector in the two rules:

/ip firewall filter
add action=drop chain=forward out-interface=ncr_bridge
add action=drop chain=forward in-interface=ncr_bridge
1 Like
  1. Why the need for two bridges vice one?

  2. In general, the standard firewall rules are useful for one LAN and simple setup.
    Once you go beyond that one has to slighly rejig the firewall rules, to ensure only the admin has access to the input chain for config purposes and that the forward chain ensure subnets access to the internet and each other is controlled.

  3. There is no need to use raw rules as they are powerful but crude weapons of security and should only be used if the standard firewall rules are inadequate, which is NOT the case here.

  4. This rule is a security infraction and should be limited at least to the LAN interface only.

add action=accept chain=input comment="Allow Winbox" dst-port=8291 protocol=\
    tcp

Modify ruleset to the following  ( get rid of raW RULES )

/ip firewall address-list  ( static leases set )
add address=admin-address1   list=TRUSTED  comment="admin desktop local wired"
add address=admin-address2  list=TRUSTED  comment="admin laptop/ipad local wifi"
add address=admin-address3  list=TRUSTED  comment="admin smartphone local wifi"

/ip firewall
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
add action=accept chain=input comment="admin access" in-interface-list=LAN src-address-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 this rule here but last of all rules }

AND FORWARD CHAIN AS FOLLOWS
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
add action=accept chain=forward comment="internet traffic" in-interface=bridge out-interface=WAN
add action=accept chain=forward comment="admin access" src-address-list=TRUSTED out-interface-list=LAN
add action=accept chain=forward comment="port forwarding" connection-nat-state=dstnat disable=yes
(enable if required or remove)
add action=drop chain=forward comment="drop all else" 

Not sure why you have any route rule? not required!!!

By the way your subnet 192.36  is NOT a private range you should be using ?????

My intention for using two bridges was to maintain the “air gap” between the 2 LANs. As far as the route rule goes, I’m a little out of my element there and saw it another post. That’s why I’m asking questions.

The 192.36. network goes back nearly 30 years and was set up by a consultant at the time for an in house only, no internet connected LAN for our ERP system written in COBOL :). We have probably 100 pc’s with static ip’s for this LAN. I know it’s not right but at this point it’s not worth the aggravation.

There’s nothing fundamentally wrong with using two bridges. Depending on your exact device, other configurations may be more efficient.

Routing rules (or other modifications to routing) are only necessary if you want to have overlapping subnets (addresses) on your two networks. Otherwise just delete them.

Raw rules are unnecessary. Remove them.

You will have to configure your firewall correctly. The forward chain is the one that applies to packets that go through the router (i.e. come in, go out) and input is what applies to packets destined for the router. E.g. the following firewall rules block packet forwarding between your two bridges:

/ip firewall filter
add action=drop in-interface=bridge out-interface="ncr_bridge"
add action=drop in-interface="ncr_bridge" out-interface=bridge

and so on…

BTW, don’t be ashamed of your COBOL system and its old-timey network. I’ve handled plenty of these, and they work just fine. You’re absolutely on the right track with isolating it from the general Internet and basically everything else that doesn’t absolutely has to have access to it.

Thanks for the explanation on what the routing rules are for @lurker888. I have deleted them along with the raw rules and added firewall filter in the forward chain:

/ip firewall filter
add action=drop chain=forward in-interface=bridge out-interface=ncr_bridge
add action=drop chain=forward in-interface=ncr_bridge out-interface=bridge

Glad to help. Just keep in mind that the two rules that I gave were only as an illustration.

To arrive at a correct final solution, you will have to carefully map what networks should have access to what others, and construct an appropriate set of firewall rules. So basically create a sort of table with your networks (for you currently: [some wider network], bridge, ncr_bridge) as row and column headers, and consider the cells at each intersection of labels: should these have access to each other? should both be allowed to initiate this access, or only one side?

Hi John,

For another viewpoint, in my forward chain rules, besides mostly all the default rules, I have a drop all else rule at the end, so anything not explicitly allowed above, is not passed.
In this construct your two rules would not be required because they were not allowed. Cleaner and m,ore efficient IMHO.

ex.

/ip firewall
.....{input chain}.........
+++++++++++++++++++++++++++
{ 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="port forwarding" connection-nat-state=dstnat \
  disabled=yes  { enable if required or remove }
add action=drop chain=forward comment="Drop all else" 

In the above set of rules, there will be no layer3 traffic between the two bridges.