Blocking distractions with a Mikrotik router

I have a problem with HN. I spend way too much time there. While I owe it a lot of my career success, it's also my personal Kryptonite. I'm not the only one with this problem, and HN itself is aware of the phenomenon; the site offers a "noprocrast" mode (short for "no procrastination"), which temporarily blocks access to it server-side (as long as you're logged in) after you spent a configurable amount of time. Unfortunately, it's easy to trigger by accident (say, you refreshed a HN tab while switching between tabs in your browser), and I found that it doesn't really work for me. Neither does black-holing DNS on my machine (I have two others), or browser extensions.

What I need is the ability to disable HN (and occasionally some other sites) for a given set of hours during the day, for it to work across all my devices, not require ongoing configuration, and be a bit of a hassle to disable. Today I've managed to accomplish that, with the help of my Mikrotik router.

(As an aside, I recommend everyone who isn't afraid of technology to get a small-office grade router instead of the usual consumer stuff. Two well-known brands in this space are Mikrotik and Ubiquiti. The reason is the amount of control over your home network you get this way.)

There are four components to this solution: DHCP leases, NAT, Web Proxy and Address Lists. The general idea is: use a transparent Web Proxy whose only purpose is to black-hole undesired web traffic (or redirect it to a local site with productivity tips). Use NAT rules to redirect all requests from select devices to unwanted URLs at certain times to the Web Proxy. Assign static IPs to your personal devices via DHCP settings. Finally, use Address Lists to group together your devices on one list, and distracting sites on another, so that you need only a single NAT rule.

DHCP handling and setting Address Lists is easy. In WebFig interface, under IP/DHCP Server/Leases, find your devices and double click on each entry, then select "Make Static" (and change the IP if needed). Address Lists can be configured under IP/Firewall/Address Lists. You have to add each individual device/site address there, and Name option assigns them to appropriate lists, creating a new one if it didn't exist before. I've created two, blockme and my_devices.

Configuring NAT and Web Proxy is a bit trickier; misconfiguration risks cutting yourself off the router, so make sure that you leave out one device you use from the address list, in case you need to log back in and fix a mistake.

Here's my proxy configuration:

enabled: yes
           src-address: ::,192.168.xx.1
                  port: 8080
             anonymous: no
          parent-proxy: ::
     parent-proxy-port: 0
   cache-administrator: webmaster
        max-cache-size: none
 max-cache-object-size: 2048KiB
         cache-on-disk: no
max-client-connections: 600
max-server-connections: 600
        max-fresh-time: 3d
 serialize-connections: no
     always-from-cache: no
        cache-hit-dscp: 4
            cache-path: web-proxy

Most of these are default settings; two that you need to change is: src-address, where you put the address of your router/gateway (without the xx), and max-cache-size, which I set to none, because I only want a filtering proxy, not a caching one. Then, on Access tab, create a single, empty rule, with Action set to Deny.

For NAT configuration, I have again just a single rule:

;;; Filtering proxy - block unwanted websites during work hours
chain=dstnat action=redirect to-ports=8080 protocol=tcp src-address-list=my_devices
dst-address-list=blockme dst-port=80,443 time=8h-18h,mon,tue,wed,thu,fri log=no log-prefix=""

This is where the magic happens. It redirects both HTTP and HTTPS request to hosts from the address list blockme to the web proxy (port 8080), but only Monday-Friday, 08:00 - 18:00, and only for the devices on the list my_devices.

That's it! Enjoy your new, router-level anti-procrastination tool. As a bonus, you might want to find or create a page with motivational quotes, and change the Proxy settings to redirect requests there.