Building a DNS Blackhole with FreeBSD

Building a DNS Blackhole with FreeBSD


This document will outline how to setup FreeBSD to act as a DNS Blackhole (DNSBH).

What is a DNS Blackhole and why would I want one?

A DNS blackhole (DNSBH) in its simplest form is just a box running bind that maintains a listing of malicious domains. When clients request a 'flagged' domain they will be redirected to either themselves (localhost), or to a safe local location that explains to the user why they just ended up where they did.

Keep in mind that this isn't an inline device and depending of the deployment strategy can be easily bypassed. That being said, It is low cost, low maintenance, somewhat flexible and if deployed correctly can still  be quite effective at threat mitigation.

The real truth is in the numbers though. Our deployment blocks on average 1000 requests/day. Even if only 1% of that would have led to an infection, the hardware and operation costs of the device would be recouped in a couple weeks.

Hardware Requirements

The beauty of this solution is that it requires very little horsepower. My first incarnation consisted of Dell Optiplex desktop. This bad boy had 1GB of RAM and a dual core Pentium 4 processor@3.00GHz complete with an 80GB SATA drive. This served 5000 clients without any issues.

The second incarnation I spec'd up a bit because I was interested in running IDS components on the inbound requests to see if there was added value to this approach. The incumbent is a 2U server with 2 dual core processors@2.8GHz and 5GB of RAM. It also has RAID. This is overkill of course but it opens up some data mining possibilities.

How to configure BIND

Most everything you need is already available on a base install. I usually start with a custom install, use the Kern-Developer distribution (somewhat minimalistic) and also grab the ports tree.

Once the box is up:

1) Edit /etc/rc.conf and make sure it has (add where necessary and substitute your interface name, gateway, etc.) The IP address of this server will be


ifconfig_bge0="inet  netmask"









Save and exit the file.

2) Edit /etc/hosts:

::1              localhost bhdns    localhost bhdns bhdns

Save and exit the file.

3) Edit /etc/resolv.conf and add:



nameserver <upstream provider>

Save and exit the file.

4) Now take a look at /etc/namedb. The file is well documented. These are the changes/additions that you should make:

In the options section you need to add an entry to allow clients access. This fictitious install is on a 10 network so it would look like:

allow-query {; };

Next you want to set the address that the service will listen on. Use the same address you set in rc.conf:

listen-on {; };

Now you can set up a forwarder, in my case the same one used in /etc/resolv.conf:

forwarders { <upstream provider>; };

This isn't a requirement but by using a forwarder you will take advantage of a more local cache which will increase performance.

The rest of the settings you can gloss over (unless you want to do more than just DNSBH). At the very end of the file though, you want to add the actual block lists. You can have as many as you wish but to keep things simple I will focus on a single list from a single source. I will use the list from malwaredomains as an example:


include "/etc/namedb/blackhole/spywaredomains.zones";

Save and exit the file.

5) Create a folder called blackhole (same location you specified above) and fetch the zonefile:

~# mkdir /etc/namedb/blackhole

~# cd /etc/namedb/blackhole

~# fetch

This file contains entries that look like:

zone ""  {type master; file "/etc/namedb/blockeddomain.hosts";};

With this loaded, any client request for will be redirected to whatever we have set up in /etc/namedb/blockeddomain.hosts. Essentially, all we are doing is mapping all of the domains listed in that file to the same DNS (A) record.

Lets create this record now.

6) Edit /etc/namedb/blockeddomain.hosts:

; This zone will redirect all requests back to the blackhole itself.

$TTL    86400   ; one day

@       IN      SOA (


                          28800   ; refresh  8 hours

                          7200    ; retry    2 hours

                          864000  ; expire  10 days

                          86400 ) ; min ttl  1 day



*               IN      A

Save and exit the file.

Note: You can redirect the request to anywhere you wish but it is worthwhile to send the user to a place that explains what just happened. If not, the user might get confused and open a vague "The Interweb is broken" helpdesk ticket.

We should be good to go. Try and start the service:

~# /etc/rc.d/named start

For debugging (or other) reasons it might be worth it to separate named logs from the syslog catchall. To do this, edit /etc/syslogd.conf and add:


*.*                                             /var/log/named.log

Save and exit the file and then:

~# touch /var/log/named.log

~# /etc/rc.d/syslogd restart

How to automate the update process


To make things a little easier, I made a simple script to manage the update process. The script does the following:

