We now have real documentation!
This commit is contained in:
parent
3dfe3fef0d
commit
f607fff0f8
286
README.md
286
README.md
@ -1,38 +1,276 @@
|
|||||||
# Ansible role for NSD
|
# Ansible role for NSD
|
||||||
|
|
||||||
It is assumed that all machines host the exact same zones in the same way
|
This Ansible role installs and configure NSD, an authoritative DNS server.
|
||||||
(i.e. for each zone, they are either all masters, or all slaves).
|
|
||||||
|
## 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
|
This greatly simplifies configuration, and there is generally no need
|
||||||
to have masters and slaves for the same zone handled by Ansible, since
|
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
|
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)
|
- dynamic DNS records (which isn't supported by NSD anyway)
|
||||||
- DNSSEC (you could always generate DNSSEC signatures in ansible, but it's awkward)
|
- 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",
|
Of course, you can workaround this limitation by simply calling this role multiple
|
||||||
they will be used for the NSD configuration on all hosts.
|
times with different machines and different configuration.
|
||||||
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.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user