skadns
Software
www.skarnet.org
The skadnsd program
skadnsd is the skadns daemon. It reads a series of
queries on stdin, resolves them asynchronously, and writes
the answers to stdout as soon as it gets them. It exits 0
when its stdin closes. It exits 111 on any serious error,
writing the error message to stderr.
skadnsd is a stub resolver. It reads /etc/resolv.conf
every 10 minutes or 10000 queries, looking for a "nameserver" line containing
the address of a DNS cache (aka full resolver). It will exit 111 if it cannot
find any valid cache address in /etc/resolv.conf. If the
DNSCACHEIP environment variable is set, its value overrides
what /etc/resolv.conf says.
Interface
skadnsd does not fork, does not background itself automatically,
and does not use syslog. It is not meant to be run directly by the
user: it will be invoked and spawned by the skadns library calls.
There are 2 ways to use skadnsd:
- (preferred) Use the skadns_startf() library call.
A skadnsd child will then be spawned from your
calling process, and automatically reaped when you call
skadns_end(). It requires care with applications that
trap SIGCHLD.
- Use the skadns_start() library call, together with
a skadnsd service.
Running skadnsd as a child process
This is the simplest and safest way of using skadns. Forget
about skadnsd: just start your library calls with
skadns_startf() and end them with skadns_end().
Be careful though: if you're using SIGCHLD handlers, make sure they do
not interfere with the child processes your application has without
knowing. This is a general Unix programming rule.
Running skadnsd as a daemon
skadnsd has no "standalone" mode: it is designed to work with a Unix
domain super-server, like
ipcserver
or unixserver.
You should run skadnsd (and its Unix super-server) under a specific user
and group, for elementary security reasons; and you should run its
dedicated logger as another specific user. Do NOT run skadnsd as root -
you have been warned. Check your super-server documentation to find how
to run it under a specific account.
daemontools users will
find an example service directory in .../service/skadnsd.
Example run scripts in the shell language (run.sh) and
in the execline
language (run.exl) are provided.
It is possible to run skadnsd without daemontools: a command line such as
ipcserver -l0 -u `id -u skadns` -g `id -g skadns` /path/to/socket skadnsd 2>&1 | su dnslog logger -p daemon.err &
should work, if /path/to/socket matches SKADNS_IPCPATH in include/skadns.h.
Be aware that running skadnsd without daemontools is unsupported - and since you
installed ucspi-ipc or ucspi-unix, you will get to like the style, and eventually
switch to daemontools. :-)
Notes
- If a bad-designed client sends a lot of queries and never reads the
answers, those will indefinitely queue up in the daemon, eating up
memory. You should run your process (or your Unix super-server, if you're
using a skadnsd service) under a program like
softlimit to
set a memory limit to every skadnsd instance. If skadnsd runs out of
allowed memory, it will just die.
- Under Linux, when skadns is statically linked against the
dietlibc, with the default
SKADNS_MAXCONCURRENCY value of 1000, you should be safe with setting
a memory limit of 250 kB for skadnsd. (To reduce that size, decrease
SKADNS_MAXCONCURRENCY.) On any system, if you linked skadns dynamically
with your C library, add some space for it. In any case, if skadnsd
needs more than one megabyte of memory, then fix your client.
- If you're using a skadnsd service: you should configure your
Unix super-server to set a maximum
number of concurrent skadnsd instances; ipcserver and unixserver have
the -c option for this.
- There is currently no way to specify a maximum number of
concurrent daemon instances for the same client: this allows
trivial denial-of-service attacks. I'd like that functionality to
be implemented in super-servers: with an inet super-server, use the
IP address (${$PROTO}REMOTEIP) to identify the client, and with a
unix super-server, use the uid (${$PROTO}REMOTEEUID) to identify the
client - though it would not be portable, since many systems have no
getpeereid
implementation yet.
- The only way to ensure absolute reliability of the skadnsd process is
to run it as a child, not as a daemon: use skadnsd_startf() when
possible.