GeoIP Blocking and Suricata on MikroTik CCR2116 Using Docker

Unlike UniFi, MikroTik RouterOS does not have built-in GeoIP filtering, which has always been a bit disappointing.

However, with Docker now available on MikroTik, RouterOS has become much more flexible. It is possible to add third-party applications and services that are not natively supported by RouterOS.

Of course, there are still some limitations, and not every Docker application will work on the router. But for my home lab, I have found it surprisingly useful.

I couldn't find a suitable Docker solution for GeoIP blocking on MikroTik, so I asked Claude for some help and decided to build my own.

The result was a great success, and I'm very happy with how it turned out.

First, I obtained the GeoIP database from MaxMind and set up the API key. Then I created a Dockerfile along with a Python application and built an ARM64 Docker image using Docker Buildx on my Debian machine.

I then imported the image into the MikroTik container environment and ran it directly on my CCR2116.

The application generates the IP lists by country and imports them into the MikroTik firewall address-list.

I decided to allow only four countries:

  • KR — South Korea
  • TW — Taiwan
  • LV — Latvia
  • US — United States

Everything else is blocked.

The reason for allowing these four countries is simply based on the services I use:

  • South Korea — local connections
  • Taiwan — Synology NAS
  • Latvia — MikroTik-related IPs
  • United States — Cloudflare

The US list was the biggest challenge. It contains almost 100,000 IP addresses, and the text data is more than 25 MB.

MikroTik could not handle importing the entire list at once, so I modified the application to split the address list into multiple chunk files.

Each chunk is around 2 MB, and MikroTik imports them sequentially. This works without any problems.

I also made all of the important options configurable through the container environment variables, so there is no need to rebuild the Docker image whenever I want to change the configuration.

Finally, I apply the blocking at the RAW firewall level.

The resource usage is surprisingly low. The container and related processing use around 2 GB of memory, while CPU usage is usually only around 3–4%.

For a CCR2116, this is more than acceptable.

With this setup, I now have three major security/networking functions running directly on my MikroTik:

  • AdGuard Home — DNS filtering with DoH/DoT
  • Suricata — IDS/IPS
  • GeoIP Block — country-based IP filtering

Suricata is currently running on a separate mini PC, but I am also considering building a lightweight, GUI-less version and running it directly inside a Docker container on the CCR2116.

That would be quite interesting.

I have to say, Docker support on MikroTik is turning out to be a really big deal.

If RouterOS doesn't provide a particular feature, you can sometimes simply build or deploy the functionality yourself.

There isn't anything particularly flashy about this setup, but it is surprisingly powerful and solid.

When I originally bought the CCR2116, I installed a 1 TB NVMe drive. At the time, the price was almost at its lowest, so I thought 1 TB would be more than enough.

Now that I'm running multiple Docker applications and accumulating logs, I kind of wish I had gone with 2 TB instead. :slight_smile:

At the moment, CPU usage across the system is still below 10%, so performance is excellent. The main concern now is simply how quickly the logs and other data will accumulate.

Most of the security/blocking rules I'm using are from free sources rather than paid services. For a home lab, the free rules are more than sufficient.

So, little by little, I've managed to move almost everything I need directly onto the CCR2116.

AdGuard Home, Suricata, and now GeoIP blocking — all running through Docker on the MikroTik.

This is probably one of the things I like most about RouterOS.

It may not have every feature built in, but with Docker, you can sometimes just build what you need.

If it doesn't exist, build it.

That's what makes MikroTik so much fun. :slight_smile:

well this is one of the problems that can 'almost' be solve using routeros alone.

fetch https://stat.ripe.net/data/country-asns/data.json?resource=ru
parse json and populate firewall ip list

except you can't because fetch command is limited to 32k of data
i asked if they would consider increasing that limit and they said 'no'

Can the container get access of the RouterOS file system ?
Then you and the container builder can fetch this from inside of the container and save to RouterOS file system. Maybe that your saying.

why do you need containers at all?
if that limit was high enough you could have geoblocking by fetching ip lists directly from ripe in a simple script.

If you fetch over 150,000 IPs, you will understand why you should use Docker.