DNSBL: how does it work, and how to create and build an own

DNSBL is a DNS based [DNS = Domain Name System] blackhole list, which can be used as countermeasure against unwanted mail spam.

One of the most efficient ways to block mail spam is to do it on mail server level by denying incoming connects from spam sources, where the contacting remote machine is identified by its IP address which is checked against one or more DNSBLs on the fly.

The first DNSBL was the MAPS RBL (Realtime Blackhole List) by Paul Vixie in 1997. Since MAPS went commercial and RBL is now a service mark of MAPS LLC, the generic term DNSBL is preferred over RBL or DNSRBL in this article.

 

How does a DNSBL work

The mailserver checks the IP address of every incoming SMTP connect request against one or more DNSBLs = DNS based black lists.
These BLs are just a list of spam-related IP addresses, implemented as a DNS zone file, so that the list can be easily queried by simple and fast DNS lookups, and hence the name DNSBL.

The “positives” entries in that zone file (following example in BIND format) are A records and TXT records like

44.3.200.10.dnsbl.example.com.  IN A  127.0.0.3
                                IN TXT "spam source, rot in hell"
45.3.200.10.dnsbl.example.com.  IN A  127.0.0.3
                                IN TXT "spam source, rot in hell"
*.5.222.10.dnsbl.example.com.   IN A  127.0.0.10
                                IN TXT "confirmed DUL range, please use your ISP's smart mail host"
2.0.0.127.dnsbl.example.com.    IN A  127.0.0.2
                                IN TXT "My-private-blacklist: test record. The list is active"

Note: all domain names and/or IP addresses given in this arcticle are just examples and unrelated to the real world.

Please note the reversed notation of the IP address octets (ip4r) as the address is translated into an articifical subdomain name. So IP address 10.200.3.44 gets listed as 44.3.200.10.dnsbl.example.com.

The 127.0.0.x (the x to be greater than 1) is freely choosen by the zone maintainer. Entries may be grouped in such way that different 127.0.0.x may designate different classes of entries like spam sources, open relays, spam support sites, DULs, etc.
However, most mail server programs cannot see the difference, so it doesn’t really matter for the simple decision if we will accept a connection (= no entry) or not (= 127.0.0.x).

For testing purposes to check if the list is active and working, a 127.0.0.2 test record should be there per convention.

If our mail server gets a SMTP connect from remote IP address 10.200.3.44 and you configured the server do check the dnsbl.example.com DNSBL, the mail server now does a DNS lookup for the name 44.3.200.10.dnsbl.example.com (note the reversed notation of the IP address octets (ip4r)) and will get the following information from the DNS:
Address: 127.0.0.3
44.3.200.10.dnsbl.example.com text = "spam source, rot in hell"
Per convention, if the DNSBL returns a 127.0.0.x (for x > 1), it is a positive hit.
So the mail server now concludes from the positive hit “127.0.0.3” that the connecting machine is unwanted and may terminate the SMTP conversation by sending a final reject message consisting of an appropriate 5xx error code and the TXT information from the DNS query:
"553 spam source, rot in hell".
No mail seen at all.

Next our mail server gets a connect from remote IP address 10.222.5.99. A DNS lookup for the name 99.5.222.10.dnsbl.example.com will return the following information from the DNS:
Address: 127.0.0.10
99.5.222.10.dnsbl.example.com text = "confirmed DUL range, please use your ISP's smart mail host"
So the mail server will see a positive hit and consequently sending a 5xx reject message
"553 confirmed DUL range, please use your own ISP's mail host"
to terminate the SMTP conversation. No mail seen at all.

Next our mail server gets a connect from remote IP address 10.111.1.22. A DNS lookup for the name 22.1.111.10.dnsbl.example.com will return the following information from the DNS:
can't find 22.1.111.10.dnsbl.example.com. : NXDOMAIN
As there is no hit, the mail server will continue the SMTP dialogue with the remote server and accept the incoming mail.
Everything is fine here.

 

Why an own DNSBL ?

There are several public blackhole lists available, so you should NOT build an own one, unless you really need to.

