gdnsd - An authoritative DNS daemon
Usage: gdnsd [-fsSD] [-c /etc/gdnsd] <action>
-D - Enable verbose debug output
-f - Foreground mode for [re]start actions
-s - Force 'zones_strict_startup = true' for this invocation
-S - Force 'zones_strict_data = true' for this invocation
-c - Configuration directory
-x - No syslog output (must use -f with this if [re]start)
checkconf - Checks validity of config and zone files
start - Start as a regular daemon
stop - Stops a running daemon previously started by 'start'
reload-zones - Send SIGUSR1 to running daemon for zone data reload
restart - Equivalent to checkconf && stop && start, but faster
condrestart - Does 'restart' action only if already running
try-restart - Aliases 'condrestart'
status - Checks the status of the running daemon
is very fast, light, and pluggable authoritative DNS daemon.
When started as the "root" user, gdnsd will always attempt to drop
privileges to another user, and will fail fatally if that does not succeed.
The default username for this is "gdnsd", but this can be overridden
in the main config file.
The primary configuration file is the file named config
Note that the configuration file does not have to exist for successful startup.
Without a configuration file, gdnsd will load all of the zones in the zones
directory and listen on port 53 of 0.0.0.0 and "::" using default
settings. It will also, by default, automatically process changes
(add/delete/update) to the set of zonefiles present in the zones directory,
which defaults to the zones/
subdirectory of the configuration
- Set the configuration directory, defaults to
- Sets foreground mode for the start, restart, condrestart,
or try-restart actions. All other actions are implicitly foreground
operations and ignore this flag. When [re]starting with "-f",
the new daemon will not use "fork(); setsid(); fork();" to
detach from the terminal, and will not close default stdio descriptors or
stop mirroring its log output to the stdio descriptors at runtime.
Otherwise it behaves the same as an invocation without this flag. See also
"-x" regarding syslog output.
- Forces the "zones_strict_startup" configuration
option to true for this invocation, regardless of the setting in the
config file. This is mostly useful for validation during the
- Forces the "zones_strict_data" configuration
option to true for this invocation, regardless of the setting in the
config file. This is mostly useful for validation during the
- Enables additional debugging output to syslog and/or the
terminal, as appropriate.
- Disables syslog output completely. By default, almost all
possible output from all gdnsd invocations is sent to syslog, even if it
is also mirrored to the terminal. The only exception to this rule (well,
apart from certain early fatal log outputs which are only triggered in the
case of internal code bugs) is the commandline usage output on invalid
This flag is only legal for the start, restart, condrestart, and try-restart
options if used in combination with the "-f" flag (as otherwise
the resulting daemon could end up with no error output channel at all). It
is legal for all other commands (which are all implicitly foreground
actions, and all also output to syslog by default).
Primarily intended for e.g. linting invocations of checkconf, the daemon's
testsuite, etc, to avoid spamming syslog with things unrelated to a real
Do not use this flag for a start invocation within a systemd unit file.
acts as its own initscript, internalizing daemon management
functions. All valid invocations of the gdnsd command include an
, most of which model normal initscript actions. You may still
want a light initscript wrapper to comply with distribution standards for e.g.
terminal output on success/failure, setting up resource and security limits,
etc, but it's not necessary for basic functionality.
- Checks the validity of the configuration file and
zonefiles, setting the exit status appropriately (0 for success).
The "start", and all "restart"-like actions implicitly
do the same checks as "checkconf" as they load the configuration
for runtime use.
- Starts gdnsd as a runtime DNS daemon.
- Stops a gdnsd daemon previously started by start.
- This is equivalent to the sequence "checkconf
&& stop && start". What actually happens behind the
scenes is a bit more complicated, with the goal of making restarts as
seamless and downtime-free as possible.
"restart" is a special case of "start" which first
completely starts itself (including the acquisition of listening sockets,
if possible, see below) and is ready to answer requests *before* it stops
the previous instance of the daemon. This eliminates any stop -> start
delays from expensive startup steps like parsing large numbers of
zonefiles and/or polling for initial monitoring results on a large number
On platforms where "SO_REUSEPORT" works correctly, the new daemon
uses this option (as did the old) to start its listening sockets in
parallel with those of the previous daemon just before sending the
termination signal to it, to eliminate any window of true unavailability.
However, keep in mind that a handful of requests will still be lost: those
which were already in the local socket buffers for the old instance when
If "SO_REUSEPORT" isn't supported or doesn't work properly, the
daemon will re-attempt its socket acquisition after the short delay of
waiting for the previous daemon's pid to exit. The delay should normally
be fairly constant (does not scale up with zones/configuration) and
minimal in these cases, on the order of <1s.
"SO_REUSEPORT" became available in Linux starting with kernel
version 3.9. BSDs have had it for much longer.
Note: "restart" will not work correctly for a daemon that's
running under systemd, no matter how it's executed. Executing it from the
commandline will sort-of work in that it will replace the daemon that's
running as a systemd service with one that isn't a systemd service, but
that probably isn't what you want to do. Those running under systemd will
need to use e.g. "systemctl restart gdnsd", which will do a full
serial stop -> start cycle, in order for configuration changes to take
- Sends "SIGUSR1" to the running daemon, forcing a
manual re-check of the zones directory for updated files. Generally this
should only be necessary if the configuration option
"zones_rfc1035_auto" has been explicitly set to
"false", disabling the default mode where gdnsd continuously
monitors for and loads zonefile data changes.
It is not advised to set up an initscript "reload" action which
invokes "reload-zones", as a future version of gdnsd will very
likely include a true reload action for full re-configuration without
restart. It's better to leave the canonical reload action undefined for
now to reduce incompatibilities and/or surprises when that update
- This is basically "restart only if already
Performs the same actions as "restart", but aborts early (with a
successful exit value) if the daemon was not already running.
- Alias for "condrestart".
- Checks the status of the running daemon, returning 0 if it
is running or non-zero if it isn't.
Any other commandline option will be treated as invalid, which will result in
displaying a short help text to STDERR
and exiting with a non-zero exit
status. This includes things like the ubiquitous --help
The directory for standard RFC1035 zone files (the default zone data backend) is
the subdirectory named "zones" in the configuration directory, so
the default would be /etc/gdnsd/zones/
RFC1035 zone files are the traditional zone file format that one typically uses
with e.g. BIND. For more information on the internal format and processing of
these files, see gdnsd.zonefile
(5). This section is about how the
directory itself is managed.
All files in the zones directory are considered zone files. In general there
should be exactly one file per zone, and the filename should match the zone
name. Filenames beginning with "." are ignored. All zone file must
be regular files (as opposed to directories, symlinks, sockets, etc).
By default, the zones directory is handled dynamically: as files are added,
modified, and deleted in this directory, zone data will automatically update
at runtime. This feature can be disabled (such that an explicit SIGUSR1 or
"gdnsd reload-zones" is required to re-scan for changes) in the
config file via the directive "zones_rfc1035_auto" (see
(5)). It is legal for the directory to be empty at startup,
which results in all queries returning "REFUSED".
In order to better support the special case of RFC 2137 -style classless
in-addr.arpa delegation zones (which contain forward slashes), any
"@" symbol in the filename will be translated to a forward slash
("/") when transforming a filename into its corresponding zone name.
For similar reasons, if your server is intended to serve the root of the DNS,
the filename for the root zone should be the special filename
, rather than the impossible literal filename .
Because authoritative servers cannot serve two domains which have a
parent<->child relationship correctly, a root server cannot serve any
other zone, so this would be the sole zonefile.
The standard DNS zone file escape sequences are recognized within the filenames
(e.g. "\." for a dot within a label, or "\NNN" where NNN
is a decimal integer in the range 0 - 255), if for some reason you need a
strange character in your zone name.
Trailing dots on zonefile names are ignored; e.g. example.com
are functionally equivalent.
Duplicate zones (e.g. having both of the above representations of
"example.com" present in the zones directory, and/or adding a
different case-mapping such as EXample.Com
) are handled by loading both
and giving runtime lookup priority to one of the copies based on a couple of
simple rules: the highest "serial" wins, and if more than one file
has the highest serial, the highest filesystem "mtime" value wins.
If the primary copy is later removed, any remaining copy of the zone will be
promoted for runtime lookups according to that same ordering.
Subzones (e.g. having zonefiles for both "example.com" and
"subz.example.com") are only marginally supported. The child zone
will be loaded into memory, but its data won't be available for lookup, as it
is suppressed by the existence of the parent zone. If the parent zone is later
removed, the subzone data will become available. Logically, it is not possible
for a single server to be authoritative for both a subzone and its parent zone
at the same time, as each "role" (parent and child) requires
different responses to requests for data within the child zone. gdnsd choses
to default to the "parent" role in these conflict cases.
Tools which are used to update zonefiles while gdnsd is running should always
use atomic operations ("rename()", "unlink()",
"link()") to alter the zone files. See the documentation for
"zones_rfc1035_quiesce" in gdnsd.config
(5) for more details
There is now experimental support for djbdns-format zonefiles in the
subdirectory of the config directory (default
. For more information see gdnsd.djbdns
If the same zone is specified via more than one zone data backend (e.g. rfc1035
+ djbdns), the same rules shown in the above section apply: both will be
loaded and managed, but only one will be used for queries at any given time
(based on mtime/serial).
Important directory paths for the core daemon code:
- Default configuration directory, unless overridden via
"-c". The primary configuration file is always the file
config in the configuration directory.
- Default run_dir. The daemon will store a pidfile here
(which is not intended for reliable text-based consumption by third
parties). See the entry for "run_dir" in the
gdnsd.config(5) manpage for more information about this
- Default state_dir. The admin_state file is read from
this directory for administrative state-overrides on monitored resources,
see below in the FILES section. See the entry for "state_dir" in
the gdnsd.config(5) manpage for more information about this
- This is the default path that plugin shared libraries are
loaded from. Other directories can be prepended to the search path via the
configuration option "plugin_search_path", documented in
- This is the default path for daemon-private executables
that users should not run. The only current case is
gdnsd_extmon_helper for the extmon plugin and the path for this can
be overridden in that plugin's configuration, documented in
This file is the input for administrative state overrides affecting plugin
resolution decisions. The intent of this file is to allow explicit, human
administrative decisions to temporarily override the states affecting plugin
decision-making on issues of failover and/or geographic distribution. A
non-existent file is treated the same as an empty file. The file is watched at
runtime for changes, and any overridden state found is applied quickly. The
file is expected to persist reboots and daemon restarts in order to preserve
the administrator's intent through these events.
A basic understanding of how both monitoring and resolution plugins in gdnsd
work is assumed (see gdnsd.config
(5)). This file is parsed as a vscf
hash data structure (again, see gdnsd.config
(5) for deeper details of
that format). The keys are the names of monitored or virtual resources, and
the values are forced state values (optionally with monitored-TTL values as
well). Keys can also be wildcards using the shell glob syntax which affect
For normal monitored resources, the typical form of a key would be
"THING/service_type", where "THING" is the monitored
address or CNAME value and "service_type" is the service_type
configured to monitor that address or CNAME value by one or more resolver
plugins. The value portion takes the form of "STATE[/TTL]", where
"STATE" is "UP" or "DOWN" and the TTL portion is
an optional override of the monitored TTL.
The order of the lines in the file is important; they are processed and applied
in-order such that later lines can override the actions of earlier lines. This
is especially handy for making exceptions to glob-matches.
2001:db8::2:123/my_http_check => DOWN # down a specific res+stype
foo.example.com./extmon_ping => UP # up a specific res+stype
192.0.2.1/* => DOWN # down all service_types for this address
*/xmpp => UP/30 # up all resources monitored by xmpp w/ TTL 30 ...
192.0.2.2/xmpp => DOWN # ... except this one
Some resolution plugins can also register virtual resources (which are not
monitored by any "service_type") solely for the purpose of
administrative override of decision-making. Currently the geoip and metafo
plugins do this for their "datacenters", and the keys they create
take the form of "plugin_name/resname/dcname" to force a
datacenter's state at the per-resource level. The geoip plugin also supports
keys of the form "plugin_name/mapname/dcname" to force a
datacenter's state at the per-map level. These forcings override the aggregate
state passed up to geoip/metafo from per-datacenter plugins (e.g. multifo or
weighted monitoring several addresses in a datacenter), and in the geoip case
the more-specific per-resource forced state will override any per-map forced
geoip/map3/dc-us => DOWN # down dc-us in geoip map3
*/dc-jp => DOWN # down all datacenters named dc-jp for geoip and metafo
metafo/res_www/dc-jp => UP # exception to above
All of the available monitored and virtual keys that can be matched in this file
are listed in the daemon's HTML, CSV, and JSON -format outputs from the
built-in status http server (default port 3506), as are their current monitors
and admin_state-forced states.
This daemon is implicitly compatible with running as a systemd service on Linux,
and should have come with a ready-made unit file during installation that
When the daemon detects that it's running underneath systemd as a unit (by
detecting that systemd is the running init system and that gdnsd's initial
parent pid is 1), it makes some changes to its default behaviors to be more
systemd-friendly. This includes shutting off stdio output very early (as soon
as syslog is open) because the stdio and syslog output channels are redundant
under systemd and lead to duplicate messages in the journal. It also makes use
of systemd's notification socket to coordinate operations with the init
Because of these things, it is critical that the gdnsd unit file uses the
"NotifyAccess=all" setting, and that the "ExecStart="
command for gdnsd uses a commandline that resembles "gdnsd -f start"
and does not use "-x" (other extra options are ok).
Example unit file contents for the Service section:
ExecStart=/usr/sbin/gdnsd -f start
It is not advised to set up "ExecReload=/usr/sbin/gdnsd reload-zones"
to re-purpose the systemctl reload action for zone reloads, as a future
version of gdnsd will very likely include a real option for full configuration
reload under systemd, which would change this behavior. It's better to leave
the canonical reload action undefined for now to reduce incompatibilities
and/or surprises when that update occurs. It is even less advised to try to
configure "ExecReload=/usr/sbin/gdnsd restart", as this will
In general, if you're running gdnsd as a systemd service, you should use the
supplied style of unit file and use "systemctl" for daemon control
(e.g. start, stop, restart, status), and use "/usr/sbin/gdnsd
reload-zones" for zone reloads.
Any signal not explicitly mentioned is not explicitly handled. That is to say,
they will have their default actions, which often include aborting execution.
- SIGTERM, SIGINT
- Causes the daemon to exit gracefully with accompanying log
- Causes the daemon to attempt to load any new changes to the
- Ignored during daemon runtime.
- Ignored always.
An exit status of zero indicates success, anything else indicates failure.
The gdnsd manual.
Copyright (c) 2012 Brandon L Black <firstname.lastname@example.org>
This file is part of gdnsd.
gdnsd is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
gdnsd is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
gdnsd. If not, see <http://www.gnu.org/licenses/>.