Foreword

It’s been a while since I talked about my projects on here. I started with the network that I showed in my post “Building a Hub and Spoke VPN with WireGuard” when I just came out of an entry level / apprentice position where I worked a lot with Cisco and Fortinet equipment, and it was the first time that I touched anything besides that.

During the last months I have come in touch with many other vendors (Palo Alto, Extreme Networks, HPE, Aruba and Juniper) and learned about how firewalling works in enterprise environments.

As I’m writing this, my new router arrived this weekend.
A MikroTik CCR2004-1G-12S+2XS.
So I took the time to rethink my firewall and found many interesting functionalities that MikroTik offers

Note that MikroTik firewalls are very versatile and I am definetely not using it to its full capabilities. There are much more advanced ways of handling traffic with MikroTik that I have not yet studied, like /ip/firewall/raw or /ip/firewall/mangle, nor have I ever really used the layer7 feature of MikroTik, or even stuff like jumping to custom chains.

The goal of this post is to highlight to newbies with MikroTik how you can achieve similar behaviour as you see with more popular firewalls like Palo Alto (Note that this is a brave comparison between two entirely different products: an NGFW and a Router)

Also you might grab some new ideas on how to design a network.

Let’s get into it.

Where to start?

Let me first define what I count towards “advanced” firewalling:

  • Use of Zones
  • Use of Address Objects
  • Strict segmentation of servers
  • Network-level segmentation of clients is not too important, preferrably you would find a way to deny intra-vlan traffic through features provided by a vendor (Blocking intra-VLAN traffic - Fortinet), or ACLs.

When starting to make a new set of firewall policies the basis of that is your network segments and interfaces, overall your network structure from the POV of your firewall.

For each topic where I get into a specific feature I will explain the structure that I used and naming convention.

What does the network look like?

Before starting with the firewall, you will need to analyze the network structure and see where you can group similar things together. Obviously in my home network I can just define all segments myself, in an existing infrastructure that would look different.

I created the following structure:

My Site subnet is a 10.X.0.0/16.

I made use of /24 supernets to /29 subnets. Each server that I have will get it’s own /29 subnet. In a /29 there is room for 4 hosts. So 3 hosts alongside the subnets gateway.

I did this because I might want to add another server into a subnet, maybe because it requires layer 2 connectivity to another host, maybe just for shits and giggles. I don’t know right know, but I have 65535 addresses available anyways and they don’t cost a whole lot (nothing). the number 29 also looks pretty.

On a more serious note, alongside the fact that I might want to add another host into one of the subnets, I want the same CIDR in all subnets. So I decided to make it a little larger in all subnets, rather than trying to plan ahead and have a mix of /30s and /29s. A bonus to this that I noticed that I can use the prefix 29 easily for filtering in scripting. For example :foreach subnet in=[/ip/route/find where dst-address~"/29"] do={/routing/ospf/interface-template add networks=[/ip/route/get $subnet dst-address]}

I can use those supernets in firewall policies for instance, to allow access from all servers to my DNS server.

I am using small segments to prevent lateral movement on layer 2 networks, as devices on the same VLAN can communicate directly to each other, if no ACLs filter that. By giving each device its own subnet I enforce they need to go over the gateway to reach any other host, which means the firewall policies will be applied to all traffic in my network.

Zones

A Zone is a list of interfaces that are strictly bound to this zone. A Zone object can be used in a firewall policy as either ingress or egress Zone. For example I could have 4 VLAN trunk interfaces that are all part of my Wi-Fi network. I can put these VLAN interfaces into the Zone Wi-Fi and use it in a policy to allow Internet traffic from Wi-Fi to WAN.

The benefit of Zones is that, if your interfaces should ever change, you don’t need to change anything about your firewall policies. Just add the new interfaces to the Zone and everything works as before

There are no Zones in MikroTik.

The feature that MikroTik provides is /interface/list and behaves slightly different. It’s still a list of interfaces, as the name suggests, but the interfaces have the ability to be in multiple interface list at the same time. Also a nice feature of that is, that you can include an interface list into another interface list.

I can’t actually think of a scenario where I would need that, but it’s still cool nonetheless lol.


I created these interface lists:

  • L3_WAN
  • L3_VPN
  • L3_DMZ
  • L3_0_Admin
  • L3_1_Server
  • L3_80_WIFI
  • L3_255_MGMT

I don’t think the first 3 need any explaining.

The naming convention includes a number at the second separator, which is equal to the value of the 3rd octet in the addresses that you find in this Zone (interface list).

For example:

  • L3_0_Admin = 10.X.0.0/24
  • L3_1_Server = 10.X.1.0/24
  • L3_80_WIFI = 10.X.80.0/24

Address Objects

Address Objects store a network address and can be used in firewall policies instead of just an address.

Again, that way I can change the underlying address without touching firewall policies.

In MikroTik there are address-lists instead of address objects combined with address groups, like you would see in a Palo Alto.

That is fine, as I can just create an address list that only stores one address, and add multiple in case I want to.

The only thing I’m missing here is address-lists to include other address-lists. Sadly this is not implemented.


I defined address objects like these:

  • H_srv-nas01
  • H_srv-radius01
  • H_deb.debian.org
  • N_ChaeynzAdmin
  • N_ChaeynzMgmt

H_ stands for Host
N_ stands for Network

MikroTik has a feature that I was not expecting, which is address lists containing DNS names. The DNS name will automatically be resolved and create a dynamic member of the address list for each IP address the DNS name resolves to. This is extremely useful, as IPs of websites can change a lot. Websites like Google have several different IPs that google.com resolves to, that also change from time to time. I don’t want to statically add the IP addresses of those to an address list, nor do I want to script that. Being able to just define a DNS name as value is good.

What can I do with this? Let’s get hands on:

This gives me the possibility to create a policy to allow traffic FROM H_srv-nas01 (whichever address that may be) TO H_deb.debian.org (whichever address that may be)

Policies

A great part of working with larger sets of policies is finding them. To make it quicker readable to the eye I found a naming convention for all firewall policies where I can look at the name and see what it does. At least vaguely.


I created the following naming convention:

  • <a/d> | Action | Accept / Drop
  • <n/u> Source Type | Network / User | (There is no user source in MikroTik FW as it doesnt provide an Identity Firewall, but I want the same naming convention across all Firewalls)
  • <app> | The Application that is being allowed by this policy | Note that I don’t apply the policy to a real application, but rather a tcp/udp + port combination. I used the name of the application I expect anyways, but theoretically any application could say they use tcp/80
  • <src-zone> | The in-interface-list in shortform
  • <dst-zone> | The out-interface-list in shortform
  • <target> | If applicable, the destination host / network

Each value is separated by a dot.

For example a policy that allows the admin network HTTP and HTTPS access would look like this:

Closing remarks

I know this was a comparably short post, but hopefully you find it useful.

Whenever I search for best practices I rarely find what I am looking for, so I tried to create something that I wish I had when getting into firewalling.

Sources: