rbldnsd(8)

NAME
rbldnsd - DNS daemon sutable for running DNS-based blocklists

SYNOPSYS
rbldnsd [options] zone:dataset...

DESCRIPTION

rbldnsd is a small DNS-protocol daemon which is designed to handle queries to DNS-based IP-listing or NAME-listing services. Such services are a simple way to share/publish a list of IP addresses or (domain) names which are "listed" for for some reason, for example in order to be able to refuse a service to a client which is "listed" in some blocklist.

rbldnsd is not a general-purpose nameserver. It will answer to A and TXT (and SOA if such RRs are specified) queries, and has limited ability to answer to NS and MX queries.

rbldnsd will answer queries to DNS zones specified on the command line as an ordered list of zone specifications, Each zone specification consists of zone basename, dataset type and a comma-separated list of files that forms a given dataset: zone:type:file,file,...

Several zones may be specified in command line, so that rbldnsd will answer queries to any of them. Also, a single zone may be specified several times with different datasets, so it is possible to form a zone from a combination of several different dataset. The same dataset may be reused for several zones too (and in this case, it will be read into memory only once).

Note that order of zones in command line is important. Zones will be looked for every query in order specified, and first matching zone will be searched. So, if you want rbldnsd to answer queries to several subzones and a "base" zone that is a combination of all it's subzones, specify base zone after all it's subzones in a command line (see examples below).

There are several dataset formats available, each is sutable and optimized (in terms of memory, speed and easy use) for a specific task. Available dataset types may be grouped into 3 categories:

    lists of IP addresses. When query is done to a zone with such data, query is interpreted as an IP address in a reverse form (similar to in-addr.arpa zone). If an address in question is found in dataset data, rbldnsd will return A and TXT records specified in data for that IP. This is a classical IP-based blocklist.

    lists of domain names. Similar to list of IP addresses, but with generic domain names instead of IPs (wildcards allowed). This type of data may be used to form a blocklist of e.g. sender domain names.

    generic list of various types of records, as an auxilary data to form complete nameserver. This format is similar to bind-style datafiles, but very simplified. One may specify A, TXT, NS and MX records here.

OPTIONS

The following options may be specified:

-u user[:group]
    rbldnsd will change it's userid to the specified user, which defaults to rbldnsd, and group, which by default is the primary group of a user. rbldnsd will refuse to run as root user, since this is insecure.

-r rootdir
    rbldnsd will chroot to rootdir if specified. Data files should be available inside rootdir.

-w workdir
    rbldnsd will change it's working directory to workdir (after chrooting to rootdir if -r option is also specified). May be used to shorten filename paths.

-b [address][:port]
    rbldnsd will bind to specified address which defaults to a wildcard address, and port which defaults to 53 (standard DNS port).

-a netlist
    access control list: answer queries that orginate from IP addresses matching netlist only. Queries originated from other IPs will be silently ignored. By default, all IPs are allowed. netlist consists of comma-separated list of CIDR ranges or hostnames, optionally negated by exclamation mark, like 127.0.0.1,!127/8. Implicit all-matching entry are always added at the end of the list, to allow access to the rest of IPs if last entry was negative and to disallow access if it was positive (so this example allows access from 127.0.0.1, disallows from all other IPs in loopback range, and allows to everyone else). By default, rbldnsd allows access from any IP address. Note that hostnames may be used in netlist too, like localhost/8.

-t ttl
    Set answer time-to-live value to be ttl secounds. All answers will contain ttl as a value of time-to-live field. Default is 2048.

-c check
    Set interval between checking for zone file changes to be check secounds, default is 60 (one minute). rbldnsd will check zone file's last modification time every so often, and if it detects a change, zone will be automatically reloaded. Setting this value to 0 disables automatic zone change detection. This procedure may also be triggered by sending SIGHUP signal to rbldnsd.

-e  Allow non-network addresses to be used in CIDR ranges. Normally, rbldnsd rejects addresses such as 127.2.3.4/24, where prefix is not within the network mask derived from bit number (in this case, correct form is 127.2.3.0/24, note the trailing zero in prefix). This is done in order to catch possible typos in zones (rbldnsd will warn about a problem and will ignore such entry). This option removes a check whenever CIDR prefix fits within network mask.

