NAME DwMain - A UDP non-recursive caching DNS resolver DESCRIPTION DwMain is a working DNS forwarding cache. This is a UDP-only server with the following features: * Small size and memory footprint suitable for embedded systems * Simple and clean codebase * Secure design * Spoof protection: Strong cryptography used to determine the Query ID and source port * Ability to read and write the cache to a file * Dynamic cache that deletes entries not recently used * Ability to use expired entries in the cache when it is impossible to contact upstream DNS servers. * Ipv6 support can be compiled in if desired TCP support is available via the separate program DwTcp. COMMAND LINE ARGUMENTS DwMain has a single optional command line argument: The location of the configuration file that DwMain uses specified with the "-f" flag. If this is not defined, DwMain uses the file "/etc/dwood2rc" as the configuration file. In other words, invoking DwMain as DwMain will cause DwMain to use /etc/dwood2rc as the configuration file; invoking DwMain as DwMain -f foobar will cause DwMain to use the file "foobar" in the current working directory (the directory one is in when starting DwMain) as the configuration file. CONFIGURATION FILE FORMAT The DwMain configuration file supports the following parameters: bind_address This is the IP (or possibly IPv6) address we bind to. cache_file This is the filename of the file used for reading and writing the cache to disk; this string can have lowercase letters, the '-' symbol, the '_' symbol, and the '/' symbol (for putting the cache in a subdirectory). All other symbols become a '_' symbol. chroot_dir This is the directory the program will run from. deliver_all Some upstream DNS servers violate the RFCs and send "name error" DNS packets without a SOA record in the NS section of the reply. Deadwood used to discard such packets; Deadwood now passes such packets on to the client without caching them. Should the old behavior of discarding these packets is desired, set this to 0 with "deliver_all=0" in the dwood2rc file. The default value for this is 1 dns_port This is the port Deadwood binds to and listens on for incoming connections. The default value for this is the standard DNS port: port 53 handle_noreply When this is set to 0, Deadwood sends no reply back to the client with a UDP query is sent and the upstream DNS never sends a reply. When this is set to 1, Deadwood sends a SERVER FAIL back to the client with a UDP query is sent and the upstream DNS never sends a reply. The default value for this is 1 handle_overload When this has a value of 0, Deadwood sends no reply when a UDP query is sent and the server is overloaded (has too many pending connections); when it has a value of 1, Deadwood sends a SERVER FAIL packet back to the sender of the UDP query. The default value for this is 1. hash_magic_number This is a large 31-bit prime number that the hash compression function uses; use the RandomPrime C program to generate a suitable random prime for this function. This number should be secret; its default value changes for every release of Deadwood. maradns_uid The user-id Deadwood runs as. This can be any number between 10 and 65535; the default value is 99 (nobody on RedHat-derived Linux distributions). This value is not used on Windows systems. maradns_gid The group-id Deadwood runs as. This can be any number between 10 and 65535; the default value is 99. This value is not used on Windows systems. max_ttl The maximum amount of time we will keep an entry in the cache, in seconds. This is the longest we will keep an entry cached. The default value for this parameter is 86400 (one day); the minimum value is 300 (5 minutes) and the maximum value this can have is 7776000 (90 days). The reason why this parameter is here is to protect Deadwood from attacks which exploit there being stale data in the cache, such as the "Ghost Domain Names" attack. maximum_cache_elements The maximum number of elements our cache is allowed to have. This is a number between 32 and 16,777,216; the default value for this is 1024. Note that, if writing the cache to disk or reading the cache from disk, higher values of this will slow down cache reading/writing. maxprocs This is the maximum number of pending remote connections Deadwood can have. The default value for this is 32. With DwTcp, this is the number of allowed open TCP connections. num_retries The number of times we retry to send a query upstream before giving up. If this is 0, we only try once; if this is 1, we try twice, and so on, up to 8 retries. Note that each retry takes timeout_seconds seconds before we retry again. Default value: 1 random_seed_file This is a file that contains random numbers, and is used as a seed for the cryptographically strong random number generator. Deadwood will try to read 256 bytes from this file (the RNG Deadwood uses can accept a stream of any arbitrary length). recurse_min_bind_port The lowest numbered port Deadwood is allowed to bind to; this is a random port number used for the source port of outgoing queries, and is not 53 (see dns_port above). This is a number between 1025 and 32767, and has a default value of 15000. This is used to make DNS spoofing attacks more difficult. recurse_number_ports The number of ports Deadwood binds to for the source port for outgoing connections; this is a power of 2 between 256 and 32768. This is used to make DNS spoofing attacks more difficult. The default value is 4096. recursive_acl This is a list of who is allowed to use the load balancer, in "ip/mask" format. Mask must be a number between 0 and 32 (for IPv6, between 0 and 128). For example, "127.0.0.1/8" allows local connections. resurrections If this is set to 1, Deadwood will try to send an expired record to the user before giving up. If it is 0, we don't. Default value: 1 timeout_seconds This is how long Deadwood will wait before giving up and discarding a pending UDP DNS reply. DwTcp uses this to determine how long to wait on an idle TCP connection before dropping it. The default value for this is 3, as in 3 seconds. upstream_port This is the port Deadwood uses to connect or send packets to the upstream server. The default value for this is 53; the standard DNS port. upstream_servers["."] This is a list of DNS servers that the load balancer will try to contact. verbose_level This determines how many messages are logged on standard output; larger values log more messages. The default value for this is 3. ip/mask format of IPs DwMain uses both standard ip/netmask formats to specify IPs. An ip is in dotted-decimal format, e.g. "10.1.2.3" (or in ipv6 format when ipv6 support is compiled in). The netmask is used to specify a range of IPs. The netmask can be in one of two formats: A single number between 1 and 32 (128 when ipv6 support is compiled in), which indicates the number of leading "1" bits in the netmask, or a 4-digit dotted-decimal netmask. 10.1.1.1/24 indicates that any ip from 10.1.1.0 to 10.1.1.255 will match. 10.1.1.1/255.255.255.0 is identical to 10.1.1.1/24 10.2.3.4/16 indicates that any ip from 10.2.0.0 to 10.2.255.255 will match. 10.2.3.4/255.255.0.0 is identical to 10.2.3.4/16 127.0.0.0/8 indicates that any ip with "127" as the first octet (number) will match. 127.0.0.0/255.0.0.0 is identical to 127.0.0.0/8 The netmask is optional, and, if not present, indicates that only a single IP will match. DNS over TCP DNS-over-TCP is currently supported using the DwTcp program, which is a simbolic link to DwMain (DwMain checks argv to decide whether to process DNS-over-UDP or DNS-over-TCP). DwMain does not support caching over TCP; it exists so we can resolve the occasional truncated reply or handle the occasional non-RFC-compliant TCP-only DNS resolver. IPV6 support This server can also be optionally compiled to have IPv6 support. In order to enable IPv6 support, add '-DIPV6' to the compile-time flags. For example, to compile this to make a small binary, and to have ipv6 support: export FLAGS='-Os -DIPV6' make SECURITY DwMain is a program written with security in mind. In addition to use a buffer-overflow resistant string library and a coding style and SQA process that checks for buffer overflows and memory leaks, DwMain uses a strong pseudo-random number generator (The 32-bit version of Radio Gatun) to generate both the query ID and source port. For the random number generator to be secure, DwMain needs a good source of entropy; by default Deadwood will use /dev/urandom to get this entropy. If you are on a system without /dev/urandom support, it is important to make sure that DwMain has a good source of entropy so that the query ID and source port are hard to guess (otherwise it is possible to forge DNS packets). Note that DwMain is not protected from someone on the same network viewing packets sent by DwMain and sending forged packets as a reply. To protect DwMain from certain possible denial-of-service attacks, it is best if DwMain's prime number used for hashing elements in the cache is a random 31-bit prime number. The program RandomPrime.c generates a random prime that is placed in the file DwRandPrime.h that is regenerated whenever either the program is compiled or things are cleaned up with make clean. This program uses /dev/urandom for its entropy; the file DwRandPrime.h will not be regenerated on systems without /dev/urandom. On systems without direct /dev/urandom support, it is suggested to see if there is a possible way to give the system a working /dev/urandom. This way, when DwMain is compiled, the hash magic number will be suitably random. If using a precompiled binary of DwMain, or if using a system where it is not feasible to add /dev/urandom support, one can use another system to generate a 31-bit random prime (perhaps using a different system with /dev/urandom support), then use the hash_magic_number parameter to have DwMain use this random prime number. DAEMONIZATION DwMain does not have any built-in daemonization facilities; this is handled by the external program Duende or any other daemonizer. BUGS Deadwood will not parse a file with an incomplete last line (a file where the final line of the file doesn't end with a line feed or carriage return), but will instead report a syntax error on the final line of the file. Example configuration file Here is an example dwood2rc configuration file: # This is an example deadwood rc file # Note that comments are started by the hash symbol bind_address="127.0.0.1" # IP we bind to # The following line is disabled by being commented out #bind_address="::1" # We have optional IPv6 support # Directory we run program from (not used in Win32) chroot_dir = "/etc/deadwood" # Please replace these numbers with the IPs of # real recursive DNS servers; this information # can be obtained from your ISP or network # manager. upstream_servers["."]="10.1.2.3, 10.2.3.4" # Who is allowed to use the cache. This line # allows anyone with "127.0" as the first two # digits of their IP to use DwMain recursive_acl = "127.0.0.1/16" # Maximum number of pending requests maxprocs = 8 # Send SERVER FAIL when overloaded handle_overload = 1 maradns_uid = 99 # UID Deadwood runs as maradns_gid = 99 # GID Deadwood runs as maximum_cache_elements = 60000 # If you want to read and write the cache from disk, # make sure chroot_dir above is readable and writable # by the maradns_uid/gid above, and uncomment the # following line #cache_file = "dw_cache" LEGAL DISCLAIMER THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. AUTHORS Sam Trenholme (http://www.samiam.org) is responsible for this program and man page. He appreciates all of Jean-Jacques Sarton's help giving this program Ipv6 support.