GDNSD(8)

NAME
gdnsd - An authoritative DNS daemon

SYNOPSIS
  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)
  Actions:
    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

DESCRIPTION
gdnsd is very fast, light, and pluggable authoritative DNS daemon.

BASIC SECURITY
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.

BASIC CONFIGURATION
The primary configuration file is the file named config in the configuration directory.

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 directory ("/etc/gdnsd/zones/").

COMMANDLINE OPTION FLAGS

-c  Set the configuration directory, defaults to /etc/gdnsd.

-f  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.

-s  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 "checkconf" option.

-S  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 "checkconf" option.

-D  Enables additional debugging output to syslog and/or the terminal, as appropriate.

-x  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 commandline arguments.

    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 runtime daemon.

    Do not use this flag for a start invocation within a systemd unit file.

ACTIONS
gdnsd acts as its own initscript, internalizing daemon management functions. All valid invocations of the gdnsd command include an action, 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.

checkconf
    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.

start
    Starts gdnsd as a runtime DNS daemon.

stop
    Stops a gdnsd daemon previously started by start.

restart
    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 of resources.

    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 it exited.

    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 effect.

reload-zones
    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 occurs.

condrestart
    This is basically "restart only if already running".

    Performs the same actions as "restart", but aborts early (with a successful exit value) if the daemon was not already running.

try-restart
    Alias for "condrestart".

status
    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 and --version.

ZONE FILES - RFC1035
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 gdnsd.config(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 ROOT_ZONE, 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 and 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 about this.

ZONE FILES - DJBDNS
There is now experimental support for djbdns-format zonefiles in the djbdns subdirectory of the config directory (default /etc/gdnsd/djbdns/. For more information see gdnsd.djbdns(5).

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).

DIRECTORIES
Important directory paths for the core daemon code:

/etc/gdnsd
    Default configuration directory, unless overridden via "-c". The primary configuration file is always the file config in the configuration directory.

/var/run//gdnsd
    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 directory.

/var/lib/gdnsd
    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 directory.

/usr/local/lib/gdnsd
    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 gdnsd.config(5).

/usr/local/libexec/gdnsd
    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 gdnsd-plugin-extmon(8).

ADMIN STATE FILE - /var/lib/gdnsd/admin_state
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 multiple resources.

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.

Example:

    /var/lib/gdnsd/admin_state:
        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 state.

Example:

    /var/lib/gdnsd/admin_state:
        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.

SYSTEMD COMPATIBILITY
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 works correctly.

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 system.

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:

    [Service]
    Type=notify
    NotifyAccess=all
    ExecStart=/usr/local/sbin/gdnsd -f start
    ExecStop=/usr/local/sbin/gdnsd stop

It is not advised to set up "ExecReload=/usr/local/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/local/sbin/gdnsd restart", as this will not work!

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/local/sbin/gdnsd reload-zones" for zone reloads.

SIGNALS
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 output.

SIGUSR1
    Causes the daemon to attempt to load any new changes to the zone data.

SIGHUP
    Ignored during daemon runtime.

SIGPIPE
    Ignored always.

EXIT STATUS
An exit status of zero indicates success, anything else indicates failure.

SEE ALSO
gdnsd.config(5), gdnsd.zonefile(5), gdnsd.djbdns(5)

The gdnsd manual.

COPYRIGHT AND LICENSE
Copyright (c) 2012 Brandon L Black <blblack@gmail.com>

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 version.

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/>.