-q  Quick and quiet start. Normally, rbldnsd does zone load in foreground, printing progress and statistic info, and aborts in case of any errors. With this flag, nothing will be printed and first zone load will be done in background (unless -n option is also given), and zone load errors will be non-fatal.

-p pidfile
    Write rbldnsd's pid to the specified pidfile, so it will be easily findable. This file gets written before entering chroot jail (if specified) and before changing userid, so it's ok to specify e.g. /var/run/rbldnsd.pid here.

-l logfile
    Specifies a file to which log all requests made. This file is created after entering chroot jail and becoming a user. Logfiles may be quite large, esp. on busy sites (rbldnsd will log every recognized request if this option is specified). This option is mainly intended for debugging purposes. Upon receiption of SIGHUP signal, rbldnsd reopens it's logfile. If logfile prefixed with a plus sign (+), logging will not be buffered (i.e. each line will be flushed to disk); by default, logging is buffered to reduce system load.

-L netlist
    Only log requests that come from IPs matching netlist (which is treated the same way as for -a option above). By default (if -l option is given), rbldnsd will log all requests coming from allowed networks.

-n  Do not become a daemon. Normally, rbldnsd will fork and go to the background after successeful initialization. This option disables this behaviour.

-s  Log memory usage info (obtained via mallinfo(3) routine) and (re)load times (obtined via utimes(2) routine) on zone (re)loads.

DATASET TYPES AND FORMATS

