DNS based adblock using Mikrotik RouterOS

A few years back, I wrote a guide about using DNS based adblock with OpenWRT.  I have since moved on to using Mikrotik as my primary routing device and have implimented a similar DNS based adblock.  Here’s how I did it combining various resources online.

At the time of the last article, I was using one of those old, underpowered Linksys WRT54Gs.  You probably know the type I am talking about, the black/blue boxes made by Linksys when they were a standalone company.  After my network outgrew the old Linksys router, I “upgraded” to a Mikrotik RB951Ui-2HnD.  I say “upgraded” because I immediately flashed OpenWRT onto the device and never looked into RouterOS.  I forgot why I flashed back to factory firmware on the Mikrotik, but after using it for a while now, I can’t imagine using anything other than RouterOS, even good old OpenWRT.

The basic idea of DNS based adblocking is this:  any device on your network goes to a website and when that website has an advertisement on it, the ad is usually directed to a known advertising website for just that box/ad/display on the web page.  With DNS based adblocking, your browser tries to look up the advertising site, but is instead presented with a special dead IP address and the advertisement does not load.  This works network-wide across all devices including phones, tablets, computers, etc.

The Setup

  • Mikrotik router with at least 64 MB RAM free, not total
  • Mikrotik router running the latest RouterOS
  • Latest WinBox for Mikrotik
  • Some basic networking knowledge regarding IP routing, firewalls, etc.

The following config file contains a list of known advertising domains from http://winhelp2002.mvps.org/hosts.htm and pre-converted into Mikrotik’s config format.  Extract the DNS config file below and upload the .rsc into Mikrotik:

Download Mikrotik Adblock DNS Config

WinBox > Files > Upload... > mikrotik_adblock.rsc
WinBox > Terminal > /import mikrotik_adblock.rsc

This configuration will load a list of domains into the DNS static entries with an IP address of 240.0.0.1.  You can confirm the import by checking the DNS static records:

WinBox > IP > DNS > Static

Now we need to setup a firewall rule to block the special IP address 240.0.0.1.  When it comes to blocking via firewall rules, I prefer to use not use “drop” because this results in the requesting agent trying over and over until it times out.  Instead, we will give immediate feedback that the request is denied so our web browsers don’t hang up trying to load a page element.

Rejecting TCP attempts:

WinBox > IP > Firewall > Filter Rules > Add [+]
  General
    Chain: forward
    Dst. Address: 240.0.0.1
    Protocol: 6 (tcp)
    Connection State: new
  Action
    Action: reject
    Log: checked
    Log Prefix: ADBLOCK
    Reject With: tcp-reset
  Comment: Adblock tcp-reset

Rejecting UDP attempts:

WinBox > IP > Firewall > Filter Rules > Add [+]
  General
    Chain: forward
    Dst. Address: 240.0.0.1
    Protocol: 17 (udp)
    Connection State: new
  Action
    Action: reject
    Log: checked
    Log Prefix: ADBLOCK
    Reject With: icmp network unreachable
  Comment: Adblock udp unreachable

Rejecting all other attempts:

WinBox > IP > Firewall > Filter Rules > Add [+]
  General
    Chain: forward
    Dst. Address: 240.0.0.1
  Action
    Action: drop
    Log: checked
    Log Prefix: ADBLOCK
  Comment: Adblock drop

Make sure that our DHCP clients are using our Mikrotik as a DNS server:

WinBox > IP > DHCP Server > Networks > Edit Primary Network
  DNS Servers: <your Mikrotik IP>

Make sure that our Mikrotik is using OpenDNS for DNS lookups:

WinBox > IP > DNS
  Servers: 208.67.222.222
           208.67.220.220
  Allow Remote Requests: checked

Force all of our clients on the network to use our DNS, even if they try to use their own DNS servers:

WinBox > IP > Firewall > NAT > Add [+]
  General
    Chain: dstnat
    Dst. Address: [!] <your Mikrotik IP>
    Protocol: 6 (tcp)
    Dst. Port: 53
    In. Interface: <your LAN bridge/interface>
  Action
    Action: redirect
    To Ports: 53
  Comment: DNS Redirect (TCP)
WinBox > IP > Firewall > NAT > Add [+]
  General
    Chain: dstnat
    Dst. Address: [!] <your Mikrotik IP>
    Protocol: 17 (udp)
    Dst. Port: 53
    In. Interface: <your LAN bridge/interface>
  Action
    Action: redirect
    To Ports: 53
  Comment: DNS Redirect (UDP)

Hooray!  Now all of your network clients should be forced to use your Mikrotik’s DNS server which will use static entries for the known advertising/malware domains.

