Saturday, November 5, 2016

Scheduled blocking of websites using cheap routers

Searching for how to block Facebook on a schedule, you can see how complicated it is. Actually, just blocking a site like this is complicated by itself because of the many IP's it could use.

You may want to block youtube, gaming and social time-wasting websites, but allow two hours of access in the evenings every day. The amount of IP's to deal with is phenomenal. Also, nowadays many sites use the https protocol so URL-based blocking won't work. Somebody set up a proxy server on an old laptop to filter the web contents, but both the installation and maintenance are troublesome.

I find the DNS based solution very simple. In DD-WRT, a line in the /tmp/hosts file can block the whole site:

10.0.0.1  www.youtube.com

where a non-reachable IP is assigned to the external website. So you just need two versions of the hosts file, and restart the DNS service dnsmasq after the file is changed. Then you need two scripts as cronjobs, for example:

0   22   *   *   *   root  sh /tmp/stop.sh
0   20  *   *   1-4  root sh /tmp/go.sh
0  19  *  *  0,5,6 root sh /tmp/go.sh

At 22:00 every day, youtube and others sites are blocked. On weekdays except  for Friday, movie time starts at 20:00, but earlier on other days at 19:00. The schedule can be entered via GUI on the Administration > Management > Cron box.

The "root" prefix is the one thing that I hate developing anything for dd-wrt. Cookbook instructions are good enough for me. You need that to run the commands with root privilege, or it wouldn't work. Because of its limitations, it mostly does something different from Linux, even though the source codes have the same origin. There are full of landmines like this and the system can never be documented enough. Even if there are documents, the functions may not work on your build version because of different chipsets and manufacturers.

To modify the hosts files and 3-line scripts, save a startup script at the Administrations > Commands tab:

cp /tmp/hosts /tmp/hosts.go
echo "10.0.0.1   www.youtube.com">>/tmp/hosts
cp /tmp/hosts /tmp/hosts.stop
echo "cp /tmp/hosts.go /tmp/hosts"> /tmp/go.sh
echo "stopservice dnsmasq" >> /tmp/go.sh
echo "startservice dnsmasq" >> /tmp/go.sh
echo "cp /tmp/hosts.stop /tmp/hosts" > /tmp/stop.sh
echo "stopservice dnsmasq" >> /tmp/stop.sh
echo "startservice dnsmasq" >> /tmp/stop.sh
Basically, it's adding one line per website on the hosts file to be blocked.

The blocking is not necessarily immediate because of the browser cache. My observation shows that the cache expires in a few minutes at most. That means if you have been watching youtube movies less than a few minutes when the blocking starts, you may still be able to access youtube for a few more minutes. Once you stop accessing youtube for a few minutes, you cannot access it again during blockage hours. I doubt if that makes a loophole. But this can easily be plugged by enforcing a total internet ban for a few minutes, for only those IP's assigned to kids.

Now, the blockage affects everybody using the router as the DNS nameserver. For adults, you can use public servers such as the google ones at 8.8.8.8. You have to do it on every adult machine. For the kids' machines, you can use the DD-WRT access restrictions to block port 53, so all DNS requests are rejected if they try to hack, forcing the default name server 192.168.1.1 to be used. To select the affected machines, only the IP range works on my version of DD-WRT.

MAC-based restrictions mostly don't work on my version. So I have to use Static Leases on the Services tab to assign IP's to machines by their MAC's. It should be noted that it is rather easy to change IP's on any machine to defeat blocking. A simple solution will be a script to police the lease table at regular intervals and send me an email if the same MAC has other IP's assigned. It would be rather painful to develop on the router but a lot less hassle using an old laptop with Linux installed.

I also use OpenDNS for the underlying web filter. It's about the only DNS filter that allows you to customize categories to block, to whitelist and blacklist. For example, I disable all search engines but whitelist Google. So I can concentrate on getting the SafeSearch mode working on Google. The same way I disable all video sharing sites but whitelist youtube, so I can concentrate on making the restricted mode work. The router is setup to allow these sites through. Once they are working fine, I can block each site with a line in the hosts file.

The other interesting approach I tried is to install a parallel DNS nameserver on an old laptop with Linux installed, on the same wifi network. It is trivial to install Dnsmasq and works in no time. You just need to point to that machine IP for the DNS nameserver. It's the same Dnsmasq on DD-WRT but on a more powerful machine, with lots of memory and hard disc space. More fancy things can be done but the blocking above can be done by two static hosts files, one on the router and one on the Linux machine. You just need to change the nameserver file at the router, for the request to either go straight to OpenDNS or via the Dnsmasq at the laptop. But you have to make sure that the hard drive is not constantly used. The /tmp directory in dd-wrt is a RAM drive.





0 22  *  *  *  sh /tmp/stop.sh
0 20 * * 1,2,3,4  sh /tmp/go.sh
0 19 * * 0,5,6 sh /tmp/go.sh

No comments:

Post a Comment