Dataset files are text files which are interpreted depending on type specified in command line. Empty lines and lines starting with hash character (#) are ignored, except of a special case outlined below. A (comma-separated) list of files is interpreted as if all files where logically combined into one single file.

If a line starts with a dollar sign ($), hash character and a dollar sign (#$), or colon and a dollar sign (:$), it is interpreted in a special way, regardless of dataset type (this is one exception where a line starting with hash character is not ignored - to be able to reuse zone files of DJB's rbldns). After dollar sign, keyword is expected, to mean one of the following:

$SOA origindn persondn serial refresh retry expire minttl
    Specifies SOA (Start Of Authority) record for all zones using this dataset. Only first SOA record is interpreted. This is the only way to specify SOA - by default, rbldnsd will not add any SOA record into answers, and will REFUSE to answer to certain queries (notably, SOA query to zone's base domain name). It is recommended, but not mandatory to specify SOA record for every zone (it is yet unknown whenever a DNSBL nameserver should reply to SOA queries or not).

    If serial value specified is zero, timestamp of most recent modified file will be substituted as serial.

$TTL time-to-live
    (planned)

The following dataset types are available:

ip4set
    A set of IP addresses or CIDR address ranges, with common A and TXT values. IP addresses are specified one per line, by an IP address prefix (initial octets), complete IP address, CIDR range, or IP prefix range (two IP prefixes or complete addresses delimited by a dash, inclusive). Examples, to specify 127.0.0.0/24:
      127.0.0.0/24
      127.0.0
      127/24
      127-127.0.0
      127.0.0.0-127.0.0.255
      127.0.0.1-255
    to specify 127.16.0.0-127.31.255.255:
      127.16.0.0-127.31.255.255
      127.16.0-127.31.255
      127.16-127.31
      127.16-31
      127.16.0.0/12
      127.16.0/12
      127.16/12
    Note that in prefix range, last boundary is completed with all-ones (255), not all-zeros line with first boundary and a prefix alone. In prefix ranges, if last boundary is only one octet (127.16-31), it is treated as "suffix", as value of last specified octet of the first boundary prefix (127.16.0-31 is treated as 127.16.0.0-127.16.31.255, i.e. 127.16.0.0/19).

    Every IP address that fits within any of specified ranges is "listed", and rbldnsd will respond to reverse queries against it within specified zone with positive results.

    First non-comment line of a file, if started with a colon (:), specifies A value and TXT template to return (see below). If none specified, rbldnsd will return 127.0.0.2 for matching A queries and no record for matching TXT queries. If TXT record template is specified and contains occurences of of dollar sign ($), every such occurence is replaced with an IP address in question, so singe TXT template may be used to e.g. refer to a webpage for an additional information for a specific IP address.

    Any additional text after IP address or range is ignored by rbldnsd.

    This is the most compact effective type: queries are very fast and memory requiriments are less than of other types.

ip4vset
    A set of IP addresses or CIDR ranges, similar to i4set, with ability to specify individual A values and TXT templates for every entry (in additional to defaults). Every line contains single IP address, IP address prefix (initial octets), CIDR range, or inclusive range of two IP prefixes or addresses (separated by a dash), which is optionally folloved by A value and TXT template in the same form as default values specified in first line that starts with colon sign (see below).

    If an entry starts with an exclamation sign (!), this is exclusion entry, i.e. corresponding address range is excluded from being listed. This may be used to specify large range except some individual addresses, in a compact form.

    Default values line may be specified at any place in a file, and applies to all subsequent entries up to the end of a file or to next default values.

    This zone type may be used in place of ip4set, but memory requiriments are at least 3 times more than of ip4set.

dnset
    Set of domain names. Similar to ip4set, but instead of IP addresses, data consists of domain names (not in reverse form). One domain name per line, possible starting with wildcard (either with star-dot (*.) or just a dot). Again, if first non-comment line starts with colon, it is interpreted as default A value and TXT template. In TXT template, every occurence of dollar sign is replaced with domain name in question. For example, given query a.b.bl.example.com for zone bl.example.com and TXT template http://example.com/$, resulting TXT will be http://example.com/a.b if domain name a.b is listed.

    This zone type may be used instead of ip4set, provided all CIDR ranges are expanded and reversed (but in this case, TXT template will be expanded differently). Any text in line after domain name is ignored.

dnvset
    Set of domain names similar to dnset, with an ability to specify A and TXT values for every record line in ip4vset, and to specify exceptions by starting domain name with an exclamation sign. Requires more memory than dnset. Default values may be specified several times, line for ip4vset.

generic
    Generic type, simplified bind-style format. Every record should be on one line (line continuations are not supported), and should be specified completely (i.e. all domain names in values should be fully-qualified, entry name may not be omitted). No wildcards are accepted. Only A, TXT, NS and MX records are recognized. Examples:

     # bl.ex.com
     # specify some values for current zone
     @ NS ns1.ex.com
     @ NS ns2.ex.com
     www A 127.0.0.1
     about TXT "ex.com combined blocklist"

  Resulting A values and TXT templates

In all zone file types except generic, record values are specified as following:
  :127.0.0.2:Blacklisted: http://example.com/bl?$
If first non-comment line starts with a colon, it specifies default A and TXT for all entries in this file (which does not have specific values for zone formats that allows to specify individual values). Similar format is used to specify values for individual records, e.g. for ip4vset type:
  127.0.0.2 :127.0.0.2:Blacklisted: http://example.com/bl?$
or, without specific A value:
  127.0.0.2 Blacklisted: http://example.com/bl?$

Two parts of a line, delimited by second colon, specifies A and TXT record values. Both are optional. By default (either if no default line specified, or no IP address within that line), rbldnsd will return 127.0.0.2 as A record. 127.0.0 prefix may be omitted, so the above example may be simplified to:
  :2:Blacklisted: http://example.com/bl?$
There is no default TXT value, so rbldnsd will not return anything for TXT queries it TXT isn't specified.

In TXT template, any occurence of dollar sign is replaced with original query string (or IP address) when formatting resulting TXT record.

SIGNALS
Rbldnsd handles the following signals:

SIGHUP
    recheck zone files and reload any outdated ones. This is done automatically if enabled, see -c option. Additionally, rbldnsd will reopen logfile upon receiving SIGHUP, if specified (-l option).

SIGTERM, SIGINT
    Terminate process.

SIGUSR1
    Log current statistic counters into syslog. Rbldnsd collects how many packets it handled, how many bytes was received, sent, how many OK requests/replies (and how many answer records) was received/sent, how many NXDOMAIN answers was sent, and how many errors/refusals/etc was sent, in a period of time.

SIGUSR2
    The same as SIGUSR1, but reset all counters and start new sample period.

NOTES

Several zones may be served by rbldnsd, every zone may consist of several datasets. There are numerous ways to combine several data files into several zones. For example, suppose you have a list of dialup ranges in file named `dialups', and a list of spammer's ip addresses in file named `spammers', and want to serve 3 zones with rbldnsd: dialups.bl.ex.com, spam.bl.ex.com and bl.ex.com which is a combination of the two. There are two ways to do this:

 rbldnsd options... \
   dialups.bl.ex.com:ip4vset:dialups \
   spam.bl.ex.com:ip4vset:spammers \
   bl.ex.com:ip4vset:dialups,spammers

or:

 rbldnsd options... \
   dialups.bl.ex.com:ip4vset:dialups \
   spam.bl.ex.com:ip4vset:spammers \
   bl.ex.com:ip4vset:dialups \
   bl.ex.com:ip4vset:spammers

(note you should specify combined bl.ex.com zone after all it's subzones in a command line, or else subzones will not be consulted at all).

In the first form, there will be 3 independant data sets, and every record will be stored 2 times in memory, but only one lookup will be needed to resolve queries for combined bl.ex.com. In second form, there will be only 2 data sets, every record will be stored only once (both datasets will be reused), but 2 lookups will be needed to resolve queries against combined bl.ex.com zone.

When combining several data files with ip4set or dnset file types, A and TXT values will be the same for all records from all data files, and that will be from first data file (so specifying defaults in all but first file has no effect). This may be considered a bug, but that's a tradeoff between an optimal storage and flexibility. If you really need to have different A and TXT values and data from several files, either use ip4vset (or dnvset) types or use more than one data set for one zone (in both cases result will be the same: default values will be assigned from the same file where this record was initially located, and if there was no defaults in a file and no A/TXT value for an entry, it will not have one, regardless of how many files has been read before this one).

generic zone type is very rudimentary. It's purpose is to complement all the other type to form complete nameserver that may answer to NS, A, TXT and MX queries.

BUGS

Most of the bugs outlined in this section aren't really bugs, but present due to non-standartized and thus unknown expected behaviour of a nameserver that serves a DNSBL zone. rbldnsd matches BIND runtime behaviour where appropriate, but not always.

List of zones in command line is ordered. If a superzone specified before it's subzone in a command line, all queries for subzone will be directed to superzone, without subzone being even consulted, which is unlikely to be expected behaviour. This may change in the future.

rbldnsd lowercases all the domain names in all data files when loading, to speed up some operations. This isn't a problem in almost all cases.

rbldnsd will refuse to answer a query for a zone consisting of a ip4set or ip4vset dataset that does not provide all 4 octets of an IP address. That is, 0.0.127.bl.example.com, where bl.example.com consists of set of IP addresses, will be answered with REFUSE code. This is because currently, there is no easy way for rbldnsd to know whenever any of 127.0.0.x address is listed (this currently requires quite some lookups), so it does not know whenever this domain - 0.0.127.bl.example.com - really exists or not.

There is no TCP mode. If a resource record does not fit UDP packet (512 bytes), it will be silently ignored. For most usages, this isn't a problem, because there should be only a few RRs in an answer, and because one record is usually sufficient to descide whenever a given entry is "listed" or not. rbldnsd isn't a full-featured nameserver, after all.

Unlike BIND, rbldnsd does not add NS records to AUTH section of every answer, even if such records are specified (in `generic' dataset). This way, answer size is much likely to fit in a single UDP packet.

rbldnsd does not allow AXFR operations. For DNSBLs, AXFR is the stupidiest yet common thing to do - use rsync for zone transfers instead. This isn't a bug in rbldnsd itself, but in common practice of using AXFR and the like to transfer huge zones in a format which isn't sutable for such a task. Perhaps in the future, if there will be some real demand, I'll implement AXFR "server" support (so that rbldnsd will be able to act as master for BIND nameservers, but not as secondary), but the note remains: use rsync.

VERSION
This manpage corresponds to rbldnsd version 0.84.

AUTHOR
The rbldnsd daemon written by Michael Tokarev <mjt@corpit.ru>, based on ideas by Dan Bernstein and his djbdns package.

LICENCE
GPL.