Saturday, October 17, 2020

Effectively Internet Filtering in 2020

(To skip my rambline intro and get to the nitty gritties, search this page for, "After that long introduction")

In college, back when the internet was young, I hated the clumsy ineffective internet filtering that was in place on campus. It often blocked sites that were perfectly fine, and did not catch all the sites of the type that they were trying to block. Fast forward 10 years or so and I saw my children stumbling upon some content that I didn't want them to see on my unfiltered home internet and my attitude changed a bit. Back then web filtering was pretty easy. Nothing was encrypted and DansGuardian was the go-to tool. You set up a transparent web proxy and DansGuardian would scan the entire content of every website that you downloaded in your home. Incriminating words and phrases would trigger its blocking and it would replace the website you were downloading with an explanatory message. The beauty was that there was no need to scour the web, categorize every website in the world, and maintain lists. It still had its false positives and if a website hand objectionable images but otherwise benign text there was nothing it could do, but it took the edge off the raw internet.

Today, it's not so easy. The HTTPS Everywhere campaign bothered me at first. It felt unnecessary, and it most definitely broke my DansGuardian filtering. I have since come to understand the importance and necessity of HTTPS and I'm very glad that Let's Encrypt has made it easy for all of us to use it. But I do still have kids.

DNS filtering came to the rescue, first with OpenDNS, and now I use CleanBrowsing. It's pretty good, but sometimes I want more control. One night our school had a parent-night presentation about internet safety for kids and they had invited some vendors to pitch their wares. One of them was RouterLimits. They had a small box that you simply connected to your network and it would filter internet traffic based on categories or individual sites you listed. No software or configuration of other hosts or your router required. It could also enforce time windows with no internet. "How is this possible when this box is just another client on the LAN?" I pressed their salesman. It was a small company and I think he was also an engineer because he realized I was one, and he slyly said to me, "ARP spoofing."

"That's evil!" I instinctively replied. And then I thought a little more about it and realized it was evil. Evil genius! I bought one right there. Their model was great. Pay $80 for $5 worth of hardware and you get their service for life. Plug the little box into your LAN and connect to their web service. The little box collects a list of hosts on the LAN by paying attention to broadcast traffic, then it floods each host with ARP replies to tell them all that it is the gateway and begins its Man in the Middle attack. If a kid tries to visit badsite.example.com, or any site during the time window when internet is configured to be off for their device, the RouterLimits box sees that and just drops the packet. If a kid tries to visit goodsite.example.com, the RouterLimits box simply forwards the packet along to the actual gateway. Simple and very effective.

The schedule was the thing I loved the most. I had never had that with DansGuardian or CleanBrowsing alone. Sadly, RouterLimits was bought by a bigger company that changed the business model to a yearly subscription. Also, right about the same time, the RouterLimits box lost its ability to block my Roku for some reason. Kids were watching Netflix late into the night on school nights again, dang it. I worked with the RouterLimits support team a bit, but they couldn't figure out what was going on. I wasn't super motivated to debug it myself, because I didn't want to start paying a regular fee for this service anyway.

I still wanted my kids kicked off the internet at a decent time on school nights, though, so I started looking for solutions. The first thing I tried was a pi-hole. It doesn't have scheduling built-in, but I was able to hack together a script that modified the pi-hole database directly to put my kids' devices into a group that had a blocklist that filtered everything. That mostly worked, but it was really a hack. And then my raspberry pi's SD card died and I didn't have a backup. I started looking for another solution. I remember ARP spoofing and did a little research. Sure enough, there is a tool called ettercap that make it pretty easy, especially if you just want to block everything.

After that long introduction, some nitty gritties. To run ettercap in text-mode and see what it can do, run this command:

sudo ettercap -Tq

Play around with it a bit, it's pretty cool.

To filter (perform a Man in the Middle Attack), you'll want to scan and save a list of hosts on the LAN, like so (change the 1000 to your user ID):

sudo env EC_UID=1000 ettercap -Tqk lan-hosts

To man-in-the-middle a host with IP 192.168.1.193, and if your gateway is 192.168.1.1, run this:

sudo ettercap -Tq -M arp:remote /192.168.1.1// /192.168.1.193//

For me that didn't really do anything because it simply forwarded the packets it was intercepting on to the gateway. To do something with the packets ettercap is intercepting, you need to create a filter. My filter is simple, just drop every packet:

drop();

Put that in a text file named drop-all.ecf and run this to compile the filter

etterfilter drop-all.ecf -o drop-all.ef

You can read the ettercap-filter man page for more information about what you can do. I image the RouterLimits box had some more interesting filters (assuming they were using ettercap).

Once you have your filter compiled, add it to the above ettercap command like so:

sudo ettercap -Tq --filter drop-all.ef -M arp:remote /192.168.1.1// /192.168.1.193//

You have successfully performed a Denial of Service attack against 192.168.1.193. If you have, for example, two kids devices you want to block, you need the lan-hosts file you made earlier, and you do this:

sudo ettercap -Tz -j lan-hosts --filter drop-all.ef -M arp:remote /192.168.1.1// /192.168.1.193\;192.168.1.221//

You can add as many ip addresses as you like to list, separated by semi-colons. As far as I can tell, they all need to be listed in lan-hosts too. I believe you could use MAC addresses instead of IP addresses, but I have my router giving out fixed IP addresses to all my kids devices (that was to make the pi-hole hack work), so I just use the IP addresses.

All that's left is to run ettercap with --daemon, make a cron job or systemd timer to start and stop it at the times you want to block your kids' internet access, and you are done! It just so happens that I have written an ansible playbook that does all this for you. You'll have to modify lan-hosts and the internet-stop.service to use your own devices MAC and IP addresses, then run ansible-playbook to deploy this to a raspberry pi (or some other linux box on your LAN that you leave on all the time) and you are good to go.

P.S. This even block the Roku. ettercap couldn't detect the Roku on my LAN like it could other hosts for some reason, so that's probably why Router Limits couldn't block it, but once I manually entered the Roku's IP and MAC into the lan-hosts file, ettercap was able to DoS it just like all the other hosts.

No comments: