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



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?

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: 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: Dnspbctl supports the following arguments: