Friday, December 10, 2010

Whitelist filter with transparent Tinyproxy and Firehol

I'm a dad with 5 small children. Letting them onto the internet without any restrictions would be as irresponsible as not teaching them how to use the internet. So I decided to filter the traffic. First I tried OpenDNS' FamilyShield. That works great with english sites, but it does let through hungarian porn sites for example. Hence I decided, a whitelist would be a more suitable solution. I looked for some applications, the most obvious choice was Dansguardian. Dansguardian needs a proxy, Squid is the recommended one, but many bloggers recommend tinyproxy as a more light-weight alternative. Looking at Tinyproxy, I soon realized, that it supports filtering even as whitelist. No need for a big gun, Tinyproxy should suffice, I thought. And I was right. But first... and now comes the story, and through this you will see why I love open source.

In Archlinux, installing Tinyproxy takes this:

pacman -S tinyproxy

Here is what I have changed in the /etc/tinyproxy/tinyproxy.conf file:

FilterURLs On
FilterDefaultDeny Yes
Filter "/etc/tinyproxy/whitelist"

For the meaning of those settings please refer to the very file, comments are extensive.

So, I logged into my son's account and set Firefox' proxy to localhost:8888. Now nothing but the entries in the whitelist were shown, everyting else was filtered. Nice. There is another browser, Konqueror, which needed to be proxied as well, and we were set. Wait... really? I found some problems with this setup. First, my son can change the proxy settings anytime he wants, and second, I have to do the same procedure for all my kids accounts. Well, the first case can be solved by locking the proxy settings in Firefox and in KDE4 with the awesome Kiosk Admin Tool. The second case just requires some handywork. And, what if I dont know the passwords?

Spoiled by Archlinux as I am (ie. striving for perfection), I decided to look further. I already heard about transparent proxies, so I looked into the README of Tinyproxy, and quickly learned that it does support transparent proxy mode, all it takes is to compile it with the "--enable-transparent-proxy" switch. I checked the Archlinux package, well, it was compiled without that switch. No problem, this is why we have the wonderful ABS system. Using Bauerbill, recompiling a package is easy:

bauerbill -S --abs tinyproxy

I added the switch in the PKGBUILD and couple of seconds later I had my brand new tinyproxy package installed. Next thing was to setup the firewall. I'm using Firehol, and there is a wonderful command to reroute traffic to the proxy:

transparent_proxy "80 443" 8888 "nobody root bin my wife's acc and mine"

That routes all requests to http and https ports to the proxy, except for those users listed. To my surprise, Tinyproxy answered with a page that said "Unknown method or unsupported protocol", as if Tinyproxy were not compiled with transparent support. I went to the IRC channel, where I lingered for quite some days until I got an answer. There was a guy who just got into Tinyproxy two days before. Long story short, he pointed out that the compile switch should be

--enable-transparent

I searched google, looked into the README, and every reference I could get my hands on stated the opposite. But that guy looked into the source code and that is what counts, no questions asked (later I asked one of the devs about this, and he admitted that this switch was changed in 2004, but no docs were updated, lol). So, I quickly recompiled Tinyproxy, and lo and behold ... well ... it behaved differently. Now it stated that the page was filtered, even for urls that definitely were included into the whitelist. Simply every page got filtered. I rechecked the situation by simply setting the proxy again in Firefox, and this time it worked correctly. So Tinyproxy behaved differently when working as transparent proxy. What can a poor man do if he cannot code? File a bug report of course :) But as an experienced bug reporter, I first checked if someone else had already reported it. Sure enough there was already a bug report several months old. The last comment was from the developer, saying "I'll look into it". But there was another very important piece: a patch! The user who reported the bug was apparently a programmer and provided a patch with the bugreport as well. Whohoo, I immediately applied the patch to the source, and yes, you guessed it, Tinyproxy finally worked flawlessly in transparent mode.

Of course I reported my success to the devs, and the next day the patch was included into the official git repository, ready to be compiled. The README is corrected as well :)

I have set up an AUR package named tinyproxy-git for anyone who wants to try it. Just use Bauerbill:

bauerbill --aur -S tinyproxy-git

The morals of the story? The developers often just need some people who are interested in using their product and are willing to test, try and report issues, and most importantly, thank them for their work and encourage them to continue. I saw this happening many times, recently with the fish shell for example. I you like a particular product, get involved in any way you can, be an optimist, and never take it for granted.

Sunday, February 21, 2010

Rescuing a CD in Archlinux

I have a CD with our favorite movie on it: Bud Spencer - Soldier of Fortune. I promised to my son to watch it together with him. Unfortunately the CD was faulty, KDE didn't recognise it. My son was so sad, I just had to do something about it.

tail -f /var/log/kernel.log

revealed "Buffer I/O error on device sr0, logical block 326084". After some failed attempts and reading some 'man mount' I found out how to mount the CD:

mount -r -t iso9660 -o nofail,ro /dev/sr0 /media/cd/

After this, ls /media/cd/ did show the file on the CD. Time to use the almighty dd utility. I found this blog entry to be very helpful:

http://decio.blogspot.com/2007/06/how-to-recover-files-from-damaged-cddvd.html

(On a side note, it seems the author of this blog uses GoboLinux, well done!)

So the command to rescue my CD was:

dd if=/media/cd/Zsoldoskatona.avi of=/tmp/Zsoldoskatona.avi bs=512 conv=noerror,sync

And we were able to watch the movie!