dnscache
, tinydns
, axfrdns
, and walldns
services
The Bernstein dnscache
, tinydns
, axfrdns
, and walldns
tools from djbdns can be run as services, and the proxy and content DNS services are preconfigured with certain defaults.
There are two ways in which these tools can be run as services.
The service bundles package comes with one predefined system-level service bundle for each of dnscache
, tinydns
, axfrdns
, and walldns
; and an associated service bundle for each of the associated log services cyclog@dnscache
, cyclog@tinydns
, cyclog@axfrdns
, and cyclog@walldns
.
The external formats import subsystem enables these service bundles according to the usual presets such as a dnscache_enable="YES"
flag in /etc/rc.conf
.
These service bundles are configured in the conventional ways for djbdns services:
variables named ROOT
, IP
, CACHESIZE
and so forth stored in an environment variable directory in the conventional place for a service.
These can be accessed and modified in the conventional ways:
rcctl set dnscache CACHESIZE 1000000
system-control print-service-env tinydns IP
The exceptions are:
the listening IP address of the axfrdns
service, which is hardwired to ::0
in the service's run
program
the data resource limit of the dnscache
service, which is set with a hardwired use of hardlimit
in the service's run
program
In both cases this is because the run
program is not a shell script and does not have shell variable expansion mechanisms for parameterizing what it passes to hardlimit
and tcp-socket-listen
.
The axfrdns
service uses ucspi-socket-rules-check
, though, which is how one can arrange to restrict client access.
For each of the network addresses listed as network_addresses
in /etc/rc.conf
the external formats import subsystem generates a dnscache@
address, a axfrdns@
address, and a tinydns@
address service.
If there are no network addresses, it generates dnscache@127.0.0.1
, axfrdns@127.53.0.1
, tinydns@127.53.0.1
, and walldns@127.53.1.1
.
This requires the modified dnscache
and tinydns
tools from djbwares, because service management arranges to pass in their listening socket(s), already opened and bound to address, as open file descriptors.
The djbwares versions of the dnscache
and tinydns
tools have been enhanced to be capable of this (the former requiring two open file descriptors, one a TCP listening socket and one a UDP listening socket).
Again, the service bundles are configured in the conventional ways for djbdns services: variables in a conventionally-placed environment variable directory, read by envdir
and understood by rcctl
and other tools.
However, the IP
environment variables are ignored by the djbwares versions of the programs, when they find that they have been supplied the listening socket file descriptors already opened.
The DATALIMIT
variable is also ignored in favour of a hardwired hardlimit
invocation.
The generated per-address services are set up to have their log outputs directed into the log services of the single global services.
The external formats import subsystem again enables these service bundles according to the usual presets, although a flag in /etc/rc.conf
is less convenient than (say) a systemd-style preset file in /etc/system-control/presets/20-dns.preset
containing:
enable dnscache@127.0.0.1 enable cyclog@dnscache enable axfrdns@127.53.0.1 enable cyclog@axfrdns enable tinydns@127.53.0.1 enable cyclog@tinydns enable walldns@127.53.0.1 enable cyclog@walldns
By default, each tinydns
service bundle is set up with its own private service/root
directory, and each axfrdns
is set up with its service/root
symbolically linked to that.
Each service/root
directory contains an individual Makefile
, data
source file, and tools such as add-ns
(which are short scripts that need Laurent Bercot's execlineb
script interpreter).
However, they can be pointed at shared databases in three simple ways, if one wants content served from a common shared database:
Make root
a symbolic link to a common shared root
directory somewhere, just like each axfrdns
service does with its related tinydns
service.
Modify the ROOT
environment variable for the service, by default set in the environment directory to "root
" and thus naming the service/root
directory, to name a common shared root
directory somewhere.
The common shared directory will be a common shared changed-root area for all services sharing it.
It can be anywhere that one likes, with the proviso that the tinydns-d
and axfrdns-d
user accounts must have the privileges to change directory to it (from their service directories) and the privileges to search it for the data.cdb
and to read that file.
One choice, for example, is to use a dns
subdirectory next to the area used by the Bernstein publicfile servers for their data.
Modify the Makefile
to duplicate a common shared data.cdb
instead of compiling it from the local data
source file.
You might be doing this anyway if the content DNS server is supposed to be one of a cluster of such servers, sharing their data.cdb
files from a single database "master".
Or you might be sharing bits and pieces of the source data
file around and have a Makefile
that concatenates them together before compiling them to the data.cdb
database.
How and what one does in this area, and the tradeoffs and design decisions, are well beyond the scope of this Guide however.
By default, each dnscache
service bundle is set up with its own private service/root/ip
and service/root/servers
directories telling it whom to contact with back-end queries and whom to answer on the front end.
It is a rare configuration where one wants to share these amongst multiple dnscache
services, and usually one will not want to do so.
Note:
service/seed
files are not used by these services.
A fresh seed is copied directly from /dev/urandom
for every invocation of the dæmon and sent through a pipe from which it can only be read once.
dnscache
does not require seeds to remain the same from run to run of the server, and a seed in a file has to be (a) only readable by the superuser, (b) specifically not readable by the dnscache-d
user, and (c) not shared amongst multiple dnscache
services.
This makes use of the pipe
utility which can set up a pipeline with the main dæmon process as one of the elements of the pipe (something which cannot be done directly in shell script).
You do not have to turn anything else on if the content DNS server on 127.53.0.1 is the tinydns@127.53.0.1
service, the proxy DNS server on 127.0.0.1 is the dnscache@127.0.0.1
service, and your DNS client library defaults to contacting 127.0.0.1 for proxy DNS service.
Until you change it, the only front-end client that will be recognized according to service/root/ip
will be the client with IP address 127.0.0.1.
You have to explicitly turn on client access to your proxy DNS server to the world.
It is not automatically turned on for you.
Note:
You have to turn on a dnscache
server that listens on something other than 127.0.0.1, too.
The dnscache@127.0.0.1
service provides proxy DNS service to clients on your local machine, which will all talk to it via the IP address 127.0.0.1 which is the one already recognized client.
Note:
If they are configured to talk to it, that is.
You must have the equivalent of nameserver 127.0.0.1
in /etc/resolv.conf
configured somehow.
Again, exactly how to configure your DNS client library to talk to 127.0.0.1 is well beyond the scope of this Guide, involving all sorts of complexities and details from DHCP leases to how resolvconf
and NetworkManager
work.
On the BSDs, if you don't have any nameserver
directives, 127.0.0.1 is the default where the DNS client library goes looking for proxy DNS service; so, again, things should just work with the defaults.
Until you change it, the service/root/servers/@
file in the dnscache@127.0.0.1
service bundle will direct all back-end queries made by dnscache
to a private .
(i.e. root) content DNS server presumed to be listening on 127.53.0.1.
The tinydns@127.53.0.1
content DNS server is set up as a private root content DNS server.
It has delegations in its database for all of the (ICANN) top-level domains, and will direct dnscache
to the second-level content DNS servers appropriately.
It also contains data that will cause it to answer (same-host and same-site originated) queries for reverse lookups of 10.0.0.0/8, 127.0.0.0/8, and 192.168.0.0/16 IP addresses, and some others.
Keeping this as the configured service/root/servers/@
is a good idea for several reasons.
It is generally good practice to run one's own private root content DNS server.
It stops a whole lot of DNS traffic for nonexistent stuff leaking out of one's personal computer, or one's organization, onto the public Internet.
It also means that one is in ultimate control of one's own root, rather than relying upon the altruism of an outside party.
(It's not something that North Americans tend to appreciate; but the fact that ICANN is sponsored and controlled by the U.S. government is a worry for people in other countries and on other continents.)
It's also resilient even if the machine's own immediate network connection is lost, and available in the bootstrap even before a machine has gained DHCP leases.