Several specialized blocklists are listing open relays, SOCKS proxies, known spam sources, ISP dial up links (DUL), and others. Some wellknown DNSBLs are sbl.spamhaus.orgbl.spamcop.netlist.dsbl.orgrelays.ordb.orgdnsbl.sorbs.netdnsbl.njabl.org, just to name a few. There are many others.

More Links:
dmoz.org – DNSBL-listings.
openrbl.org – Check an IP address against common DNSBLs.
moensted.dk – Check an IP address against a long list of DNSBLs.
declude.com – Long list of IP based DNSBLs.

One need for an own BL could be, that you need an additional own private list to additionally check some “special” private entries not (yet) covered in the public BLs, or if you need an own private whitelist to be checked before the public blacklists. You should, however, implement a private list in a way that it does not leak out into the public due to DNS mis-configurations.

If you really should think that the world needs a new public BL, please re-consider several times, if you are prepared for both the organizational as well as the technical aspects of: (automatic) management of the BL, setting up a database for the list entries and batch procedures to automatically generate zone files from the database content, rules and processes (both manual and automatic) for listing, de-listing and expiring of entries, discussion and legal trouble with owners of listed IPs demanding de-listing against your rules, costs for the operation of several parallel servers to cover lookup demand load peaks and denial-of-service (DOS) attacks, funds for the resulting data traffic bandwidth costs for normal operation as well as excessive DOS-attacks, trouble with your network provider, who perhaps doesn’t want to attract DOS situations within his network and will kick you because he doesn’t want any trouble at all.

 

Howto: build an own DNSBL

For a DNSBL you need — as the name already implies — a DNS server. Depending on your environment, there are several ways to go.

The best way to build a BL would be to do it on a separate server with no interference to other DNS.
If you don’t yet have a DNS server running on the server you want to implement your own BL, then you may choose between several possibilities to set up a small own DNS especially dedicated for that purpose. You can choose between a fullblown BIND as well as other software like rbldns as part of djbdns, or rbldnsd.
Since my DNS runs under BIND, I don’t have own experience with the rbldns or rbldnsd and can’t tell you more about these.

If you only have one single server, and there already is a DNS server running, then you have basically 2 options. [As the DNS service is already running on port 53, you can’t have another DNS on the same machine on the same default port.] You can:
(1) adapt to this situation and implement the BL as an additional zone within that DNS you already have, fitting into its given setup.
(2) implement an additional DNS working on another private port like 530, and define a zone on the already running main DNS with “type forward;” pointing to the additional server.
I have choosen the 1st option, which will be described in the following chapter.
Caution: be careful to not screw up your setup. Only a small private DNSBL may coexist with the current load of your DNS. BIND may have performance problems with large zone files with many entries. The rbldns is said to handle larger zone files much better than bind. Don’t risk or kill your main DNS performance with just an additional BL.
You have been warned and continue in the next chapter on your own risk.

 

Add a DNSBL on a working BIND server

For a small domain site just being hosted on a single server, with SMTP mail and a primary authoritative BIND DNS serving just the site’s zone on the same box, here is the easy way to just add an additional small private low-traffic DNSBL on that same server box.
The small zone file with the spammy addresses is just plainly written with an ASCII editor, doing the ip4r reversing of the addresses manually. No database or other software is needed.

In the following example configuration, the main domain is example.com,
the DNSBL is dnsbl.example.com,
all is running on the same server box with IP addess 192.168.177.22.
Just do a search-and-replace to change to your own needs.

Step 0: Before you start: check your existing DNS setup for “example.com” with www.dnsreport.com and ensure that everything is OK and there are no current errors in your DNS setup. Create backup copies of the config and zone files, so that you could easily switch back, if would find yourself hosed later.

Step 1: Change your bind (named) config file /etc/named.conf to include the following:

options {
        ....
        # globally deny public lookups and public recursion
        allow-query { localhost; };
        allow-recursion { localhost; };
}

# main zone file for the domain "example.com"
zone "example.com" in {
        # we are the primary and authoritative server
        type master;
        file "example-com.zone";
        notify yes;
        # now allow public lookups just for this domain
        allow-query { any; };
        # allow zone transfer to your secondary nameservers only
        allow-transfer {
          xx.xx.xx.xx; yy.yy.yy.yy;
        };
};

