Start
   Blogaria
   Bored
   bsgen
   cconf
   Cookies
   Dialwhatever
   dnspb
   fch
   HammerServer
   jpeginfo
   kalk
   Lectures
   Microproxy
   msc
   Nasapics
   Off The Grid
   PGPkey
   Posters
   SafeEdit
   Simple listserv
   syscheck
   Wallpapers
Karel as an adult

A little movie
An animation can't be properly rendered. You have probably a too old version of Flash player.






dnspb

Summary for the fast and furious
Latest version 0.06
Latest news ChangeLog
Latest sources dnspb-0.06.tar.gz
Contact karel@kubat.nl

What is dnspb?

Dnspb is a proxy/balancer for DNS requests. It handles both UDP and TCP operations.

Dnspb is based on my previous proof of concept program dns-balance. The description is still hosted at my site, read it if you want for an overview of concepts. The improvement points that are listed at the bottom of the dns-balance description have made it into the code base of dnspb.

Balancing
In general, here's what dnspb can do for you. If you have multiple UDP and/or TCP back ends, then you can put dnspb "in front of them" as a proxy/balancer. Clients contact dnspb to resolve names (or to do other DNS-related operations), and dnspb forwards the requests to the next-best back end it knows. This is the DNS server with the least connections at that time. The request is resolved at the true DNS server, upon which dnspb sends this answer to the client who had requested the operation. This is basic balancing: dnspb distributes the traffic over all the back ends that are "behind" it.

Fail-over
When a back end goes down, then dnspb detects this, and takes it out of rotation - i.e., it makes sure that next requests don't get forwarded to that back end. However, dnspb periodically checks "dead" back ends to see whether they've come alive. Once dnspb sees that such a back end has awoken, then it's automatically added to the pool. This is basic fail-over: if you have more DNS servers and one dies, then dnspb makes sure that clients don't suffer from it. (Live checks are on by default, but they can be turned off.)

