=head1 NAME

gdnsd - An authoritative DNS daemon

=head1 SYNOPSIS

  Usage: gdnsd [-fsSD] [-c @GDNSD_DEFPATH_CONFIG@] <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

=head1 DESCRIPTION

B<gdnsd> is very fast, light, and pluggable authoritative DNS daemon.

=head1 BASIC SECURITY

When started as the C<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 C<gdnsd>, but this can
be overridden in the main config file.

=head1 BASIC CONFIGURATION

The primary configuration file is the file named F<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 C<0.0.0.0> and C<::>
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 F<zones/> subdirectory of the configuration
directory (C<@GDNSD_DEFPATH_CONFIG@/zones/>).

=head1 COMMANDLINE OPTION FLAGS

=over 4

=item B<-c>

Set the configuration directory, defaults to F<@GDNSD_DEFPATH_CONFIG@>.

=item B<-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 C<-f>, the new daemon will not
use C<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 C<-x> regarding syslog output.

=item B<-s>

Forces the C<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 C<checkconf> option.

=item B<-S>

Forces the C<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 C<checkconf> option.

=item B<-D>

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

=item B<-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 C<-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.

=back

=head1 ACTIONS

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

=over 4

=item B<checkconf>

Checks the validity of the configuration file and zonefiles, setting
the exit status appropriately (0 for success).

The C<start>, and all C<restart>-like actions implicitly do
the same checks as C<checkconf> as they load the configuration for
runtime use.

=item B<start>

Starts gdnsd as a runtime DNS daemon.

=item B<stop>

Stops a gdnsd daemon previously started by start.

=item B<restart>

This is equivalent to the sequence C<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.

C<restart> is a special case of C<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 C<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 C<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.

C<SO_REUSEPORT> became available in Linux starting with kernel
version 3.9.  BSDs have had it for much longer.

Note: C<restart> will B<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.  C<systemctl restart gdnsd>, which will do a full
serial stop -> start cycle, in order for configuration changes to take
effect.

=item B<reload-zones>

Sends C<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 C<zones_rfc1035_auto>
has been explicitly set to C<false>, disabling the default mode
where gdnsd continuously monitors for and loads zonefile data
changes.

It is not advised to set up an initscript C<reload> action which
invokes C<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.

=item B<condrestart>

This is basically "restart only if already running".

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

=item B<try-restart>

Alias for C<condrestart>.

=item B<status>

Checks the status of the running daemon, returning 0 if it
is running or non-zero if it isn't.

=back

Any other commandline option will be treated as invalid,
which will result in displaying a short help text to F<STDERR>
and exiting with a non-zero exit status.  This includes
things like the ubiquitous B<--help> and B<--version>.

=head1 ZONE FILES - RFC1035

The directory for standard RFC1035 zone files (the default
zone data backend) is the subdirectory named C<zones> in the
configuration directory, so the default would be
F<@GDNSD_DEFPATH_CONFIG@/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
L<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
C<.> 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 C<gdnsd reload-zones> is required to
re-scan for changes) in the config file via the directive
C<zones_rfc1035_auto> (see L<gdnsd.config(5)>).  It is legal for
the directory to be empty at startup, which results in all queries
returning C<REFUSED>.

In order to better support the special case of RFC 2137 -style
classless in-addr.arpa delegation zones (which contain forward
slashes), any C<@> symbol in the filename will be translated
to a forward slash (C</>) 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 F<ROOT_ZONE>, rather than the impossible
literal filename F<.>.  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. C<\.> for a dot within a label, or C<\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. F<example.com>
and F<example.com.> are functionally equivalent.

Duplicate zones (e.g. having both of the above representations of
C<example.com> present in the zones directory, and/or adding a
different case-mapping such as F<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 C<serial> wins,
and if more than one file has the highest serial, the highest
filesystem C<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 C<example.com> and
C<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 (C<rename()>, C<unlink()>, C<link()>) to alter the zone
files.  See the documentation for C<zones_rfc1035_quiesce> in
L<gdnsd.config(5)> for more details about this.

=head1 ZONE FILES - DJBDNS

There is now experimental support for djbdns-format zonefiles
in the F<djbdns> subdirectory of the config directory
(default F<@GDNSD_DEFPATH_CONFIG@/djbdns/>.  For more information
see L<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).

=head1 DIRECTORIES

Important directory paths for the core daemon code:

=over 4

=item F<@GDNSD_DEFPATH_CONFIG@>

Default configuration directory, unless overridden via C<-c>.  The
primary configuration file is always the file F<config> in the
configuration directory.

=item F<@GDNSD_DEFPATH_RUN@>

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 C<run_dir> in the L<gdnsd.config(5)> manpage
for more information about this directory.

=item F<@GDNSD_DEFPATH_STATE@>

Default state_dir.  The F<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 C<state_dir> in the
L<gdnsd.config(5)> manpage for more information about this directory.

=item F<@GDNSD_DEFPATH_LIB@>

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 C<plugin_search_path>, documented in L<gdnsd.config(5)>.

=item F<@GDNSD_DEFPATH_LIBEXEC@>

This is the default path for daemon-private executables that users should
not run.  The only current case is F<gdnsd_extmon_helper> for the
extmon plugin and the path for this can be overridden in that plugin's
configuration, documented in L<gdnsd-plugin-extmon(8)>.

=back

=head1 ADMIN STATE FILE - F<@GDNSD_DEFPATH_STATE@/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 L<gdnsd.config(5)>).  This file is parsed as a vscf hash
data structure (again, see L<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
C<THING/service_type>, where C<THING> is the monitored address or CNAME value
and C<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 C<STATE[/TTL]>, where C<STATE> is C<UP> or C<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:

    @GDNSD_DEFPATH_STATE@/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 C<service_type>) solely for the purpose of administrative
override of decision-making.  Currently the geoip and metafo plugins do this
for their C<datacenters>, and the keys they create take the form of
C<plugin_name/resname/dcname> to force a datacenter's state at the
per-resource level.  The geoip plugin also supports keys of the form
C<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:

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

=head1 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 C<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 C<NotifyAccess=all> setting, and that the C<ExecStart=> command for
gdnsd uses a commandline that resembles C<gdnsd -f start> and
does not use C<-x> (other extra options are ok).

Example unit file contents for the Service section:

    [Service]
    Type=notify
    NotifyAccess=all
    ExecStart=@GDNSD_SBINDIR@/gdnsd -f start
    ExecStop=@GDNSD_SBINDIR@/gdnsd stop

It is not advised to set up C<ExecReload=@GDNSD_SBINDIR@/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 C<ExecReload=@GDNSD_SBINDIR@/gdnsd restart>, as this
will B<not> work!

In general, if you're running gdnsd as a systemd service, you should use
the supplied style of unit file and use C<systemctl> for daemon control
(e.g. start, stop, restart, status), and use C<@GDNSD_SBINDIR@/gdnsd reload-zones>
for zone reloads.

=head1 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.

=over 4

=item B<SIGTERM>, B<SIGINT>

Causes the daemon to exit gracefully with accompanying log output.

=item B<SIGUSR1>

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

=item B<SIGHUP>

Ignored during daemon runtime.

=item B<SIGPIPE>

Ignored always.

=back

=head1 EXIT STATUS

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

=head1 SEE ALSO

L<gdnsd.config(5)>, L<gdnsd.zonefile(5)>, L<gdnsd.djbdns(5)>

The gdnsd manual.

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

=cut
