http:// qmail.jms1.net / djbdns / blocking.shtml

Blocking domain names with djbdns

One of the things that really irritates me is Internet marketing companies which use banner ads and "web bugs" (tiny images, usually transparent) to track who's looking at which web pages. It's none of their business which web pages I look at.

When I install a new machine, I almost invariably turn off cookies, scripting, and third-party images as soon as I run the browser. However, depending on the browser, these options are not always available. For example, Mozilla is the only one I've seen which allows you to block third-party images.

From what I've seen, almost all of these third-party images come from "ad server" domain names such as doubleclick.net (which was sued for correlating their cookies with personal information such as names and email addresses and then selling that information.)

I consider this to be a form of highjacking or theft, where my web browser is being used by somebody other than myself (i.e. as a device for gathering marketing data.) To put it very simply, I do not want my machines to send data to, or retrieve data from, these marketing companies. My browsing habits are none of their fscking business.


Finding a solution

There are third-party add-ons for some browsers which do part of the work- automatically deleting cookies, making "web bugs" more visible, and blocking images from known banner sources.

However, most of these solutions are non-free, and are only available for certain browsers, on certain platforms- an Internet Explorer add-on, for example, doesn't do much for Konqueror running under Linux on an UltraSparc, or Opera running on a Sharp Zaurus handheld computer (all of which I have done.)

Back when I was using BIND, I found that it was possible to deliberately "poison" the DNS server to make it appear that certain domain names didn't exist, by creating a zone file containing nothing but an SOA record, and having one or more "zone" blocks in the named.conf file pointing to that zone file. This page gives the specifics.

At first glance, djbdns didn't seem to have a way to do this. However, I came across a post on a mailing list which told how to do it by adding a second IP address to an ethernet card, and running a "poison server" on the second IP. This works by creating an instance of tinydns that returns "record not found", no matter what name is in the query.

My first thought was "what a cool idea!" I tried it on my test server and it worked beautifully... but I had to "borrow" an IP address from another machine in order to do it. It just didn't make sense to have to set up an IP address for something that would never be used outside the machine...

Then I realized that the localhost interface is also never used outside the machine. If only it were possible to add a second IP address to the localhost interface...

It turns out that with Linux, and with Mac OS X, you can. Most *nix-like systems have some way to attach multiple IP addresses to an interface. I would imagine that this same procedure can be used to attach a second IP address to the localhost interface.

If anybody knows how to do this with other operating systems and can write up a simple set of directions, send it to me and I will include it here.


Walk-Through

Our sample scenario will be a single workstation, such as a laptop. I am including examples for a RedHat Linux system, as well as Max OS X.

At this point you have a "poison server" which will answer ANY DNS query with "record not found" and with the authoritative bit turned on, which tells a caching resolver (such as dnscache) that there is no point in trying any other nameservers, that the "not found" answer is official.


Setting which domains are blocked

The final step, the crucial step, is to tell your resolver to use this as the DNS server for the domain names you don't want to ever see. The first part is to configure the domains you don't want to see:

# cd /service/dnscache/root/servers
# echo 127.0.0.2 > doubleclick.com
# echo 127.0.0.2 > doubleclick.net
# echo 127.0.0.2 > public.com
# echo 127.0.0.2 > cyberoffers.com
# echo 127.0.0.2 > x10.com
# echo 127.0.0.2 > atdmt.com
# echo 127.0.0.2 > atdmt.net
Similar for other domain names, the list goes on and on...

Once you have the list of domain overrides the way you want it, run these commands to activate them:

Still in the /service/dnscache/root/servers directory...
# chmod 644 *
# svc -t /service/dnscache

You can add more domains using the same procedure (creating a file in /service/dnscache/root/servers containing 127.0.0.2), and you can remove domains from being blocked by removing the same files. Remember to set the permissions correctly on the files (so that the "dnsrun" account can read them but not write them), and remember to restart dnscache after changing the files.

If you are going to block a massive number of domain names, this page tells about a Perl script which will read a single text file and create these files for you.

Here's another optional step which may or may not be useful for your system (it's a time-saver for me because I'm used to typing "make" whenever I change something.) Create /service/dnscache/root/servers/Makefile with the following contents:

all:
    chmod 644 *
    svc -t /service/dnscache

This allows you to just type make after making changes to the files. The files' permissions will be set correctly and the dnscache service will be restarted.


Another Reason...

Another use of this type of blocking would be in the prevention of UCE (Unsolicited Commercial Email, also known as SPAM.) Many mail servers can be configured to not accept email unless the "From" address is part of a domain name which actually exists. (For my servers, running qmail, this requires the mfcheck patch.)

If you are being plagued by SPAM which has return addresses ending with @cyberoffers.com domain (which I was in the past, this domain name does exist and is known to belong to a major spamming operation in South Florida) then blocking this domain will cause your mail server to reject any emails "From" this domain to be rejected, sparing you the SPAM.


Blocking "part of" a domain

One of the issues I ran into with my own server is the fact that the "to" TLD (top-level domain) seems to not be used by anybody other than spammers and porn sites... and by djb. The logs on my server showed that every email message which arrived claiming to be from a ".to" email address (with the exception of one specific domain) was spam. Obviously, by blocking "to" I would be able to reduce the incoming spam on my machine.

However, there is that one exception. The qmail and djbdns mailing lists are managed on a machine called cr.yp.to, which is Dan Bernstien's server. I certainly have no desire to cut myself off from these lists, or from being able to use lynx on my server to access the content of his web site.

The solution is to create an override file for "to" as detailed above, but also create an override file for "yp.to" which points to the real IP addresses of the nameservers for this domain. This allows this one domain (and its children) to function normally, while preventing any other ".to" domains from working.

The following shows how I set this up on my own server.

# cd /service/dnscache/root/servers
# echo 127.0.0.2 > to

# dnsqr ns yp.to
2 yp.to:
58 bytes, 1+2+0+0 records, response, noerror
query: 2 yp.to
answer: yp.to 86400 NS a.ns.yp.to
answer: yp.to 86400 NS b.ns.yp.to
# dnsip a.ns.yp.to b.ns.yp.to
131.193.178.181
131.193.178.160
# echo 131.193.178.181 > yp.to
# echo 131.193.178.160 >> yp.to

# chmod 644 *
# svc -t /service/dnscache

And yes, this (blocking the ".to" top-level domain) did reduce the amount of spam which was coming into my server... it wasn't the most dramatic change (I figure it blocks about 80-90 connections per day, where the server's normal traffic is about 10,000 per day) but I figure every little bit helps.


Other Systems

If your computer is running Microsoft Windows, you can accomplish the same thing using DNSKong. It's a "DNS proxy" which runs in the background on your machine, blocking requests for certain domain names and passing all other requests through to your normal nameservers (usually your ISP's nameservers.)


2005-08-28 Thanks to "marlowe" for pointing out a few typos on the page.