Transaction ID randomization
Every DNS requests has a transaction ID in it. This is a number that the requesting client defines. Consecutive numbers (1, 2, 3 and so on) make the domain name system susceptible for attacks, as was illustrated by Dan Kaminski (google it if you want to know more, or see http://en.wikipedia.org/wiki/Dan_Kaminsky). Dnspb randomizes these ID's in the traffic to the true DNS servers, and in the case of UDP, randomizes the ports, which is also pretty important. This makes Kaminski-style attacks much more difficult (though the only real solution is to use dnssec).

Support of heterogenous dns
Normally your DNS back ends will be "equal" in the information that they can provide. But in cases where one group of back ends knows about one zone, and another group knows about another zone, dnspb can be put in front of these servers to combine such heterogenous zones, and to make them appear homogenous to clients. Dnspb does this by simply re-querying a next DNS back end upon receipt of a "name error" response. (This behavior can of course be turned on and off.)

Copyright and License

Dnspb is distributed in source form, as-is, licensed under GPLV3. See the file LICENSE in the source archive. This basically means that you're free to take dnspb and use it, you're free to modify it to suit your needs, and you're free to redistribute it, as you see fit - but only as long as you keep the licensing terms intact, and as long as you redistribute dnspb with all sources. If you do modify dnspb, then as a courtesy, I'd appreciate a note from you (if the modification is generic enough, I'd include it in the sources and re-distribute, including your name in the ChangeLog if you want).

Also, dnspb is distributed without explicit or implied warranty or fit of purpose. Use it at your own pleasure and risk.

How to install and start dnspb?

  • Obtain the source archive dnspb-0.06.tar.gz .
  • Unpack the archive in a 'sources' directory, e.g. /usr/local/src/. The archive spills its contents into a new subdirectory dnspb-version/.
  • Change-dir into the new directory dnspb-version/ and type
    make local
  • If you want to run some tests before installing: run
    build/dnspb tcp://1.2.3.4 udp://1.2.3.4
    You will have to do this as root, since dnspb binds to port 53 which is privileged. Here, 1.2.3.4 are the IP addresses of your DNS server. You can specify several TCP back ends and several UDP back ends. Also you can put in a flag -d to see debugging output. Let this run; in an other window, run some lookups, such as
    host www.google.com localhost
    To test out TCP, run
    host -T www.google.com localhost
    Once you are done testing, just hit ^C in the window that runs dnspb. Alternatively, you can run
    dig www.google.com @localhost        # UDP test
    dig +tcp googleo.com @localhost      # TCP test
  • In order to install into /usr/sbin, run
    make install
    If you want to install into an other directory, run
    BINDIR=/where/ever make install
    This installs two utilities:
    • dnspb, the program itself;
    • dnspbctl, a control script.
  • Next copy etc/dnspb.cfg.sample to /etc/dnspb.cfg by running:
    cp etc/dnspb.cfg.sample /etc/dnspb.cfg
    After this edit /etc/dnspb.cfg to suit your needs, the configuration is pretty self-explanatory. Or see below for a description.
  • Finally fire up dnspb by running:
    dnspbctl start

The worker dnspb

The actual balancer program dnspb can be started without using dnsbpctl, just as httpd can be started without apachectl. The worker supports the following options:
  • Generic:
    • --help, -h, -?: Shows usage information.
    • --version, -v: Shows the version ID and stops.
    • --log-debug, -d: This causes dnspb to generate verbose (debugging) information. Dnspb sends this information to stdout, which can be redirected to log files, or the system logger etc..
    • --log-performance, -p: This causes dnspb to generate performance-related information.
    • --heterogenous-dns, -H: If your DNS back ends represent separate zones, then with this flag, dnspb will continue asking back ends for a resolution when it receives a "name error" answer.
  • UDP-related:
    • --idle-udp-timeout SEC, -i SEC: dnspb will wait for an UDP answer from downstream servers for the stated number of seconds, default is 2. When no answer is received within the stated time, then dnspb considers the server to be down.
    • --udp-port PORT, -u PORT: This defines the UDP port that dnspb listens to. The default is 53. Setting this port to 0 causes dnspb not to start the UDP service.
    • --udp-port-retries TRIES, -U TRIES: This is the number of (re)tries that dnspb may take to find a local UDP port for the connections with downstream DNS servers. Normally you don't have to change this setting, the default is 40.000.
    • --udp-recheck-time SEC, -r SEC: When dnspb detects that downstream DNS servers are dead, then it will recheck each SEC seconds to see whether the server(s) have awoken yet. Setting this to 0 instructs dnspb not to check at all. The default is 1 sec.
  • TCP-related:
    • --idle-tcp-timeout SEC, -I SEC: dnspb will wait for the given number of seconds before deciding that a TCP back end is dead. The default is 120.
    • --tcp-port PORT, -t PORT: This defines the TCP listen port. The default is 53. Setting this value to 0 instructs dnspb not to start the TCP service.
    • --tcp-recheck-time SEC, -R SEC: When dnspb detects that downstream TCP servers are dead, then it will recheck each SEC seconds. Setting this value to 0 inhibits TCP server checks.
Following the flags, you must specify UDP and/or TCP back ends. UDP back ends are required, unless the UDP listen-port is set to 0; TCP back ends are required, unless the TCP listen-port is set to 0. Back ends are always stated as TYPE://IP-ADDRESS, optionally followed by /WEIGHT. The TYPE must be udp or tcp. The IP address is the dotted-decimal address of the DNS servers that dnspb will talk to. The weight is an optional specifier that tells dnspb which back ends are "stronger": the bigger the weight, the more traffic the back end will receive.

Any output of dnspb is prefixed with a timestamp (up to millisecond resolution), a thread ID, a message type, and text. The thread ID is mainly for debugging purposes (to see which thread did what). The message type is something like "debug", "perf" or "info". Warnings are shown with the message type "WARN".

Three important signals that dnspb listens to, are HUP, USR1 and USR2. Signal HUP (1) causes dnspb to show the state of its back ends. Signal USR1 (30) toggles performance logging output. Signal USR2 (31) toggles debugging output.

The control script dnspbctl

Dnspbctl is a fairly simple Perl script that parses a configuration file, prepares a command that fires up dnspb, and execs it. Once dnspbctl starts the worker dnspb, it exits - it doesn't use up any resources. The configuration file that dnspbctl reads is /etc/dnspb.cfg. The syntax of this configuration file is very simple and self-explanatory. For reference an example is shown here.
# ########################################################################
# Configuration for dnspb (/etc/dnspb.cfg)
# Used by dnspbctl to control the main program dnspb.
# Syntax:
#    Configurations are stated as "label = value"
#    Some configurations have a default, some must be stated. See below.
#    Comments are lines where the first character is a #
#    Empty lines are allowed
#    You can split long lines using a \ at the end. The next line may
#        be indented.
# ########################################################################

# ########################################################################
# General section
# ########################################################################

# Should debugging information be generated? Can be toggled later in the
# running server using kill -USR2  or using dnspbctl toggledebug.
# Values may be false or true, default false.
# log-debug = false

# Should performance information be generated? Can be toggled later in
# the running server using kill -USR1  or using dnspbctl toggleperf.
# Default false.
log-performance = true

# Logging output. Use |program to send into a pipe, or >file to rewrite
# files each startup, or >>file to append to a file. There is no default,
# must be specified. A good setting is e.g.: |logger -t dnspb
# To get verbose output on console, do: (a) set above log-debug to true,
# (b) set log-output to |cat
log-output = | /usr/local/bin/loglimit /tmp/dnspb.log 10000 3

# If your DNS servers represent distinct zones, then set the following
# flag to true. Dnspb will then continue to query back ends when it
# receives a "name error" answer. If your back ends provide equivalent
# information, then leave this flag "false", which is the default.
# heterogenous-dns = false

# ########################################################################
# UDP service section
# ########################################################################

# UDP server port (0 to disable the UDP service). Default is 53.
# udp-port = 53

# UDP back ends. Specify as IP:PORT/WEIGHT, e.g. 1.2.3.4:53/1
# The default port is 53, the default weight is 1, you can leave those out
# to write e.g. 1.2.3.4. Bigger weights are bigger servers and get
# proportionally more traffic.
# There is no default, must be specified (unless you suppress the UDP
# service by saying udp-port = 0)
udp-backends = 10.124.237.66 10.51.223.77 \
               8.8.8.8 8.8.4.4

# UDP timeout. When no answer arrives from a back end within the stated
# nr of secs, the back end is marked dead. Use 0 to suppress this state
# checks. Default is 2.
# udp-timeout = 2

# Rechecking of dead back ends. Once due to time outs back ends are
# marked dead, they will be rechecked every X secs to see whether they
# are online yet. Default is 1 sec. Set to 0 to suppress checks.
# udp-recheck-time = 1

# ########################################################################
# TCP service section
# ########################################################################

# TCP server port (0 to disable the TCP service). Default is 53.
# tcp-port = 53

# TCP back ends. Specify as IP:PORT/WEIGHT, e.g. 1.2.3.4:53/1
# The default port is 53, the default weight is 1, you can leave those out
# to write e.g. 1.2.3.4. Bigger weights are bigger servers and get
# proportionally more traffic.
# There is no default, must be specified (unless you suppress the TCP
# service by saying tcp-port = 0)
tcp-backends = 10.124.237.66 10.51.223.77 \
               8.8.8.8 8.8.4.4

# TCP timeout. When no answer arrives from a back end within the stated
# nr of secs, the back end is marked dead. Use 0 to suppress this state
# checks. Default is 2 mins. This is much longer than UDP timeouts to allow
# for complex TCP zone operations etc..
# tcp-timeout = 120

# Rechecking of dead back ends. Once due to time outs back ends are
# marked dead, they will be rechecked every X secs to see whether they
# are online yet. Default is 3 sec. Set to 0 to suppress checks.
# tcp-recheck-time = 3
  
Dnspbctl supports the following options:
  • -c CONF: Instructs dnspbctl to read the stated configuration file, instead of /etc/dnspb.cfg.
  • -v: Turns on script verbosity (for debugging).
Dnspbctl supports the following arguments:
  • start, stop, restart: These are the typical control scripts actions.
  • status: Shows whether the DNS proxy/balancer is running, and if yes, at which process ID.
  • configtest: Verifies whether the configuration /etc/dnspb.cfg is valid.
  • commandline: Shows how dnspbctl would start dnspb given the configuration.
  • backends: Causes the underlying dnspb worker to send its back end state to the log.
  • toggledebug, toggleperf: Sends the signal USR1 or USR2 to dnspb to toggle debugging or performance logging.