Mikrotik - Zone Based Firewall
Mikrotik - Zone Based Firewall
Posted on by Ryan
Earlier we talked about using CBAC (See the post Understanding CBAC) the “classic firewall” and
we mention some information about zone based firewalls but not nearly enough. So today we will
be talking about zone based firewalls. Why are they different? We also will learn the basics about
what is zone based and what are the advantages compared to CBAC.
You can think of zone based has making interfaces in a quarantine zone, each interface by default if
set up in a zone is denied access to any other interface. This helps isolate networks that have private
and or secure information that does not need the public network to have access to it. The firewall
policies are configured using the Cisco Common Classification Policy Language (C3PL), this uses a
hierarchical structure to define network protocol inspection and allows network devices to be
grouped under one inspection policy.
Believe it or not it should be easier to configure zone based firewall compared to CBAC Remember
that CBAC has these limitations:
• By having multiple inspection policies and ACLs on several interfaces on a router makes it
difficult and sometimes overwhelming.
• All traffic through a given interface is subject to the same inspection.
• CBAC relies too heavily on ACLs, which can only do so much!
By using zones that borders a network the traffic is inspected by the policy restrictions. These
restrictions can be different in each zone or interface. Using the zone based approach does have its
benefits:
• The Zone Based firewall is not dependent on ACLs.
• The router security posture is to block unless explicitly allowed. CBAC allows everything
unless explicitly denied or checked.
• Policies are easy to read and troubleshoot with C3PL. (Cisco Common Classification Policy
Language)
• One policy affects any given traffic, instead of needing multiple ACLs, inspection actions
and rules that CBAC would need.
An important note when deciding to implement CBAC or Zone based is that either models can be
enabled on the router simultaneously. They however cannot be used on the same interface as a
router.
There are three actions the zone based firewall can take when looking at traffic:
• Inspect – This action is like the CBAC ip inspect command. It automatically allows for
return traffic and potential ICMP messages. For protocols requiring multiple parallel
signaling and data sessions (such as, FTP or H.323), the inspect action also handles the
proper establishment of data sessions.
• Drop – To a deny statement in an ACL. A log option is also available to log the rejected
packets.
• Pass – To a permit statement in an ACL. The pass action does not track the state of
connections or sessions within the traffic. Pass allows the traffic only in one direction. A
corresponding policy must be applied to allow return traffic to pass in the opposite direction.
When determining how to set up zone-based firewalls the first thing you need to think of is the
different zones that need to be implemented. The infrastructure must be split into separate zones
with different security levels. Example the public network or internet to the inside network would
be split into two zones. Create the zones for the firewall with the zone security command.
You also have to set up policies between the zones. Remember by default when zones are
configured they deny all access to any other zone as well has non-zone interfaces. You must define
the type of traffic that will be allowed on the zone. Example would be TCP and UDP sessions
which are the most common, but there is also ICMP and others that can be defined. You want to
define the traffic classes with the class-map type inspect command.
After the zones have been identified along with the traffic requirements between them, the next
thing to do is design the physical infrastructure and policies this would be stating the number of
devices between the mission-critical devices and least critical devices and determining redundant
routes and devices if any. You would specify the firewall policies with the policy-map type inspect
command. Define the class-map name and you want that policy to do? Do you want the policy to
pass, inspect or drop the traffic specified by the class-map?
You want to apply the firewall policies the source and destination zones, by using the zone-pair
security command. What zone is the source? What zone is the destination? What policy-map are
you going to use by using the service-policy type inspect command.
The last setup is to identify a subset within zones and merge the traffic; the technician must
identify the connected interfaces and apply that zone to the interface, by using the zone-member
security command.
1. To recap, you must create a zone.
2. Then define the type of traffic that will be checked by the policy by using the class-map type
inspect command
3. Next, is define the firewall policies by using the policy-map type inspect command. You
what do you want to do with that traffic that you specified earlier with the class-maps (Pass,
inspect or drop)
4. Assign the policy-maps to the zone pairs, tell the router which policy is the source and
destination by using the zone-pair security command. Tell the router which policy to use by
using the service-policy type inspect command.
5. Finally apply that zone-pair to the interface by using the zone-member security command.
That is the rundown of zone-based firewalls! Look complex? If you start to understand it you will
find it easier to carry out than CBAC. Zone-based helps keep interfaces apart by blocking all traffic
unless allowed by the policies. Like before you can always find more information online. I
recommend Cisco.com for a full understanding of zone-based policy firewall, I hope this tutorial
was helpful.
mikrotik_zbf
Mikrotik script for zone based firewall implementations
WARNING
KNOWN ISSUES
Currently, if the router's got a service running that tries to access another service running inside it,
the firewall will block the connection (for instance, hotspot trying to do a request to user manager in
the same device), this is because the connection won't have any interface associated (it'll appear as
coming from an Unknown interface and going to an Unknown interface).
If this is your case disable the rules that block traffic from UNKNOWN interfaces in chains INPUT
and OUTPUT and it'll work.
NOTES
This is a really restrictive firewall, please study it first before implementing, for instance by default
traffic from the router to the outside zone (your ISP for example) is dropped, this will cause a
problem with your routes if you're using "check-gateway", you need to allow ICMP messages to the
gateway being tested in the "Firewall-to-Outside" chain.
The chains follow an specific pattern, don't mess with it, if you want to add a rule for a specific
traffic path do so at the specific chain (ie. traffic from inside to outside must be managed in the
Inside-to-Outside chain...) Also MAKE SURE, you add the rule before the rule tagged as
"DEFAULT-RULE" for that particular chain.
An easy way to do this is in winbox go to: IP -> FIREWALL - FILTER and filter based on chains
(using the button in the top right corner) then just copy the default rule, modify it to your needs and
drag it upwards. If you want to add more rules don't copy the DEFAULT-RULE just the ones
preceding it and they'll be automatically on top of it.
#ZONE BASED FIREWALL SCRIPT
#DEFINING SECURITY ZONES (SZ) MEMBERS
#PLACE THE INTERFACES BELONGING TO A ZONE SEPARATED BY COMMAS AND
INSIDE ""
#IF YOU DON'T WANT MEMBER INSIDE A PARTICULAR ZONE JUST LEAVE THE
VARIABLE INITIALIZED (AS IN REMOVE {} AND EVERYTHING INSIDE)
#THE RULES THAT ACTIVATE THE FIREWALL ARE BY DEFAULT DISABLED YOU MUST
ENABLE THEM MANUALLY
#AUTHOR: ING. RAFAEL CARVALLO
#DATE: 11/08/2017
#VERSION: 2.0
###THIS VERSION USES INTERFACE LISTS THIS FEATURE IS ONLY AVAILABLE IN ROS
>= 6.36
:local INSIDE {"bridge-local";"wlan1"}
:local OUTSIDE {"ether1"}
:local DMZ
#CREATING THE INTERFACE LISTS
/interface list
add comment="INSIDE ZONE" name=INSIDE
add comment="OUTSIDE ZONE" name=OUTSIDE
add comment="DMZ" name=DMZ
#ADDING THE INTERFACES TO LISTS
#INSIDE
:foreach x in $INSIDE do={
/interface list member
add interface=$x list=INSIDE
}
#OUTSIDE
:foreach x in $OUTSIDE do={
/interface list member
add interface=$x list=OUTSIDE
}
#DMZ
:foreach x in $DMZ do={
/interface list member
add interface=$x list=DMZ
}
#SETTING UP THE FIREWALL CONTEXT
/ip firewall filter
#REMOVING ALL THE PREVIOUS RULES INSTALLED
remove [find where !dynamic]
#SETTING THE INITIAL RULES
add chain=forward connection-state=established,related
add chain=input connection-state=established,related
add chain=output connection-state=established,related
:do {
#FROM-INSIDE JUMP RULES
add chain=forward action=jump jump-target=From-Inside in-interface-list=INSIDE disabled=yes
add chain=input action=jump jump-target=Inside-to-Firewall in-interface-list=INSIDE
disabled=yes
add chain=output action=jump jump-target=Firewall-to-Inside out-interface-list=INSIDE
disabled=yes
#FROM-OUTSIDE JUMP RULES
add chain=forward action=jump jump-target=From-Outside in-interface-list=OUTSIDE
disabled=yes
add chain=input action=jump jump-target=Outside-to-Firewall in-interface-list=OUTSIDE
disabled=yes
add chain=output action=jump jump-target=Firewall-to-Outside out-interface-list=OUTSIDE
disabled=yes
#FROM-DMZ JUMP RULES
add chain=forward action=jump jump-target=From-Dmz in-interface-list=DMZ disabled=yes
add chain=input action=jump jump-target=Dmz-to-Firewall in-interface-list=DMZ disabled=yes
add chain=output action=jump jump-target=Firewall-to-Dmz out-interface-list=DMZ disabled=yes
#FROM-INSIDE CHAIN
add chain=From-Inside action=jump jump-target=Inside-to-Outside out-interface-list=OUTSIDE
add chain=From-Inside action=jump jump-target=Inside-to-Dmz out-interface-list=DMZ
add chain=From-Inside action=jump jump-target=Intra-Zone-Traffic-Inside out-interface-
list=INSIDE
add chain=From-Inside action=drop comment="DEFAULT-RULE"
#FROM-OUTSIDE CHAIN
add chain=From-Outside action=jump jump-target=Outside-to-Inside out-interface-list=INSIDE
add chain=From-Outside action=jump jump-target=Outside-to-Dmz out-interface-list=DMZ
add chain=From-Outside action=jump jump-target=Intra-Zone-Traffic-Outside out-interface-
list=OUTSIDE
add chain=From-Outside action=drop comment="DEFAULT-RULE"
#FROM-DMZ CHAIN
add chain=From-Dmz action=jump jump-target=Dmz-to-Outside out-interface-list=OUTSIDE
add chain=From-Dmz action=jump jump-target=Dmz-to-Inside out-interface-list=INSIDE
add chain=From-Dmz action=jump jump-target=Intra-Zone-Traffic-Dmz out-interface-list=DMZ
add chain=From-Dmz action=drop comment="DEFAULT-RULE"
} on-error={
:error "Can't create initial jump rules, please check the interfaces names"
}
#DEFAULT FOR INTERFACES NOT LISTED INSIDE A SECURITY ZONE
add chain=forward action=drop comment="DROP ALL TRAFFIC IN FORWARD COMMING
FROM AN INTERFACE WITH NO SECURITY ZONE DEFINED" disabled=yes
add chain=input action=drop comment="DROP ALL TRAFFIC IN INPUT COMMING FROM
AN INTERFACE WITH NO SECURITY ZONE DEFINED" disabled=yes
add chain=output action=drop comment="DROP ALL TRAFFIC IN OUTPUT GOING TO AN
INTERFACE WITH NO SECURITY ZONE DEFINED" disabled=yes
#INTRA SECURITY ZONE TRAFFIC
add action=passthrough chain=Intra-Zone-Traffic-Inside comment="TRAFFIC THAT TRAVERSE
THE SAME SECURITY ZONE (INSIDE) - DEFAULT ACTION: ACCEPT"
add chain=Intra-Zone-Traffic-Inside
add action=passthrough chain=Intra-Zone-Traffic-Outside comment="TRAFFIC THAT
TRAVERSE THE SAME SECURITY ZONE (OUTSIDE) - DEFAULT ACTION: ACCEPT"
add chain=Intra-Zone-Traffic-Outside
add action=passthrough chain=Intra-Zone-Traffic-Dmz comment="TRAFFIC THAT TRAVERSE
THE SAME SECURITY ZONE (DMZ) - DEFAULT ACTION: ACCEPT"
add chain=Intra-Zone-Traffic-Dmz
#INTER SECURITY ZONE DEFAULT TRAFFIC RULES
add action=passthrough chain=Inside-to-Outside comment="FROM SZ:INSIDE TO SZ:OUTSIDE
- DEFAULT ACTION: ACCEPT"
add chain=Inside-to-Outside comment="DEFAULT-RULE"
add action=passthrough chain=Inside-to-Dmz comment="SZ:INSIDE TO SZ:DMZ - DEFAULT
ACTION: ACCEPT"
add chain=Inside-to-Dmz comment="DEFAULT-RULE"
add action=passthrough chain=Outside-to-Inside comment="FROM SZ:OUTSIDE TO SZ:INSIDE
- DEFAULT ACTION: DROP"
add action=drop chain=Outside-to-Inside
add action=passthrough chain=Outside-to-Dmz comment="FROM SZ:OUTSIDE TO SZ:DMZ -
DEFAULT ACTION: ACCEPT"
add chain=Outside-to-Dmz comment="DEFAULT-RULE"
add action=passthrough chain=Dmz-to-Inside comment="FROM SZ:DMZ TO SZ:INSIDE -
DEFAULT ACTION: DROP"
add action=drop chain=Dmz-to-Inside comment="DEFAULT-RULE"
add action=passthrough chain=Dmz-to-Outside comment="SZ:DMZ TO SZ:OUTSIDE -
DEFAULT ACTION: DROP"
add action=drop chain=Dmz-to-Outside comment="DEFAULT-RULE"
add action=passthrough chain=Inside-to-Firewall comment="SZ:INSIDE TO SZ:FIREWALL -
DEFAULT ACTION: ACCEPT"
add chain=Inside-to-Firewall comment="DEFAULT-RULE"
add action=passthrough chain=Outside-to-Firewall comment="SZ:OUTSIDE TO SZ:FIREWALL -
DEFAULT ACTION: DROP"
add action=drop chain=Outside-to-Firewall comment="DEFAULT-RULE"
add action=passthrough chain=Dmz-to-Firewall comment="SZ:DMZ TO SZ:FIREWALL -
DEFAULT ACTION: DROP"
add action=drop chain=Dmz-to-Firewall comment="DEFAULT-RULE"
add action=passthrough chain=Firewall-to-Inside comment="SZ:FIREWALL TO SZ:INSIDE -
DEFAULT ACTION: ACCEPT"
add chain=Firewall-to-Inside comment="DEFAULT-RULE"
add action=passthrough chain=Firewall-to-Outside comment="SZ:FIREWALL TO SZ:OUTSIDE -
DEFAULT ACTION: DROP"
add action=drop chain=Firewall-to-Outside comment="DEFAULT-RULE"
add action=passthrough chain=Firewall-to-Dmz comment="SZ:FIREWALL TO SZ:DMZ -
DEFAULT ACTION: DROP"
add action=drop chain=Firewall-to-Dmz comment="DEFAULT-RULE"
MikroTik Firewall Zones with Interface Lists
MikroTik, Best Practices
You can now get MikroTik training direct from Manito Networks. MikroTik Security Guide
and Networking with MikroTik: MTCNA Study Guide by Tyler Hart are both available in
paperback and Kindle!
Preface
Mikrotik's RouterOS doesn't yet have specific functionality built in for network "Zones" like some
other router platforms, but with new releases of RouterOS we can get the same functionality
through "Interface Lists". An interface list is just like a firewall address list, except instead of host
IPs or CIDR subnets we're listing physical or virtual interfaces. Once we've put interfaces into their
respective lists we can use those lists in firewall rules. If you have many interfaces, such as multiple
trunked VLANs or redundant WAN connections this could help you consolidate firewall rules.
Navigation
1. Zone Overview
2. Zone Types
3. Creating MikroTik Zones
Zone Overview
I like to group my interfaces into zones based on the trust level of the network that an interface is
attached to. Often we end up with "Trusted", "Semi-Trusted", and "Untrusted" zones, and some
additional zones as needed depending on how a network is built. How you split up your zones will
be dictated by your individual organization's security, compliance, legal, and operational
requirements.
Zone Types
It's easy to think of three zone types - Trusted, Semi-Trusted, and Untrusted.
Trusted Zone
Interfaces in a Trusted zone would be internal wired LAN or VLAN gateway interfaces, and
management interfaces. We have a reasonable level of trust that the hosts in these networks are not
trying to actively compromise our systems, and so we allow them to communicate (relatively)
freely. Access to these networks would require physically plugging into a port on-premise, and
hopefully port security is in place adding an additional security layer.
Semi-Trusted Zone
A Semi-Trusted network could be a point-to-point VPN to a vendor's network, or a corporate
wireless network. We must have these networks in place for legitimate business or organizational
reasons, but there is a chance that a bad actor could get access to these networks and we want that
breach to be contained if it occurs. Many organizations give these networks access to internal server
resources (Active Directory DCs, DNS servers, etc) as required, but access to other subnets or
services is forbidden.
Untrusted Zone
Untrusted networks are networks where we know or have reason to suspect that malicious activities
could occur, or do occur. A good example of an Untrusted connection is a connection to the internet
via an ISP. Port scans and malicious login attempts are very common out on the internet, and it's a
given that attackers are actively searching for soft targets.
Guest wireless networks are great candidates for a custom zone with some additional firewall rules.
It's still untrusted, because there's no telling what kind of devices might roam onto the network and
what kind of issues they may bring with them. But even though the network is untrusted, it still has
to forward traffic outbound to the ISP, and they may be allowed to resolve DNS names using an
internal server if split DNS is configured, or they will just use a public DNS like Google's 8.8.8.8
server.
One Interface List already exists, number zero, the "all" list. It can't be deleted, but by default it isn't
used anywhere either so it doesn't affect your security.
Now that we have lists we'll assign interfaces to the lists. In this case ether1 is our internet-facing
WAN address, ether2-5 are LAN ports, wlan1 is a corporate (encrypted) wireless network, and
wlan2 is an open (unencrypted) guest wireless network:
/interface list member add list=Semi-Trusted interface=wlan1 comment="Corporate
WLAN"
/interface list member add list=Untrusted interface=ether1 comment="Pacific
Telco WAN"
/interface list member add list="Guest Wireless" interface=wlan2 comment="Guest
WLAN"
/interface list member add list=Trusted interface=ether2 comment="LAN"
/interface list member add list=Trusted interface=ether3 comment="LAN"
/interface list member add list=Trusted interface=ether4 comment="LAN"
/interface list member add list=Trusted interface=ether5 comment="LAN"
With all of our interfaces in their respective lists we can use the lists in firewall rules. Having
multiple interfaces in a rule means you only need to put the interface list in one rule, and that rule
then applies to all those interfaces. For example, we can use an input-drop rule on all WAN
interfaces by applying that rule to the "Untrusted" list:
/ip firewall filter add chain=input in-interface-list=Untrusted action=drop
comment="Drop input from WAN"
We can allow all of our trusted networks on ether2-ether5 to forward traffic out the WAN to the
internet by using just one rule:
/ip firewall filter add chain=forward in-interface-list=Trusted out-
interface=ether1 action=accept comment="Trusted nets to internet"
When new interfaces are added to the router all that needs to be done is adding the interface to the
appropriate interface list, and the correct firewall rules will now apply. (adsbygoogle =
window.adsbygoogle || []).push({});
ip_firewall_filter.rsc
# jan/29/2018 22: 4:17 by RouterOS 6.41
#
/interface list
add name=public comment="public network"
add name=local comment="local network"
add name=guest comment="guest network"
# Change the interfaces below to your own
/interface list member
add list=public interface=ether1
add list=local interface=bridge
/ip firewall filter
# WARNING! All filter rules will be deleted
:delay 10
remove [find dynamic=no]
## Enable FastTrack for all zones
add chain=forward action=fasttrack-connection \
connection-state=established,related \
comment="Enable FastTrack for all zones"
## PUBLIC ---> ROUTER
add chain=input action=jump jump-target=PUBLIC-TO-ROUTER \
in-interface-list=public comment="PUBLIC ---> ROUTER"
add chain=PUBLIC-TO-ROUTER action=accept protocol=tcp dst-port=80 \
comment="DISABLE IT IF NOT NEEDED"
add chain=PUBLIC-TO-ROUTER action=accept protocol=tcp dst-port=22 \
comment="DISABLE IT IF NOT NEEDED"
add chain=PUBLIC-TO-ROUTER action=accept protocol=tcp dst-port=1194 \
comment="OpenVPN"
add chain=PUBLIC-TO-ROUTER action=accept protocol=udp dst-port=500,4500 \
comment="L2TP/IPSec"
add chain=PUBLIC-TO-ROUTER action=accept protocol=udp dst-port=1701 \
ipsec-policy=in,ipsec
add chain=PUBLIC-TO-ROUTER action=accept protocol=ipsec-esp
add chain=PUBLIC-TO-ROUTER action=accept protocol=tcp dst-port=1723 \
comment="PPTP"
add chain=PUBLIC-TO-ROUTER action=accept protocol=gre
add chain=PUBLIC-TO-ROUTER action=return
## PUBLIC <--- ROUTER
add chain=output action=jump jump-target=ROUTER-TO-PUBLIC \
out-interface-list=public comment="PUBLIC <--- ROUTER"
add chain=ROUTER-TO-PUBLIC action=return
## LOCAL ---> ROUTER
add chain=input action=jump jump-target=LOCAL-TO-ROUTER \
in-interface-list=local comment="LOCAL ---> ROUTER"
add chain=LOCAL-TO-ROUTER action=accept
## LOCAL <--- ROUTER
add chain=output action=jump jump-target=ROUTER-TO-LOCAL \
out-interface-list=local comment="LOCAL <--- ROUTER"
add chain=ROUTER-TO-LOCAL action=accept
## PUBLIC ---> LOCAL
add chain=forward action=jump jump-target=PUBLIC-TO-LOCAL \
in-interface-list=public out-interface-list=local comment="PUBLIC ---> LOCAL"
add chain=PUBLIC-TO-LOCAL action=accept \
connection-state=established,related,untracked
add chain=PUBLIC-TO-LOCAL action=drop connection-state=invalid
add chain=PUBLIC-TO-LOCAL action=drop \
connection-state=new connection-nat-state=!dstnat
add chain=PUBLIC-TO-LOCAL action=accept
## PUBLIC <--- LOCAL
add chain=forward action=jump jump-target=LOCAL-TO-PUBLIC \
in-interface-list=local out-interface-list=public comment="PUBLIC <--- LOCAL"
add chain=LOCAL-TO-PUBLIC action=accept
## GUEST ---> ROUTER
add chain=input action=jump jump-target=GUEST-TO-ROUTER \
in-interface-list=guest comment="GUEST ---> ROUTER"
add chain=GUEST-TO-ROUTER action=drop protocol=icmp
add chain=GUEST-TO-ROUTER action=return
## GUEST <--- ROUTER
add chain=output action=jump jump-target=ROUTER-TO-GUEST \
out-interface-list=guest comment="GUEST <--- ROUTER"
add chain=ROUTER-TO-GUEST action=return
## PUBLIC ---> GUEST
add chain=forward action=jump jump-target=PUBLIC-TO-GUEST \
in-interface-list=public out-interface-list=guest comment="PUBLIC ---> GUEST"
add chain=PUBLIC-TO-GUEST action=return
## PUBLIC <--- GUEST
add chain=forward action=jump jump-target=GUEST-TO-PUBLIC \
in-interface-list=guest out-interface-list=public comment="PUBLIC <--- GUEST"
add chain=GUEST-TO-PUBLIC action=return
## LOCAL ---> GUEST
add chain=forward action=jump jump-target=LOCAL-TO-GUEST \
in-interface-list=local out-interface-list=guest comment="LOCAL ---> GUEST"
add chain=LOCAL-TO-GUEST action=drop
## LOCAL <--- GUEST
add chain=forward action=jump jump-target=GUEST-TO-LOCAL \
in-interface-list=guest out-interface-list=local comment="LOCAL <--- GUEST"
add chain=GUEST-TO-LOCAL action=drop
## [Default policy] INPUT
add chain=input action=accept connection-state=established,related,untracked \
comment="[Default policy] INPUT"
add chain=input action=drop connection-state=invalid
add chain=input action=accept protocol=icmp
add chain=input action=drop
## [Default policy] FORWARD
add chain=forward action=accept connection-state=established,related,untracked \
comment="[Default policy] FORWARD"
add chain=forward action=accept ipsec-policy=in,ipsec
add chain=forward action=accept ipsec-policy=out,ipsec
add chain=forward action=drop connection-state=invalid
add chain=forward action=drop connection-state=new \
connection-nat-state=!dstnat in-interface-list=public
add chain=forward action=reject reject-with=icmp-net-prohibited disabled=yes \
comment="Forbid connections between networks"
# The next rule allows connections between networks. Enable the rule above to
# forbid that
add chain=forward action=accept
## [Default policy] OUTPUT
add chain=output action=accept comment="[Default policy] OUTPUT"