# private block-list in a delegated sub-domain
zone "dnsbl.example.com" in {
        type master;
        file "dnsbl-example-com.zone";
        # we already had set this in the global options, but just to be sure again:
        #    no public queries to our DNSBL !!!
        allow-query { localhost; };
        # don't know if the following is required, 
        #    but it is perhaps not bad to definitely restrict
        allow-transfer { 127.0.0.1; };
};

Step 2: Change your domain’s primary zone file example-com.zone to include or look like the following:

$TTL 86400      ; 1 day
@               IN SOA  ns1 hostmaster (
                        2004032201 ; serial
                        7200       ; refresh (2 hours)
                        5400       ; retry (1.5 hours)
                        1814400    ; expire (3 weeks)
                        86400      ; minimum (1 day)
                        )
                IN NS   ns1
                IN NS   ns2.secondary-dns.xx.
                IN MX   10 mail
                IN MX   20 mail.other-mx.yyy.
;
                IN A    192.168.177.22
;
ns1             IN A    192.168.177.22
dnsbl           IN NS   ns1
ftp             IN A    192.168.177.22
mail            IN A    192.168.177.22
www             IN A    192.168.177.22
;

The “@” imports the domain name. Everything is on the same server except the secondary nameserver. Important is the delegation of the dnsbl to an own nameserver "dnsbl IN NS ns1", even if it is the same.

Step 3: Create/modify your DNSBL zone file dnsbl-example-com.zone as follows:

$TTL 86400      ; 1 day
@               IN SOA  ns1.example.com. hostmaster.example.com. (
                        2004032201 ; serial
                        7200       ; refresh (2 hours)
                        5400       ; retry (1.5 hours)
                        1814400    ; expire (3 weeks)
                        86400      ; minimum (1 day)
                        )
                IN NS   ns1.example.com.
;
                IN A    192.168.177.22
;
; -----------------------------------------------------------------
2.0.0.127       IN A    127.0.0.2
                IN TXT  "example.com test record"
3.0.0.127       IN A    127.0.0.3
                IN TXT  "example.com verified spam source"
10.0.0.127      IN A    127.0.0.10
                IN TXT  "example.com confirmed DUL range"
;
; -----------------------------------------------------------------
44.3.200.10     IN A  127.0.0.3
                IN TXT "spam source, rot in hell"
45.3.200.10     IN A  127.0.0.3
                IN TXT "spam source, rot in hell"
; a complete range 10.222.5.0/24 using * wildcard
*.5.222.10      IN A  127.0.0.10
                IN TXT "confirmed DUL range, please use your ISP's smart mail host"
; a complete range 10.223.0.0/16 using * wildcard
*.223.10        IN A  127.0.0.10
                IN TXT "confirmed DUL range, please use your ISP's smart mail host"
;

Step 4: After you are done, reload the nameserver with
rndc reload example.com

or whatever your reload/restart procedure is.
Immediately check the log files for possible errors. As a quick check do a dig or nslookup locally on the server machine for “example.com” and “2.0.0.127.dnsbl.example.com”. Then do a dig or nslookup on a remote machine for “example.com” (should resolve, but most likely from a remote cache, so you cannot be sure at this time that you didn’t screw up anything) and “2.0.0.127.dnsbl.example.com” (should not resolve from remote!).
Then again check your new DNS setup for “example.com” with www.dnsreport.com to see if you have screwed up your basic DNS or not (don’t check “dnsbl.example.com” as this is running privately on one server only (the default would be 2 nameservers) and shouldn’t reply to public queries at all).

Step 5: Reconfigure your server’s mailserver to use the new local DNSBL you just created.

We are done.

This example may easily be adapted to host the DNSBL on a separate server.

Disclaimer: the above eventually worked for me. If you try to implement the above, you will do so at your own risk. Be careful not to screw up your server/s or parts of the internet’s DNS services. No guarantees, and yes, your mileage may vary.
If you have any doubts, don’t do it.