1) Fetches the zonefile or lists of domains

2) Performs a comparison with the current file, if there are no changes, exit. If there are then

3) Make note of the additions/removals

4) Put the new zonefile in place

5) Restart the service

6) Email the changes to an admin

The script of may need to be modified if you intend to run it on a system other than FreeBSD. There are some hard paths in there as well. If you can't figure it out, just shoot me an email.

You can grab the script from here or just follow the steps below.

1) Download

~# cd /etc/namedb/blackhole

~# fetch

~# chmod +x /etc/namedb/blackhole/

2) Create the temp directory:

~# mkdir /etc/namedb/blackhole/work

3) Add an entry to roots crontab to run the script daily:

~# crontab -e

once the editor comes up, input the following line:

0    0       *       *       *       /etc/namedb/blackhole/ > /dev/null 2>&1

Save and exit the file.

This will update the file every day at midnight.

My bash is pretty shoddy so you might want to test it out first :)

~# /etc/namedb/blackhole/

If it doesn't work, send me an email and I will try and help you out.

How to setup Apache to provide an information page

As I mentioned earlier, to avoid confusion it is a good idea to send the users to an information page. You can use any web server here, Apache is way overkill but its what I know.

1) Install Apache. You can do this however you wish, I will just use the ports tree:

~# cd /usr/ports/www/apache22; make install clean

2) Edit /usr/local/etc/apache22/httpd.conf and make the following changes (in order of appearance):




DocumentRoot "/usr/local/www/dnsbh"

ErrorDocument 500 /404.html

ErrorDocument 404 /404.html

ErrorDocument 402 /404.html

The rest of the defaults are fine.

3) Create the web directory:

~# mkdir /usr/local/www/dnsbh

4) Create /usr/local/www/dnsbh/index.html this will be the main landing page when folks are redirected:

<!DOCTYPE html>



<title>Your Org Name - IT services</title>

<script type="text/javascript">url = parent.window.location.href;</script>



<h3>Security Notice...</h3>

You have been redirected to this page because the website that you tried to visit has been known to harbor

or distribute Spyware, Viruses or other forms of malicious software.


As part of our Information Security Policy we maintain a listing of potentially harmful sites to assist in the protection and stability of our computing resources. This is also done to protect users from divulging personal information to third parties where it could be used for illicit purposes such as Spam or Fraud.


If you feel your access to this web site is a requirement, contact your local Information Technology Services department for assistance.



Save and exit the file.

5) Create /usr/local/www/dnsbh/warn.png. This image should be around 127 X 57 pixels and contain something that identifies your organization along with something that conveys 'warning' either through words or images.

What happens is a lot of ad space can point to blocked domains and while the core site loads OK, you end up with your warning index document trying to pack into a small ad space. There might be a better way around this but the simplest solution I found is to use a 404 document which displays the image and that is linked back to the main page.

It is enough to prod the user along.

6) Create /usr/local/www/dnsbh/404.html. This should look something like:

<!DOCTYPE html>




<a href="/index.html" target="_new"><img border="0" src="/warn.png"></a>



That's it. There is obviously a lot of options here, this should be enough to get you started.

Monitoring examples and ideas

I have some stuff set up that leverages our existing Netflow data to try and add a little value to what goes on with this box.

The examples below are simply trending connections to port 80.

The shortcomings of this solution aside, that second image is quite compelling. You don't even need an analyst to interpret it. This is the kind of stuff that can be easily offloaded because the message is so poignant.

This example shows a typical day of activity:

This shows an infection:

A nice summary table like the one below is very useful. It is important to not just focus on hits but just how much data a client trying to send out. Large payloads repeatedly sent to this device should be an instant alarm.

Keep in mind too that that this is a webserver people are connecting to. Which means: LOGS!  Aside from the fact that we can use these to clarify events, the data is screaming to be mined. I am not quite there yet, but soon.


Being a little short handed at work, this was one of the first security solutions that I gravitated towards. The passiveness (and price) just made sense. A DNSBH can dramatically improve an organizations overall security posture for next to nothing. Yes, understand that It is NOT going to help you deal with intelligent threats, but you know what? that doesn't really matter because most aren't.

The sludge, the unworthy.. that is where this solution shines. If you are short on time, and short on resources, this is a gift.

Thanks to everyone that has contributed to and maintained these lists over the years. You have made my life a lot easier :)