06 Apr 2012 21:44
Recently I installed a CM9-based Ice Cream Sandwitch ROM on my HTC Desire and it's cool, but I found one thing extremely frustrating: the ads. They are everywhere and slow things down. I haven't noticed them before, because I always used AdAway (and AdFree before that), but with this ROM those ad blockers refused to work.
The problem seems to be the /system/etc/hosts file is real file on flash filesystem and if modified it can be only as big as 2 kilobytes, so regular host-based ad-blocking can't be used here. For some reason creating symbolic link to /data also fails.
I though the ad blocking can be done differently — by DNS server. If we can't put much to /etc/hosts file, let's set up a DNS server (say dnsmasq) that reads the hosts-to-be-blocked file and returns 127.0.0.1 for them and act as a proxy-DNS server for every other domain. But there was problem in settings DNS server in Android settings. It seems the ROM has hardcoded OpenDNS servers and you can only override this per each WiFi network. No way to do this for 3G.
But then I found, the ROM comes with iptables executable (possibly from busybox, haven't really checked) and more interestingly iptables-capable kernel. After a bit of trial and error (and Google searching) I found commands to redirect all DNS traffic comming from the phone to one predefined server:
iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 188.8.131.52
iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to-destination 184.108.40.206
The shell throws out one-line TODO (implement getprotobyname) errors but this is harmless to us. This is effective untill you flush iptables (with iptables -t nat -F) or reboot the phone.
At first I wanted to set up the ad-blocking DNS server myself, but I said, hey, someone just had to do it. I wasn't wrong, there were at least two relevant Google results for this: AdBarricade and FoolDNS. So you need to choose one and you're set.
But how do you compare those two? I mentioned I used AdAway and AdFree before and their block lists are very good (personal opinion), so I decided to download the hosts file generated by AdAway (it has the option to generate the hosts file anywhere, not just in plain /etc/hosts), shuffle it a bit and for top 1000 hosts check whether AdBarricade or FoolDNS block them. The results were:
FoolDNS (220.127.116.11): 744/1000 hosts blocked
AdBarricade (18.104.22.168): 234/1000 hosts blocked
For our purpose (measure by how many of AdAway-listed hosts are blocked) FoolDNS is a winner. That's why 22.214.171.124 was used in the iptables scripts above.
Once we have our DNS-based iptables-powered ad filtering, we may want to make it persistent. BCM ROM has a script that's called during boot process, it's /etc/boot.d/99bash and we can just append two abovementioned lines to it, to make the boot process run them each time the phone boots.