Does this site look plain?

This site uses advanced css techniques

For a long time we've used the rblcheck tool to see if a given mailserver is listed in any of the DNS-based blackhole lists, but this project has been dormant for a long time. The last update (1.5) was more than a year ago, and the code for picking apart the DNS responses is just awful (and buggy).

We were about to simply start over when we found that Yiorgos Adamopoulos had rewritten an early (but cleaner) version to use the ADNS library instead of the standard DNS resolvers. He had done this as an exercise, but the code was clean and looked to be a much better place to start. We used his code as a base for what amounts to nearly a complete rewrite.

Quick Links

DNSBL background

There are many DNS-based email blocklists, each of which is handed the IP address of an email sender. It returns an indicator of "they're in the list"or "they're not in the list", and most of the time the "in the list" response causes our mailserver to drop the connection. No point in accepting mail from purported spammers, right?

Our favorite blocklist is the Open Relay Database, which lists IP addresses of computers known to be open relays. Being an open relay is highly correlated with being a middleman for spam, and we've found that rejecting mail from these servers not only reduces our spam load, but also creates an incentive on the open relay owners to secure their computers. We love ORDB.

There are plenty of other lists of varying utility and rates of adoption, but the benefits and drawbacks of any individual list are beyond the scope of this document. Here, we're only concerned about how to query a list, not evaluate it.

All of the blocklists we're talking about use DNS as their lookup mechanism: the IP address of the connecting server is converted into a domain name, and this name is used in a standard DNS name lookup. These are always based on the IP address of the sender, not on any part of the email envelope (such as From: or To: lines).

For instance, to perform an ORDB lookup of the mailserver located at 63.203.17.35 involves a DNS query of 35.17.203.63.relays.ordb.org looking for an A (address) resource record. If there is no such record, then this IP address is not "on the list", so the connection should be accepted. Note that the four octets of the IP address are reversed, à la the in-addr.arpa mechanism.

One can do this "by hand" with the dig command and the long domain name, and we'll show some examples here. The first is a random site that's known to be an open relay (at the time of testing), followed by one of our own mailservers:

$ dig +short 130.119.226.159.relays.ordb.org A   random open relay
127.0.0.2      it's in the list

$ dig +short 35.17.203.63.relays.ordb.org A      our mail server
               no reply: not in the list
$

The actual value of the answer (here, it's 127.0.0.2) is not always interesting because it's the presense of a response, not the value of the response that is meaningful. An IP address is used because that's the only thing that a query for an "A" record can return, and one return value is as good as any other.

But some blocklists have different responses for different reasons, so knowing just which response was given might be interesting. An example is NJABL, which has a small table of possible return values: 127.0.0.2 is for open relays, 127.0.0.3 is for dialup ranges (these systems should be their ISP's SMTP servers), 127.0.0.4 for known spam sources, and a few others.

Each DNSBL can have its own sets of meanings, but any answer means that the IP being queried is "in the list". Consult the particular DNSBL documentation for the meaning - if any - of the returned values.

Detecting dead or incorrect DSNBLs

DNS Blocklists have been around long enough to have "history", and some of the original lists have disappeared for one reason or another. This means that queries to lists that no longer exist return "no such domain", which is the same as "not on the list".

An effect of this behavior is that queries to lists that no longer exist (or to lists whose names have simply been misspelled) are not reported as any kind of error. This suggests that these incorrect queries could stick around for a long time, giving an inappropriate sense of confidence in the non-spam-ness of the incoming connections, not to mention the waste of resources asking questions that won't ever get an interesting answer.

Fortunately, there seems to be a de facto standard for asking "is this a valid DNSBL?", and that involves making a query for the IP address 127.0.0.2. This should always return an "it's on the list" value, and it can be done to verify that a particular DNSBL is working or not.

Download / Build

Full C source code is available, as well as prebuilt Red Hat Linux binaries.

We promise that the binary was built from this source and that it performs no shenanigans. We don't promise that it has no bugs. Use at your own risk.

Command Line Parameters

When arblcheck is run without command-line arguments, it reports a short "help" listing that summarizes the options available, which are expanded.

-h
Show a brief help listing, then exit.
-v
Show the program's version information, then exit.
-l
Display the current list of DNSBL sites that will be queried. The program has a compiled-in list that's initialized at startup, but this list can be modified by command-line arguments. The list displayed is the list in effect at the time the -l parameter is encountered.
-c
Clear the current list of DNSBL sites to query, rendering it empty. This presumes that the -s option will be used to add new DNSBL sites to the list later.
-s SITE
Add SITE to the current list of DNSBL sites to query.
-f
Only show "filtered" results: do not generate any output for "not in the list" responses.
Exit codes

This program has three kinds of exits:

Note that a return code of (say) "2" could mean "two different targets each had one listing" or "one of your targets had two listings". No way to tell the difference without looking at the output. If this is really needed programmatically, call this program once per target.

Version history

This is a simple mirror of the revision log in our development environment, but it might lag a bit behind the version of the executable actually found on the web.

2004-08-15 1.4.2
-- Updated the DNSbl list (included SPEWS)

2003-10-21 1.4.1
-- Initial release of rewritten code.

Stuff to do

Credits