We now have real documentation!

This commit is contained in:
Baptiste Jonglez 2017-09-01 15:24:29 +02:00
parent 3dfe3fef0d
commit f607fff0f8
1 changed files with 262 additions and 24 deletions

286
README.md
View File

@ -1,38 +1,276 @@
# Ansible role for NSD
It is assumed that all machines host the exact same zones in the same way
(i.e. for each zone, they are either all masters, or all slaves).
This Ansible role installs and configure NSD, an authoritative DNS server.
## Features
This role supports both NSD3 and NSD4, allows to manage both NSD configuration
and zone files, in master or slave mode, with or without zone transfer (TSIG).
Most notably, compared to other NSD roles ([elnappo](https://github.com/elnappo/ansible-role-nsd),
[reallyenglish](https://github.com/reallyenglish/ansible-role-nsd), [creicm](https://github.com/criecm/ansible-role-nsd),
[adarnimrod](https://github.com/adarnimrod/nsd), [hudecof](https://github.com/hudecof/ansible_authoritative_dns)),
it has the following features:
- allows to store zone data in "classical" zone files, instead of having to write
zones as ansible variables like [here](https://github.com/reallyenglish/ansible-role-nsd)
- supports both master and slave scenarios, or even a mixture of both
(some zones running as master and some zones running as slave, on the same
NSD server)
- completely generic NSD configuration (you are free to define any configuration
attribute supported by NSD, there is no hard-coded list in the role). This is
similar to [here](https://github.com/reallyenglish/ansible-role-nsd) but with a
simpler syntax (automatic expansion of lists)
- supports zone transfers: TSIG keys, notify slaves...
- hopefully flexible yet simple to use!
However, it does not handles other things like firewall configuration or emails,
and only supports Debian for now.
## Use-cases
Note: all these use-cases can be used independently for each zone! That is,
a single NSD server can be both a master for `example.com` and a slave for
`example.org`.
### Pure multi-master
If all your DNS servers are configured with Ansible, this is the simplest setup:
all servers are masters for the zone, and zone data is deployed using Ansible.
In this setup, there is no need for DNS-based zone transfers.
### Multi-master with additional slaves not configured by this role
In this setup, one or more master is configured using Ansible, like in the previous
use-case. However, DNS-based zone transfer is also setup, to allow external slaves
to fetch zone data from a master. Whenever Ansible updates a zone on the masters,
it will tell NSD to notify the slaves.
Note that in this setup, it is your responsibility to configure the slaves appropriately
(accept notify from all masters, and fetch zone data from one or more masters).
### Slave only
In this setup, the NSD servers are simply configured as slaves for the zone.
In this case, no zone data is configured on the servers, because data will be fetched
from an external master using normal zone transfer mechanisms.
Note that in this setup, it is your responsibility to configure the master appropriately
(notify the slaves, and allow zone transfers from the slaves).
## Requirements
This role has been tested on Debian (wheezy, jessie, stretch), but could be adapted
to work on other systems. Notably, this role does not setup `nsd-control` because
this is already done automatically by the Debian package.
By default, NSD4 is assumed, you will need additional configuration for NSD3 (wheezy).
## Role variables
This documents all role variables that you can set in your playbooks. See the end
of this README for a complete example.
### Server configuration
nsd_server_config
Dictionary of key-value pairs that will be added to the `server:` configuration
section of NSD. A value can be either a string or a list. In the latter case,
the value will be expanded into multiple configuration entries.
You can add any configuration option you want in this dictionary, but make sure
that it is a configuration option understood by NSD!
As a safety net, the role asks NSD to verify the generated configuration before
proceeding, but this will not be done when running `ansible-playbook --check`.
nsd_local_server_config
Same syntax and semantic as `nsd_server_config`.
This second variable is provided so that it's easier to add specific configuration
to a single machine. You would typically define `nsd_server_config` in `group_vars`
or in a playbook, while `nsd_local_server_config` would be defined in `host_vars`.
### TSIG keys
nsd_tsig_keys
List of TSIG keys. Each key must be a dictionary with the following attributes:
* `tsig_keyname`: name of this TSIG key. Note that in a master/slave DNS configuration,
the name of the TSIG key must be the same on master and slaves! This name is also
used to refer to TSIG keys from the `nsd_primary_zones` and `nsd_secondary_zones` role
variables. **Mandatory**.
* `tsig_secret`: base64-encoded value of the key. **Mandatory**.
* `tsig_algorithm`: algorithm used by the key, for instance `hmac-md5`. **Mandatory**.
### Primary zones
nsd_primary_zones
List of zones to be served as master. Each zone must be a dictionary with the following
attributes:
* `zone_name`: name of the zone, for instance `example.com` or `8.b.d.0.1.0.0.2.ip6.arpa.`. **Mandatory**.
* `zone_filename`: name of the file containing zone data (will be searched for in `files/nsd/`). **Mandatory**.
* `slaves`: list of DNS slaves, format is described below. **Optional**.
The format for a slave entry is the following:
* `ip`: IPv4 or IPv6 address of the DNS slave. Will be used to send "notify" messages,
and to allow zone transfers from this IP. **Mandatory**.
* `tsig_key`: name of the TSIG key to use when communicating with this slave. The name
must match the `tsig_keyname` field of a previously-defined TSIG key, see above. **Optional**.
### Secondary zones
nsd_secondary_zones
List of zones to be served as slave. Each zone must be a dictionary with the following
attributes:
* `zone_name`: name of the zone, for instance `example.com` or `8.b.d.0.1.0.0.2.ip6.arpa.`. **Mandatory**.
* `masters`: list of DNS masters, format is described below. **Optional** but a slave zone is quite useless without master.
The format for a master entry is the following:
* `ip`: IPv4 or IPv6 address of the DNS master. Will be used to request zone transfers,
and to allow notify messages. **Mandatory**.
* `tsig_key`: name of the TSIG key to use when communicating with this master. The name
must match the `tsig_keyname` field of a previously-defined TSIG key, see above. **Optional**.
### Advanced configuration variables
These variables should not need to be changed in most cases.
Variables are presented here with their default value.
nsd_version: 4
The version of NSD. Used to skip tasks or handlers that do not make
sense depending on the version.
nsd_service_name: "nsd"
The name of the init service, used to restart NSD.
nsd_pkg_name: "nsd"
Name of the Debian package to install.
nsd_control_program: "/usr/sbin/nsd-control"
Program used to control NSD, for reload, rebuild, notify...
nsd_config_dir: "/etc/nsd"
Directory where NSD configuration will be stored.
nsd_zones_config_file: "/etc/nsd/zones.conf"
Name of the config file that will hold zone configuration (it is then
included from the main NSD configuration file).
nsd_primary_zones_dir: "/etc/nsd/primary"
Directory where the zone files will be copied by this role.
nsd_secondary_zones_dir: "/etc/nsd/secondary"
Directory where slave zone files will be placed by NSD after zone transfer.
### Configuration for NSD3
For NSD3 on Debian an appropriate configuration would be:
nsd_version: 3
nsd_service_name: "nsd3"
nsd_pkg_name: "nsd3"
nsd_control_program: "/usr/sbin/nsdc"
nsd_config_dir: "/etc/nsd3"
nsd_zones_config_file: "/etc/nsd3/zones.conf"
nsd_primary_zones_dir: "/etc/nsd3/primary"
nsd_secondary_zones_dir: "/etc/nsd3/secondary"
This could be placed in a `group_vars/wheezy.yml` file or equivalent.
## Example playbook
This is a complete example playbook with several TSIG keys and several DNS zones:
the first zone is a primary zone with no slave, the second zone has two slaves, and
the third zone is a secondary zone with two masters.
- hosts: dnsservers
roles:
- nsd
vars:
nsd_server_config:
verbosity: 2
ip4-only: 'yes'
nsd_tsig_keys:
# Two TSIG keys, used in zone definition below
- tsig_keyname: "tsig-key.example.org"
tsig_secret: "3znH//y866vzpOZdahYYUlWeiY4iidiJGFRX6CI6OkUBggRNYFpZAMvlYbtnUosiBVPsgghA6zT0TzOEX0vetQ=="
tsig_algorithm: hmac-md5
- tsig_keyname: "key-eu.org"
tsig_secret: "t6ELXqsSLYl57iO2rxj+X9+DNpOV3exTBFWu9wS/3jI="
tsig_algorithm: hmac-sha256
nsd_primary_zones:
# Master zone without slave
- zone_name: "example.com."
zone_filename: "example.com.zone"
# Master zone with two slaves, one dual-stacked with a TSIG key, and one single-stacked with no key
- zone_name: "example.org."
zone_filename: "example.org.zone"
slaves:
- ip: 2001:db8:42:1337::1
tsig_key: "tsig-key.example.org"
- ip: 198.51.100.12
tsig_key: "tsig-key.example.org"
- ip: 203.0.113.8
nsd_secondary_zones:
# Slave zone with two masters, first one without key, second one with a key
- zone_name: "example.eu.org"
masters:
- ip: 192.0.2.42
- ip: 2001:db8:1234:5678::9
tsig_key: "key-eu.org"
Also in `host_vars/ns1.yml`:
nsd_local_server_config:
ip-address: ['2001:db8:ffff::42', '203.0.113.199']
The zone data for the two primary zones needs to be stored in `files/nsd/` at
the root of your ansible directory:
# ls files/nsd/
example.org.zone example.com.zone
# head -3 files/nsd/example.org.zone
$ORIGIN example.org
$TTL 3h
@ IN SOA ns1 root.example.org. (2017090101 1d 2h 4w 1h)
## Limitations
For a given zone, all machines using this role must be either all masters or all slaves.
This greatly simplifies configuration, and there is generally no need
to have masters and slaves for the same zone handled by Ansible, since
Ansible can just push the zone to all machines (so, they can all be masters).
Ansible can just push the zone data to all servers (so, they can all be masters).
There are cases where having multiple masters whose zone is pushed by Ansible
is not desirable:
would probably not be desirable:
- dynamic DNS records (which isn't supported by NSD anyway)
- DNSSEC (you could always generate DNSSEC signatures in ansible, but it's awkward)
Thus, these use-cases are not supported.
You can put key-value pairs in group_vars, under the key "nsd_common_config",
they will be used for the NSD configuration on all hosts.
A few common configuration entries are in the playbook itself, because they are
needed to properly create relevant directories.
Some machine-specific configuration is also possible, e.g. for the bind IP.
Put key-value pairs in host_vars, under the key "nsd_local_config".
If you want to pass multiple values for a key (e.g. ip-address), just use
a list as value, it will automatically be expanded.
The zones are configured in group_vars, see the example. It is possible
to optionally add a TSIG key to each slave/master, see again the example.
The zone files themselves for primary zones should be put in files/nsd.
The playbook is currently only tested with Debian wheezy.
When a master zone is updated, the slaves are notified. Obviously, the slaves
need to be configured to accept notification from at least one master and pull
zones accordingly.
Of course, you can workaround this limitation by simply calling this role multiple
times with different machines and different configuration.
## License