You will also be performing DNS lookups using OpenDNS, so you can setup an OpenDNS account and provide additional web content filtering using OpenDNS.  By default, OpenDNS will only filter out the really bad stuff such as known malware sites.  You have to enable additional content filtering under your OpenDNS account if you want a more strict web content filtering policy.

 Caveats

  • This method does not auto update.  There is a limit to what Mikrotik can handle as far as processing scripts and automating this.  You can find guides online for setting up a .php script on your own webserver to automatically download malware domain lists and create Mikrotik’s .rsc config for you.
  • Your device must have at least 64 MB RAM free.  Mikrotik’s DNS caching takes a lot of RAM.  It loads the entire static DNS list (13,000+ domains) into memory upon boot and does not read them from file when performing DNS lookups.  I have limited my domain list in the .rsc to only the list from http://winhelp2002.mvps.org/hosts.htm because of this.  There are guides out there that let you have lots of domain lists, but your Mikrotik’s performance will suffer and require more RAM.
  • Your Mikrotik will take longer to reboot.  Because the entire list is loaded into memory at boot, you will have a longer reboot cycle while the entire list is loaded into memory.  This setup on my RB951Ui-2HnD increased the reboot time from about 5-10 seconds to about 60 seconds.  Again, I am only using one domain list, there are guides out there that have 3-4 different domain lists and I would expect longer reboot times  and higher memory usage to reflect even more entries.
  • Some websites will complain you are adblocking.  Even if you disable other adblock browsing plugins, some websites will still complain.  I have also seen some video websites not playing videos because they are trying to show an ad before the video.  You can look into what domain is being used and disable or delete the static DNS entry to allow the website’s ads.

Aside from those caveats, the performance is fast after the Mikrotik is rebooted and ready.  DNS lookups are fast, and there is no noticeable difference in web browsing speed.

Happy Adblocking!

51 Replies to “DNS based adblock using Mikrotik RouterOS”

  1. Thank you for a great tutorial!
    Can you also mention how return to stock setting in case of negative affects.
    Thanks

    1. For some reason, I am not able to download the converted file from my network (which has a Mk). I tried from another place and ISP and downloaded fine.

  2. Thank you for this guide, work like a charm in my hAP2c with only one exception, there is no entry in the log

    11 ;;; adblock tcp reset
    chain=forward action=reject reject-with=tcp-reset connection-state=new protocol=tcp dst-address=240.0.0.1 log=yes
    log-prefix=”adblock”

    12 ;;; adblock udp block
    chain=forward action=reject reject-with=icmp-network-unreachable connection-state=new protocol=udp
    dst-address=240.0.0.1 log=yes log-prefix=”adblock”

    13 ;;; adblock drop
    chain=forward action=drop dst-address=240.0.0.1 log=yes log-prefix=”adblock”

    These are the last rules in the chain, so maybe this is the issue, however ad blocking is working, so I’m pretty sure traffic matches these rules and passes accordingly

    Any idea?

    1. Sounds like your Mikrotik did not have at least 64 MB of RAM FREE, NOT 64 MB total. Any device that runs out of RAM is likely to crash. You might want to look into resetting to factory default.

  3. Thanks, your explanation impressed me already when I read it in the blog post. I was just wandering if you made a rough measurement, just timing the load time of a particularly ad-ridden website or so.

    1. I have not timed it, but I have already noticed some performance differences when using reject vs drop firewall rules all around.

      It really depends on the application. When logging is turned on, you can sometimes see other ports being used besides the common 80/443. I haven’t been curious enough to packet sniff, so who knows what they are trying to do with their ad domain traffic.

  4. I’m proffered to 255.0.0.0 or 240.0.0.0
    On my opinion this is more productive rather than creating a rules that need to be processed. This is insignificantly if those DNS records less than 500. But if there more than 10k and users in your network 20+ it’s significantly.
    You can correct me if I’m wrong

    1. My method isn’t tested on a network at that scale. My little RB951 would cry with such a large network!

      Edit: Whoops, I thought you meant 10k network endpoints. I am running I think 13,000 DNS “adblock” rules, about 50-75 firewall filter, NAT, and mangle rules, 20/5 internet connection, with 8 in/out queue tree priority levels to keep everything moving (VOIP, gaming). I also have an isolated guest Wifi providing the neighborhood with a free WiFi hotspot. My internet speed is modern but not fast, Mikrotik’s CPU peaks around 50% when under full internet load.

      1. on small quantity of users it’s not big deal. But on tens of users on small office, it may on load your router.

        p.s. but it’s more short way to disable access:
        255.0.0.0 adwareserver.com

  5. What is the real-world difference between your approach using 240.0.0.1 and the widely used scheme of redirecting to 127.0.0.1?

    1. My technique is an amalgamation of several different adblock schemes I researched.

      127.0.0.1 is also known as “localhost” and is commonly used. It causes DNS lookups to try to utilize resources on the requesting device’s “self”. 99% of cases, there is no service running on the requesting device and the request likely goes into a timeout. When there is a service port running against an ad request, it can cause delays while the ad tries to run but doesn’t get the data it wants.

      Using 240.0.0.1, we force the requesting device to try to communicate outside of the LAN network. The key here is that we now have control over the attempt and can reply back (reject the packet) at our firewall with a tcp reset, port unavailable, etc.
      Rejecting packets instead of just dropping notifies the requesting service and leads to an instant failure rather than the application request getting dropped and retrying over and over due to no response.
      TL:DR; Not all advertisement applications request data over http(s) from their domains. 127.0.0.1 gives the adblocker less control over the connection attempt.

Leave a Reply

Your email address will not be published. Required fields are marked *