This role installs and configures BIND9 on Debian to set a Name Server.
Features:
- Support for configuring BIND9 according to a set of template:
- default templates can implement an authoritative nameserver for DNS zones and/or a DNS recursor with or without forwarders,
- a set named
strict_authoritative
for a secure and easy configuration of a set of authoritative servers, primaries and secundaries,
- Extensive DNSSEC support:
- automatic KSK and ZSK key creation
- automatic zone DNSSEC configuration
- support to send DNSKEY/DS formatted output over XMPP
- Support for hidden primary and authoritative secondary configuration
- Support for so called "static" zones, i.e. zones defined uploading their raw .db bind file
- Validity check of zone files with named-checkzone
- Basic support for so called "dynamic" zones, i.e. defined from variables yaml variables sets
Lest's start by a simple but complete configuration of two servers:
- set vars for your master server, for instance in
host_vars/master_name/vars/XX_bind.yml
, here with an example.com static zone and forwarder:
bind9_authoritative: yes
bind9_zones_static:
- { name: example.com , type=master }
bind9_forward: yes
bind9_forward_servers:
- 8.8.8.8
- 4.4.4.4
bind9_slaves:
- slave_ip_1
- slave_ip_2
- slave_ip_3
bind9_our_neighbors:
- slave_ip_1
- slave_ip_2
- slave_ip_3
- Place your BIND zone file in ansible directory (not in role directory):
files/bind/zones/db.example.com
. The role will check the validity of this file.
- set vars for your slave servers:
bind9_zones_static:
- { name: example.com, type: slave }
bind9_forward: yes
bind9_forward_servers:
- 8.8.8.8
- 4.4.4.4
bind9_masters:
- { name: master_name, addresses: [master_ip] }
bind9_recursor: our_network
- deploy role to your servers!
In previous example, zones' ressource records are defined by a classic BIND9 zone's file, which validity is checked, but that you have to maintain. These are the so called "static zones", raw defined by a db.<zone_name>
file.
So called "dynamic" zones' files are built form ansible variables. Their ressource records are defined through YAML ansible structure bind9_zones_dynamic
which is parsed by bind/zones/db.template.j2
template.
As there can be several zones, and zones' definitions can be long, zones' vars are worthly defined in a different vars' file, for instance host_vars/master_name/vars/YY_zones.yml
, and bind9_zones_dynamic
can be split in several variables, that can be defined in specific files. In YY_zones.yml
we may have:
bind9_zones_dynamic: >
{{ zones_my_domains
| union ( zone_my_reverse_inaddr_arpa )
| union ( zone_my_reverse_ip6_arpa ) }}
# bind9_zone_static: zone files copied from `files/bind/zones/`
bind9_zones_static:
- name: static_dom.org
type: master
- name: static_dom2.org
type: master
- name: static_dom3.org
type: slave
And in other vars' files:
zones_my_domains:
# This is the variables set for my domain
- name: dyn_domain.org
type: master
default_ttl: 600
serial: 2022050501
refresh: 1D
retry: 2H
expire: 1000H
# NS and other pre-formatted records values must be given as full qualified domain names, with or without final dot, but not relative to the zone
master: ns1.dyn_domain.org # Optional, if you don't define it, firs NS is taken
admin: postmaster.dyn_domain.org
ns_records:
- ns1.dyn_domain.org
- ns2.dyn_domain.org
# RR values are either relative to the zone, either with a final dot when outside.
rrs:
- {label: "@", type: MX, rdata: 10 mail}
- {label: webmail, type: CNAME, rdata: mail}
- {label: "@", type: A, rdata: 8.8.8.221}
- {label: "@", type: AAAA, rdata: 2001:db8:6a::95}
- {label: www, type: CNAME, rdata: webserver.dyn_domain.org.}
- {label: mail, type: A, rdata: 8.8.8.222}
- {label: mail, type: AAAA, rdata: 2001:db8:6a::22}
- {label: webserver, ttl: 86400, type: A, rdata: 8.8.8.223}
- {label: webserver, ttl: 86400, type: AAAA, rdata: 2001:db8:6a::23}
And similarly zone_my_reverse_inaddr_arpa
and zone_my_reverse_ip6_arpa
for IP reverse DNS resolution. Note that for generic NS records we adopted the terminology defined in RFC 1034, Section 3.6
Basically the role builds bind9 configuration, i.e. /etc/bind/named.conf.*
files, as well as zone definition files, which are placed in /etc/bind/zones/
directory.
Configuration is based on a set of templates, and the role can handle several ones. Presently two sets of templates are proposed:
- the default one, a general purpose set of templates that has evolved with the role,
- a "strict authoritative" NS templates' set, that:
- denies by default any query, recursion or transfer, and only allows queries from any and transfers from slaves for zones the server is authoritative on.
- automates, for each zone, the inclusion of secundary NS servers and also-notify IPs in the allow-transfer permissions.
Templates' set is defined by variable bind9_templates
. You should set it to the absolute path or the relative path to the templates/
directory of the role. For strict authoritative NS config, define in your vartiables:
bind9_templates: strict_authoritative/
Several variables of the role define options and values in the set of templates you use. Note that the same role's variable of the role may have slightly different meanings, or no meaning at all, depending on the choosen set of templates.
You can develop your own set of templates and set, for instance:
bind9_templates: "{{ playbook_dir }}/host_vars/<my_host>/templates/"
PRs with good BIND9 configs templates are welcome!
This templates' set is designed to configure strict Authoritative Name Servers, primaries or secondaries:
- queries are refused except for the zones we are authoritative for,
- transfers are selectively set by zone and no recursion at all,
- when we answer, we give th same answer to the whole internet (for public internet zones, baroque configurations that restrict answers or, worse, give different answers to different clients, such as with views, are bad ideas that break the internet, considering DNS is a core part of it),
- by default, zone transfer are allowed, zone by zone, to secundaries and also-notify elements
- customizations should allow to configure all kind of sets of primaries or secudaries, visible or hideden.
Therefore, when you set bind9_templates: strict_authoritative/
, in options
BIND configuration section, these templates always set:
recursion no;
allow-query { none; };
allow-transfer { none; };
allow-recursion { none; };
Default configuration values are set with bind9_<parameter>
role variables, that can be overwritten for each zone with specific values in the .<parameter>
field in the corresponding zone's element in bind9_zones_static
or bind9_zones_static
.
Depending on the parameter considered, templates implement the default value either in the options
section of BIND config files (notify
, also-notify
), either picking default values and set them in the zone's configuration section (allow-query
, allow-transfer
). With ACLs and setting parameter values per zone, the role can handle all sort of particular cases for some zones.
The YAML structure of ther variables allows to overcome and unify (at least for simplified configurations the role permits) BIND's management of two kind of lists: masters and acl. Templates take advantage of this characteristic to automatically configure secundary NS IPs and also-notify IPs in the zone's allow-transfer
configuration directive for zones we are master for. Zone parameters are defined to extend or to overwrite this list of allow-transfer.
bind9_masters
andbind9_slaves
should be enough for standard internet zones and if you have the same set of NS authoritative servers for all your zones. You don't have to care aboutallow-transfer
for slaves in the master server: the role does the job.- Use
bind9_also_notify
if you have some hidden NS servers. Don't worry neither aboutallow-transfer
to those hosts, the role also does the job. - If some of your zones have specific configuration:
bind9_masters_extra
can help you for different sets of masters for your secundary zones,bind9_acl
, along with specific values per zone set inbind9_zones_static
orbind9_zones_dynamic
, will help to set all kind of transfers, notifications and even to restric queries for eventual private zones.
- zone by zone, the templates also takes care of including slaves and also-notify hosts for allow-transfer.
Explicitely, you can use the following variables to configure your NS server and its zones:
-
bind9_masters
: default primary (or master) NS servers for zones we are secondary (or slave) for.bind9_masters: my_primariy: - IPv4_1 - IPv6_1 my_fault_back_primary: - IPv4_1 - IPv6_1
With these lists the template builds the primaries' or masters' list(s) to be used by default as
masters
for zones we are slave for, when masters are not specifically set for the zone. Note that masters' list can only contain other masters' lists names or individual IPs. IPv4 or IPv6, but not network IPs range, ending with a / and a mask length.Magic-mix of acls and masters' lists: Thanks to the similarity of YAML structure with
bind9_acl
variable hereafter, for each element ofbind9_masters
the templates build, moreover the primaries' list, an Access Control List (ACL) with the same name and content. Therefore, contrarily than when working directly on BIND9 configuration files, we can use masters' list names, not only in [the variables that define]masters
oralso-notify
statements of a zone, but also in [the variables that define] statements which work with ACLs, such asallow-transfer
orallow-query
. Taking advantage of this trick, the role can automatically include a similar content into an notify-also statement (which requires a masters' list) as well as in the allow-transfer ones (which require an ACL). See hereafter. -
bind9_masters_extra
is a similar structure that also sets primaries' lists, but which are not the role's default values for zones declared.Magic-mix of acls and masters' lists: Thanks to the similarity of these YAML structure with
bind9_acl
variable hereafter, for each element ofbind9_masters
andbind9_masters_extra
the templates build, moreover the primaries' list, an Access Control List (ACL) with the same name and content. Therefore, contrarily than when working directly on BIND9 configuration files, we can use masters' list names, not only in [the variables that define]masters
oralso-notify
clauses of a zone, but also in [the variables that define] clauses which work with ACLs, such asallow-transfer
orallow-query
. Taking advantage of this trick, the role can automatically include a similar content into a notify-also clause (which requires a masters' list) as well as in the allow-transfer ones (which require an ACL). See hereafter. -
bind9_acl
has a quite similar structure with keywords and list of IPs but, in BIND configuration, it builds global Access Control lists, to be used in appropriate parameters, particularly in theallow-xxx
per zone. Note thatbind9_acl
can contain not noly IPs (IPv4 and IPv6) but also network IPs ranges, ending with a / and a mask length, as well as a literal reference to recursively include another ACL. As ACLs are already defined for masters, so do not use for ACL a name you already used in a masters' list. -
bind9_slaves
defines the default secundary or slave NS servers for zones we are primary or master for. It's a list of IPs, or eventually ACLs defined with previous variable. For zones we are primary for, templates also include these secondaries IPs in those allowed to transfer the zone, except if the.slaves
or the.allow_transfer
parameter hereafter is defined for the zone. -
bind9_notify
can take the valuesmaster-only
,explicit
,yes
orno
. It defines the defaut behavior for notification, wich is set inoptions
section. Lettingbind9_notify
undefined doesn't set the directive and therefore leads to BIND's default behavior, i.e.notify: yes
. We don't want to overwrite BIND's default behavior, but for most purposes of these templates, we recommend to set notify tomaster-only
. -
bind9_also_notify
is a list that defines the globalalso-noitfy
. As such, it can contain IPs or masters' lists, that can be set with the variablesbind9_masters
andbind9_masters_extra
hereabove. Except if.also_notify
or.allow_transfer
is explicitely set for the zone, templates take advantage of the masters' lists and ACLs built forbind9_masters
andbind9_masters_extra
to include the content ofbind9_also_notify
in the zone'sallow-transfer
directive, what would not be possible with BIND's syntax and grammar alone. Names are interpreted as masters' lists inalso-noitfy
clauses and as ACLs inallow-transfer
ones, but the templates have defined both with the same name and content. Globally or per zone, also-notify option is useful when you have hidden NS servers. -
bind9_also_allow_transfer
is a variable that can contain a list of IPs, network ranges of IPs and ACL names defined withbind9_acl
, that will be added, by default for zones we manage, to theallow-transfer
inferred by the role, which already includes secundaries and also-notify elements, as documented hereabove. This option may be useful for some very strange configuration, where NS servers are not notified but should be allowed to transfer zones. -
bind9_allow_transfer
is a variable that can contain a list of IPs, network ranges of IPs and ACL names, defined withbind9_acl
. If defined, it will cancel the mechanism previously defined to include secundaries and also-notify in allow-transfer zone's clause. Except if.allow_transfer
is defined for the zone, the content ofbind9_allow_transfer
and only this will populate theallow-transfer
zone's clause.
Zone by zone, in bind9_zones_static
as well as in bind9_zones_dynamic
list's elements, the following zone configuration parameters can be defined:
.allow-query
: a list of IPs and/or acls to restrict the clients that can ask for the zone. Default value isany
. (breaks the internet if you publish an NS record: use with care, only for private zones).type
: that defines de BIND9 type of zone:master
,slave
,forward
,stub
.masters
: can be defined for the zones we are slave for. You can put there anything that BIND9 accepts but, to take advantage of this role to avoid data duplication, we recommend to declare all your NS hosts inbind9_masters
andbind9_masters_extra
, and reference them by name..slaves
: can be defined for zones we are master for. It has a similar structure thanbind9_slaves
, that it will overwrite for the zone. The hosts it contains will be allowed for transfer, except if the parameter.allow_transfer
hereafter is defined..notify
:explicit
,yes
orno
(master-only
has no really useful for a single zone). Sets notification behavior for the zone,.also_notify
: can be defined zone by zone we are master for, with a similar structure thanbind9_also_notify
, that it will overwrite for the zone. and the hosts it contains will be allowed for transfer, except if the parameter.allow_transfer
hereafter is defined..also_allow_transfer
: is a list similar to an ACL, that will overwritebind9_also_allow_transfer
if defined, wich will be added to theallow-transfer
statement content inferred by the role as described hereabove..allow_transfer
: is a list similar to an ACL, that will overwritebind9_allow_transfer
for the zone. Its content and only this will populate theallow-transfer
zone's clause.
Finally, note that this set of templates no longer uses several variables that use the default templets, such as bind9_recursor
or bind9_our_neighbors
, for instance. However, bind9_authoritative
, whilst not used in the templates is tested by the role as conditionnal of several tasks. Therefore, it must be set to true (as does de defaults' definition).
Default templates have evolved with the role and try to set all kind of BIND9 configuration, as authoritative, resolver or forwarder. However, as initially there was no per zone BIND configuration, they have a different logic.
See also defaults/main.yml
for a list of role's variables, including those which are used by default templates and not by strict_authoritative/
ones.
For the XMPP notification feature, python-xmpp
needs to be installed.
For developing and testing the role we use Github Actions, Molecule and Vagrant. On the local environment you can easily test the role with
Run local tests with:
molecule test
This Ansible role is licensed under the GNU GPLv3.
Copyright 2017-2020 systemli.org (https://www.systemli.org/)