From ca1c663625a3a2567885c822f37536fd8c1f25a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Thu, 5 May 2022 23:03:12 -0300 Subject: [PATCH 01/15] Rename negative_ttl into default_ttl --- README.md | 73 ++++++++++++++++++++++++----- templates/bind/zones/db.template.j2 | 5 +- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 6352e74..a1794de 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,14 @@ Features: * automatic zone DNSSEC configuration * support to send DNSKEY/DS formatted output over XMPP * Support for hidden primary and authoritative secondary configuration -* Basic support for dynamic creation of zone files from variables - -## Basic usage - master and slave server with static zones and forwarder - -* place your zone file in ansible directory (not in role directory): files/bind/zones/db.example.com -* set vars for your master server: - - -``` +* 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 + +## Basic server configuration +### Master server +* set vars for your master server, for instance in `host_vars/master_name/vars/XX_bind.yml`, here with an example.com static zones and forwarder: +```yaml bind9_authoritative: yes bind9_zones_static: - { name: example.com , type=master } @@ -38,10 +37,13 @@ bind9_our_neighbors: - slave_ip_2 - slave_ip_3 ``` -* set vars for your slave server: +* Place your BIND zone file in ansible directory (not in role directory): `files/bind/zones/db.example.com +### Slave servers -``` +* set vars for your slave servers: + +```yaml bind9_zones_static: - { name: example.com, type: slave } bind9_forward: yes @@ -52,7 +54,56 @@ bind9_masters: - { name: master_name, addresses: [master_ip] } bind9_recursor: our_network ``` +### Dynamic zones +So called "dynamic" zones' records are defined through YAML ansible variable `bind9_zones_dynamic` which is parsed by [`bind/zones/db.template.j2`](templates/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 splited in several variables, that can bie defined in specific files. In `YY_zones.yml` we may have: +```yaml +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: +```yaml +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 + primary: 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 we adopted for generic NS records the terminology defined in [RFC 1034, Section 3.6](https://datatracker.ietf.org/doc/html/rfc1034#section-3.6) * deploy role to your servers diff --git a/templates/bind/zones/db.template.j2 b/templates/bind/zones/db.template.j2 index 8b1b1f8..05082dc 100644 --- a/templates/bind/zones/db.template.j2 +++ b/templates/bind/zones/db.template.j2 @@ -21,8 +21,9 @@ #}{% set zone=item %} ;; {{ ansible_managed }} $ORIGIN . -$TTL {{ zone.negative_ttl|default('3600') }} ; 1 hour -{# We first deal in detail with SOA and NS, which is requiered, and root zone registers +{# Default TTL of zone records. `negative_ttl` is a deprecated name of this variable. #} +$TTL {{ zone.default_ttl|default(zone.negative_ttl|default('3600')) }} ; 1 hour. +{# We first deal in detail with SOA and NS, which are requiered, and root zone registers Empezamos detallando el SOA y NS, que son indispensables, y registros de raíz de zona #} {{ zone.name }} IN SOA {{ zone.primary|default(zone.ns_records.0) }}. {{ zone.admin|default(bind9_admin) }}. ( {{ zone.serial }} ; serial From 38b48c6ddc3a4decb4461b52417ba09abfcdbee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Sun, 8 May 2022 20:24:01 -0300 Subject: [PATCH 02/15] new set of templates `strict_authoritative/` --- defaults/main.yml | 17 ++- templates/bind/named.conf.local.j2 | 34 ++++-- templates/bind/named.conf.options.j2 | 19 ++- .../strict_authoritative/bind/default.j2 | 1 + .../bind/named.conf.local.j2 | 108 ++++++++++++++++++ .../bind/named.conf.options.j2 | 89 +++++++++++++++ .../strict_authoritative/bind/rndc.key.j2 | 1 + templates/strict_authoritative/bind/zones | 1 + templates/strict_authoritative/logrotate.d | 1 + 9 files changed, 259 insertions(+), 12 deletions(-) create mode 120000 templates/strict_authoritative/bind/default.j2 create mode 100644 templates/strict_authoritative/bind/named.conf.local.j2 create mode 100644 templates/strict_authoritative/bind/named.conf.options.j2 create mode 120000 templates/strict_authoritative/bind/rndc.key.j2 create mode 120000 templates/strict_authoritative/bind/zones create mode 120000 templates/strict_authoritative/logrotate.d diff --git a/defaults/main.yml b/defaults/main.yml index a052a75..0845f2c 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -35,6 +35,9 @@ bind9_notify_explicit: no # Default zone type bind9_zone_type: master +## //!\\ Several of the following variables have different meanings or (no meaning at all) depending on the templates' set you use +## See here after bind9_template variable. + # Permitted hosts/networks for recursion (when configured as recursor) bind9_our_networks: - localhost @@ -64,6 +67,9 @@ bind9_rndc_algorithm: hmac-md5 # Global secondaries for all zones (if configured as primary) # bind9_slaves: # - 1.2.3.4 +# +# Let's progressively rename this variable with bind preferred terminology: +bind9_secondaries: "{{ bind9_slaves }}" # Enable BIND's XML statistics-channels (for monitoring purposes) bind9_statistics_enabled: False @@ -113,7 +119,16 @@ bind9_packages: # Directory for bind9 files templates bind9_templates: "" -# The default value takes templates form the {{ role_path }}/templates/ directory of the role +# The role can handle different sets of templates for bind and zones configuration. +# It presently proposes two sets of templates: +# * the defaults one, "", wich is a general purpose configuration set, that has evolved with the role. +# It's files live in {{ role_path }}/templates/ directory +# * a second new set for a strict authoritative bind NS server: `strict_authoritative` It accepts DNS queries only for zones it is authoritative for. +# allow-transfer for secunday NS servers, notify-also for hidden slaves, and even allow-query and notify can be defined zone by zone. +# It's files live in {{ role_path }}/templates/strict_authoritative/ directory +# Note that several default variables `bind9_*` have different meanings than with default templates' set. +# bind9_templates nust be set as a relative or absolute directory, including it's trailing "/": +# bind9_templates: strict_authoritative/ # You can set your own templates, for example with: # bind9_templates: "{{ playbook_dir }}/host_vars//templates/" diff --git a/templates/bind/named.conf.local.j2 b/templates/bind/named.conf.local.j2 index 1bc87fb..4c7ddd2 100644 --- a/templates/bind/named.conf.local.j2 +++ b/templates/bind/named.conf.local.j2 @@ -38,30 +38,48 @@ zone "{{ zone.name }}" { type {{ zone_type }}; {% if zone_type == 'master' %} file "/etc/bind/zones/db.{{ zone.name }}"; -{% if bind9_notify_explicit|default() %} +{% if zone.allow_query %} + allow-query { +{% for allow_query_item in zone.allow_query %} + {{ allow_query_item }}; + }; +{% endif %} +{% if zone.allow_transfer %} + allow-transfer { +{% for allow_transfer_item in zone.allow_transfer %} + {{ allow_transfer_item }}; + }; +{% endif %} +{% if bind9_notify_explicit %} notify explicit; -{% elif zone.notify|default(true) %} - notify yes; +{% elif zone.notify | default(true) %} + notify {{ zone.notify | default(true) | ternary ('yes','no') }}; +{% endif %} +{% if zone.also_notify %} + also-notify { +{% for also_notify_item in zone.also_notify %} + {{ also_notify_item }}; + }; {% endif %} -{% if (bind9_dnssec|default() or zone.dnssec|default()) and zone.dnssec|default(bind9_dnssec_zones_default_enabled) %} +{% if (bind9_dnssec or zone.dnssec | default() ) and zone.dnssec | default( bind9_dnssec_zones_default_enabled ) %} auto-dnssec maintain; inline-signing yes; {% endif %} -{% if zone.update_policy_grant|default() %} +{% if zone.update_policy_grant | default() %} update-policy { grant {{ zone.name }}_ddns_update {{ zone.update_policy_grant }}; }; {% endif %} {% elif zone_type == 'slave' %} file "/var/lib/bind/db.{{ zone.name }}"; -{% if zone.masters|default() or bind9_masters|default() %} +{% if zone.masters | default() or bind9_masters | default() %} notify no; masters { -{% if zone.masters|default() %} +{% if zone.masters | default() %} {% for master in zone.masters %} {{ master }}; {% endfor %} -{% elif bind9_masters|default() %} +{% elif bind9_masters | default() %} {% for master in bind9_masters %} {{ master.name }}; {% endfor %} diff --git a/templates/bind/named.conf.options.j2 b/templates/bind/named.conf.options.j2 index e0d7446..abd800c 100644 --- a/templates/bind/named.conf.options.j2 +++ b/templates/bind/named.conf.options.j2 @@ -1,3 +1,6 @@ +// BIND 9 Configuration - generated by systemli.bind9 ansible role +// DO NOT edit, change your ansible config and re-run your ansible playbooks + options { directory "/var/cache/bind"; @@ -32,7 +35,7 @@ options { recursion {{ bind9_recursor|default()|ternary('yes', 'no') }}; allow-recursion { {{ bind9_recursor|default()|ternary('our_networks', 'none') }}; }; - allow-query { {% if bind9_hidden_master|default() %}our_neighbors{% elif bind9_authoritative|default() %}any{% else %}our_networks{% endif %}; }; + allow-query { {% if bind9_hidden_master|default() %}our_neighbors{% elif bind9_authoritative|default() %}none{% else %}our_networks{% endif %}; }; {% if bind9_authoritative|default() %} allow-transfer { our_neighbors; }; @@ -89,8 +92,18 @@ acl our_neighbors { {% endfor %} {% endif %} }; +{% if bind9_acl is defined %} + // Custom acls +{% for acl_item in bind9_acl %} +acl {{ acl_def.name }} { +{% for item_address in acl_item.addresses %} + {{ acl_address }}; +}; +{% endfor %} +{% endif %} {% if bind9_named_logging %} + logging { channel bind_log { file "{{ bind9_log_path }}/bind.log" versions {{ bind9_log_versions }} size {{ bind9_log_size }}; @@ -99,8 +112,8 @@ logging { print-severity yes; print-time yes; }; - {% for category in bind9_log_categories %} +{% for category in bind9_log_categories %} category {{ category.name }} { {{ category.destination }}; }; - {% endfor %} +{% endfor %} }; {% endif %} diff --git a/templates/strict_authoritative/bind/default.j2 b/templates/strict_authoritative/bind/default.j2 new file mode 120000 index 0000000..0bab1c2 --- /dev/null +++ b/templates/strict_authoritative/bind/default.j2 @@ -0,0 +1 @@ +../../bind/default.j2 \ No newline at end of file diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 new file mode 100644 index 0000000..0baae9d --- /dev/null +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -0,0 +1,108 @@ +// BIND 9 Configuration - named.conf.local - generated by systemli.bind9 ansible role +// DO NOT edit, change your ansible config and re-run your ansible playbooks +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include "/etc/bind/zones.rfc1918"; + +{% if bind9_masters|default() %} +{% for master in bind9_masters %} +masters {{ master.name }} { +{% for addr in master.addresses %} + {{ addr }}; +{% endfor %} +}; +{% endfor %} +{% endif %} +{% if bind9_masters_extra|default() %} +{% for master in bind9_masters_extra %} +masters {{ master.name }} { +{% for addr in master.addresses %} + {{ addr }}; +{% endfor %} +}; +{% endfor %} +{% endif %} + +{% if bind9_statistics_enabled %} +statistics-channels { + inet 127.0.0.1 port 8053 allow { 127.0.0.1; }; +}; +{% endif %} + +// The following zones are managed by this DNS Server // +{% for zone in (bind9_zones_static + bind9_zones_dynamic)|sort(attribute='name') %} +{% set zone_type = zone.type|default(bind9_zone_type|default('master')) %} +zone "{{ zone.name }}" { + type {{ zone_type }}; +{% if zone_type == 'master' %} + file "/etc/bind/zones/db.{{ zone.name }}"; + allow-query { +{% if zone.allow_query is defined and zone.allow_query | length() > 0 %} +{% for allow_query_item in zone.allow_query | list %} + {{ allow_query_item }}; +{% endfor %} + }; +{% else %} + any; + }; +{% endif %} +{% set zone_secondaries = zone.secondaries | default( bind9_secondaries | default( [] ) ) %} +{% set zone_allow_transfer = zone.allow_transfer | default( zone_secondaries + zone.also_allow_transfer | default(bind9_also_allow_transfer | default( [] ) ) ) %} +{% if zone_allow_transfer %} + + // allow transfer from secundaries and extra also_allow_transfer hosts + allow-transfer { +{% for allow_transfer_item in zone_allow_transfer %} + {{ allow_transfer_item }}; +{% endfor %} + }; +{% endif %} +{% if bind9_notify_explicit %} + notify explicit; +{% else %} + notify {{ zone.notify | default(true) | ternary ('yes','no') }}; +{% endif %} +{% set zone_also_notify = zone.also_notify | default( bind9_also_notify | default() ) %} +{% if zone_also_notify %} + also-notify { +{% for also_notify_item in zone_also_notify %} + {{ also_notify_item }}; +{% endfor %} + }; +{% endif %} +{% if (bind9_dnssec or zone.dnssec | default() ) and zone.dnssec | default( bind9_dnssec_zones_default_enabled ) %} + auto-dnssec maintain; + inline-signing yes; +{% endif %} +{% if zone.update_policy_grant | default() %} + update-policy { + grant {{ zone.name }}_ddns_update {{ zone.update_policy_grant }}; + }; +{% endif %} +{% elif zone_type == 'slave' %} + file "/var/lib/bind/db.{{ zone.name }}"; +{% if zone.masters | default() or bind9_masters | default() %} + notify {{ zone.notify | default ('no') | ternary ('yes','no') }}; + masters { +{% if zone.masters is defined %} +{% for master in zone.masters %} + {{ master }}; +{% endfor %} +{% elif bind9_masters is defined %} +{% for master in bind9_masters %} + {{ master.name }}; +{% endfor %} +{% endif %} +{% endif %} + }; +{% elif zone_type == 'forward' %} + forwarders { +{% for fwd in zone.forwarders %} + {{ fwd }}; +{% endfor %} + }; +{% endif %} +}; +{% endfor %} diff --git a/templates/strict_authoritative/bind/named.conf.options.j2 b/templates/strict_authoritative/bind/named.conf.options.j2 new file mode 100644 index 0000000..f439d4d --- /dev/null +++ b/templates/strict_authoritative/bind/named.conf.options.j2 @@ -0,0 +1,89 @@ +// BIND 9 Configuration - named.conf.options - generated by systemli.bind9 ansible role +// DO NOT edit, change your ansible config and re-run your ansible playbooks + +options { + directory "/var/cache/bind"; + + // If there is a firewall between you and nameservers you want + // to talk to, you may need to fix the firewall to allow multiple + // ports to talk. See http://www.kb.cert.org/vuls/id/800113 + + // If your ISP provided one or more IP addresses for stable + // nameservers, you probably want to use them as forwarders. + // Uncomment the following block, and insert the addresses replacing + // the all-0's placeholder. + +{% if bind9_forward|default() %} + forwarders { +{% for forwarder in bind9_forward_servers %} + {{ forwarder }}; +{% endfor %} + }; +{% endif %} + + //======================================================================== + // If BIND logs error messages about the root key being expired, + // you will need to update your keys. See https://www.isc.org/bind-keys + //======================================================================== + dnssec-validation {{ bind9_dnssec_validation }}; +{% if ansible_distribution_major_version|int >= 11 %} + qname-minimization {{ bind9_qname_minimization }}; +{% endif %} + auth-nxdomain no; # conform to RFC1035 + listen-on-v6 { any; }; + + // Yes, we are strict authoritative: only allow per zone. + recursion no; + allow-query { none; }; + allow-recursion { none; }; +{% if bind9_notify_explicit|default() %} + + // Notify only nameservers from also-notify, not from NS RRs in zones + notify explicit; +{% endif %} +{% if bind9_dnssec|default() %} + + // Look here for DNSSEC keys + key-directory "/etc/bind/keys"; +{% endif %} +}; +{% if bind9_zones_static|selectattr('update_keyfile','defined')|list|default() %} +{% for zone in bind9_zones_static|selectattr('update_keyfile','defined')|list|default([]) %} +{% if zone_type|default(bind9_zone_type|default('master')) == 'master' %} +{% if loop.first %} + +// The following keys are used for dynamic DNS updates +{% endif %} +key "{{ zone.name }}_ddns_update" { + algorithm {{ zone.update_key_algorithm|default('hmac-sha512') }}; + secret "{{ zone.update_key_secret|default() }}"; +}; +{% endif %} +{% endfor %} +{% endif %} +{% if bind9_acl is defined %} + + // Custom acls +{% for acl_item in bind9_acl %} +acl {{ acl_item.name }} { +{% for acl_address in acl_item.addresses %} + {{ acl_address }}; +}; +{% endfor %} +{% endfor %} +{% endif %} +{% if bind9_named_logging %} + +logging { + channel bind_log { + file "{{ bind9_log_path }}/bind.log" versions {{ bind9_log_versions }} size {{ bind9_log_size }}; + severity {{ bind9_log_severity }}; + print-category yes; + print-severity yes; + print-time yes; + }; +{% for category in bind9_log_categories %} + category {{ category.name }} { {{ category.destination }}; }; +{% endfor %} +}; +{% endif %} diff --git a/templates/strict_authoritative/bind/rndc.key.j2 b/templates/strict_authoritative/bind/rndc.key.j2 new file mode 120000 index 0000000..a23d177 --- /dev/null +++ b/templates/strict_authoritative/bind/rndc.key.j2 @@ -0,0 +1 @@ +../../bind/rndc.key.j2 \ No newline at end of file diff --git a/templates/strict_authoritative/bind/zones b/templates/strict_authoritative/bind/zones new file mode 120000 index 0000000..5b64f95 --- /dev/null +++ b/templates/strict_authoritative/bind/zones @@ -0,0 +1 @@ +../../bind/zones \ No newline at end of file diff --git a/templates/strict_authoritative/logrotate.d b/templates/strict_authoritative/logrotate.d new file mode 120000 index 0000000..0d2c3aa --- /dev/null +++ b/templates/strict_authoritative/logrotate.d @@ -0,0 +1 @@ +../logrotate.d \ No newline at end of file From 64c2c1cd9d4d82cd11c4c167ad12646945a7e686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Tue, 10 May 2022 20:29:33 -0300 Subject: [PATCH 03/15] New set of templates, debug 1 --- defaults/main.yml | 11 +++++++--- .../bind/named.conf.local.j2 | 21 ++++++++++++++----- .../bind/named.conf.options.j2 | 12 +---------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 0845f2c..e94433c 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -57,19 +57,24 @@ bind9_rndc_algorithm: hmac-md5 # - name: ns-primary # addresses: # - 1.2.3.4 +# Para BIND 9.17.3: https://downloads.isc.org/isc/bind9/9.17.3/doc/arm/html/notes.html#feature-changes +# Let's progressively rename this variable with bind's preferred terminology: +# bind9_primaries: "{{ bind9_masters }}" # Primaries for particular zones (if configured as secondary) # bind9_masters_extra: -# - name: ns-primary +# - name: "ns-primary" # addresses: # - 1.2.3.4 +# Let's progressively rename this variable with bind's preferred terminology: +# bind9_primaries_extra: "{{ bind9_masters_extra }}" # Global secondaries for all zones (if configured as primary) # bind9_slaves: # - 1.2.3.4 # -# Let's progressively rename this variable with bind preferred terminology: -bind9_secondaries: "{{ bind9_slaves }}" +# Let's progressively rename this variable with bind's preferred terminology: +# bind9_secondaries: "{{ bind9_slaves }}" # Enable BIND's XML statistics-channels (for monitoring purposes) bind9_statistics_enabled: False diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 index 0baae9d..719a7ff 100644 --- a/templates/strict_authoritative/bind/named.conf.local.j2 +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -6,9 +6,15 @@ // organization //include "/etc/bind/zones.rfc1918"; +{% if bind9_statistics_enabled %} + +statistics-channels { + inet 127.0.0.1 port 8053 allow { 127.0.0.1; }; +}; +{% endif %} {% if bind9_masters|default() %} {% for master in bind9_masters %} -masters {{ master.name }} { +masters "{{ master.name }}" { {% for addr in master.addresses %} {{ addr }}; {% endfor %} @@ -17,18 +23,23 @@ masters {{ master.name }} { {% endif %} {% if bind9_masters_extra|default() %} {% for master in bind9_masters_extra %} -masters {{ master.name }} { +masters "{{ master.name }}" { {% for addr in master.addresses %} {{ addr }}; {% endfor %} }; {% endfor %} {% endif %} +{% if bind9_acl is defined %} -{% if bind9_statistics_enabled %} -statistics-channels { - inet 127.0.0.1 port 8053 allow { 127.0.0.1; }; + // Custom acls +{% for acl_item in bind9_acl %} +acl "{{ acl_item.name }}" { +{% for acl_address in acl_item.addresses %} + {{ acl_address }}; +{% endfor %} }; +{% endfor %} {% endif %} // The following zones are managed by this DNS Server // diff --git a/templates/strict_authoritative/bind/named.conf.options.j2 b/templates/strict_authoritative/bind/named.conf.options.j2 index f439d4d..9472a17 100644 --- a/templates/strict_authoritative/bind/named.conf.options.j2 +++ b/templates/strict_authoritative/bind/named.conf.options.j2 @@ -35,6 +35,7 @@ options { // Yes, we are strict authoritative: only allow per zone. recursion no; allow-query { none; }; + allow-transfer { none; }; allow-recursion { none; }; {% if bind9_notify_explicit|default() %} @@ -61,17 +62,6 @@ key "{{ zone.name }}_ddns_update" { {% endif %} {% endfor %} {% endif %} -{% if bind9_acl is defined %} - - // Custom acls -{% for acl_item in bind9_acl %} -acl {{ acl_item.name }} { -{% for acl_address in acl_item.addresses %} - {{ acl_address }}; -}; -{% endfor %} -{% endfor %} -{% endif %} {% if bind9_named_logging %} logging { From 14d9e17ea143da7d16581994c8c9947f0432c415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Wed, 11 May 2022 16:34:42 -0300 Subject: [PATCH 04/15] New set of templates, debug 2 on default templates --- templates/bind/named.conf.local.j2 | 38 ++++++++++++------- templates/bind/named.conf.options.j2 | 14 +------ .../bind/named.conf.local.j2 | 4 +- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/templates/bind/named.conf.local.j2 b/templates/bind/named.conf.local.j2 index 4c7ddd2..1e7fb55 100644 --- a/templates/bind/named.conf.local.j2 +++ b/templates/bind/named.conf.local.j2 @@ -5,10 +5,16 @@ // Consider adding the 1918 zones here, if they are not used in your // organization //include "/etc/bind/zones.rfc1918"; +{% if bind9_statistics_enabled %} +statistics-channels { + inet 127.0.0.1 port 8053 allow { 127.0.0.1; }; +}; +{% endif %} {% if bind9_masters|default() %} +// masters for zones and alñlow-notify {% for master in bind9_masters %} -masters {{ master.name }} { +masters "{{ master.name }}" { {% for addr in master.addresses %} {{ addr }}; {% endfor %} @@ -17,18 +23,23 @@ masters {{ master.name }} { {% endif %} {% if bind9_masters_extra|default() %} {% for master in bind9_masters_extra %} -masters {{ master.name }} { +masters "{{ master.name }}" { {% for addr in master.addresses %} {{ addr }}; {% endfor %} }; {% endfor %} {% endif %} +{% if bind9_acl is defined %} -{% if bind9_statistics_enabled %} -statistics-channels { - inet 127.0.0.1 port 8053 allow { 127.0.0.1; }; + // Custom acls +{% for acl_item in bind9_acl %} +acl "{{ acl_item.name }}" { +{% for item_address in acl_item.addresses %} + {{ item_address }}; +{% endfor %} }; +{% endfor %} {% endif %} // The following zones are managed by this DNS Server // @@ -38,16 +49,18 @@ zone "{{ zone.name }}" { type {{ zone_type }}; {% if zone_type == 'master' %} file "/etc/bind/zones/db.{{ zone.name }}"; -{% if zone.allow_query %} +{% if zone.allow_query is defined %} allow-query { {% for allow_query_item in zone.allow_query %} {{ allow_query_item }}; +{% endfor %} }; {% endif %} -{% if zone.allow_transfer %} +{% if zone.allow_transfer is defined %} allow-transfer { {% for allow_transfer_item in zone.allow_transfer %} {{ allow_transfer_item }}; +{% endfor %} }; {% endif %} {% if bind9_notify_explicit %} @@ -55,10 +68,11 @@ zone "{{ zone.name }}" { {% elif zone.notify | default(true) %} notify {{ zone.notify | default(true) | ternary ('yes','no') }}; {% endif %} -{% if zone.also_notify %} +{% if zone.also_notify is defined %} also-notify { {% for also_notify_item in zone.also_notify %} {{ also_notify_item }}; +{% endfor %} }; {% endif %} {% if (bind9_dnssec or zone.dnssec | default() ) and zone.dnssec | default( bind9_dnssec_zones_default_enabled ) %} @@ -86,14 +100,12 @@ zone "{{ zone.name }}" { {% endif %} }; {% endif %} -{% else %} -{% if zone_type == 'forward' %} +{% elif zone_type == 'forward' %} forwarders { -{% for fwd in zone.forwarders %} +{% for fwd in zone.forwarders %} {{ fwd }}; -{% endfor %} +{% endfor %} }; -{% endif %} {% endif %} }; {% endfor %} diff --git a/templates/bind/named.conf.options.j2 b/templates/bind/named.conf.options.j2 index abd800c..1f2df03 100644 --- a/templates/bind/named.conf.options.j2 +++ b/templates/bind/named.conf.options.j2 @@ -15,9 +15,9 @@ options { {% if bind9_forward|default() %} forwarders { - {% for forwarder in bind9_forward_servers %} +{% for forwarder in bind9_forward_servers %} {{ forwarder }}; - {% endfor %} +{% endfor %} }; {% endif %} @@ -92,16 +92,6 @@ acl our_neighbors { {% endfor %} {% endif %} }; -{% if bind9_acl is defined %} - - // Custom acls -{% for acl_item in bind9_acl %} -acl {{ acl_def.name }} { -{% for item_address in acl_item.addresses %} - {{ acl_address }}; -}; -{% endfor %} -{% endif %} {% if bind9_named_logging %} logging { diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 index 719a7ff..cf5388d 100644 --- a/templates/strict_authoritative/bind/named.conf.local.j2 +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -60,7 +60,7 @@ zone "{{ zone.name }}" { }; {% endif %} {% set zone_secondaries = zone.secondaries | default( bind9_secondaries | default( [] ) ) %} -{% set zone_allow_transfer = zone.allow_transfer | default( zone_secondaries + zone.also_allow_transfer | default(bind9_also_allow_transfer | default( [] ) ) ) %} +{% set zone_allow_transfer = zone.allow_transfer | default( zone_secondaries + zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) ) %} {% if zone_allow_transfer %} // allow transfer from secundaries and extra also_allow_transfer hosts @@ -116,4 +116,4 @@ zone "{{ zone.name }}" { }; {% endif %} }; -{% endfor %} +{% endfor %} \ No newline at end of file From 7b61f8841c28eef7149f81fa413fb363174245e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Wed, 11 May 2022 23:33:44 -0300 Subject: [PATCH 05/15] Documentation new set of templates, ready for PR --- README.md | 43 +++++++++++++++++++++++++++++++++++-------- defaults/main.yml | 12 ++++++++---- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a1794de..30eaf57 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,11 @@ Features: * Basic support for so called "dynamic" zones, i.e. defined from variables yaml variables sets ## Basic server configuration + +Lest's start by a simple but complete configuration: + ### Master server + * set vars for your master server, for instance in `host_vars/master_name/vars/XX_bind.yml`, here with an example.com static zones and forwarder: ```yaml bind9_authoritative: yes @@ -37,7 +41,7 @@ bind9_our_neighbors: - slave_ip_2 - slave_ip_3 ``` -* Place your BIND zone file in ansible directory (not in role directory): `files/bind/zones/db.example.com +* 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. ### Slave servers @@ -54,8 +58,13 @@ bind9_masters: - { name: master_name, addresses: [master_ip] } bind9_recursor: our_network ``` -### Dynamic zones -So called "dynamic" zones' records are defined through YAML ansible variable `bind9_zones_dynamic` which is parsed by [`bind/zones/db.template.j2`](templates/bind/zones/db.template.j2) template. +* deploy role to your servers! + +## Static zones and Dynamic zones + +In previous example, zones' ressource records are defined by a classic BIND9 zone file, which validity is checked, but that you have to maintain. These are the so called "static zones", raw defined by a `db.` file. + +So called "dynamic" zones' files are built form ansible variables. Theire ressource records are defined through YAML ansible structure `bind9_zones_dynamic` which is parsed by [`bind/zones/db.template.j2`](templates/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 splited in several variables, that can bie defined in specific files. In `YY_zones.yml` we may have: ```yaml bind9_zones_dynamic: > @@ -105,16 +114,34 @@ zones_my_domains: And similarly `zone_my_reverse_inaddr_arpa` and `zone_my_reverse_ip6_arpa` for IP reverse DNS resolution. Note that we adopted for generic NS records the terminology defined in [RFC 1034, Section 3.6](https://datatracker.ietf.org/doc/html/rfc1034#section-3.6) -* deploy role to your servers +## Configurable templates' set -## Dependencies +Basically the role builds bind9 configuration, i.e. `/etc/bind/named.conf,*` files, as well aa zone definition files, whicha are placed in `/etc/bind/zones/` directory. -For the XMPP notification feature, `python-xmpp` needs to be installed. +Configuration is based on a set of themplates, and the role can handle several set of templates. 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. + +Templates' set is defined by variable `bind9_templates`. For [strict authoritative NS config](templates/strict_authoritative/), you should set: +```yaml +bind9_templates: strict_authoritative/ +``` +Note that the same variable of the role may have 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: +```yaml +bind9_templates: "{{ playbook_dir }}/host_vars//templates/" +``` +PRs with good bind9 configs templates are welcome! -## Role varibles +## Role and templates varibles -See `defaults/main.yml` for a list of role variables. +See `defaults/main.yml` for a list of role variables and some doc. + +## Dependencies + +For the XMPP notification feature, `python-xmpp` needs to be installed. Testing & Development --------------------- diff --git a/defaults/main.yml b/defaults/main.yml index e94433c..db62cec 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -8,9 +8,11 @@ bind9_group: bind bind9_ipv6: yes # Run bind as a DNS recursor? +# variable used only by default templates, not strict_authoritative bind9_recursor: no # Run bind as authoritative nameserver? +# variable used only by default templates, not strict_authoritative bind9_authoritative: no # run bind with forwarding? @@ -39,11 +41,13 @@ bind9_zone_type: master ## See here after bind9_template variable. # Permitted hosts/networks for recursion (when configured as recursor) +# variable used only by default templates, not strict_authoritative bind9_our_networks: - localhost - localnets # Permitted hosts/networks for zone transfers +# variable used only by default templates, not strict_authoritative bind9_our_neighbors: - localhost - localnets @@ -52,16 +56,16 @@ bind9_our_neighbors: bind9_rndc_algorithm: hmac-md5 # bind9_rndc_key: -# Global primaries for all zones (if configured as secondary) +# Global primaries for all zones (if configured as secondary), default masters if not defined in the zone # bind9_masters: # - name: ns-primary # addresses: # - 1.2.3.4 -# Para BIND 9.17.3: https://downloads.isc.org/isc/bind9/9.17.3/doc/arm/html/notes.html#feature-changes +# For BIND 9.17.3 (not yet in debian): https://downloads.isc.org/isc/bind9/9.17.3/doc/arm/html/notes.html#feature-changes # Let's progressively rename this variable with bind's preferred terminology: # bind9_primaries: "{{ bind9_masters }}" -# Primaries for particular zones (if configured as secondary) +# Primaries for particular zones (if configured as secondary), that can also be used in also-notify directives # bind9_masters_extra: # - name: "ns-primary" # addresses: @@ -69,7 +73,7 @@ bind9_rndc_algorithm: hmac-md5 # Let's progressively rename this variable with bind's preferred terminology: # bind9_primaries_extra: "{{ bind9_masters_extra }}" -# Global secondaries for all zones (if configured as primary) +# Global secondaries for all zones (if configured as primary), default slaves if not specifically defined for the zone # bind9_slaves: # - 1.2.3.4 # From 5f9d1c81887dfc60d2f02d32f56b0cf56eca81d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Mon, 30 May 2022 18:16:32 -0300 Subject: [PATCH 06/15] WIP: addressing @andrespias review 2/6/22 19:03 --- README.md | 67 ++++++++++++++-- defaults/main.yml | 28 +++++++ templates/bind/named.conf.local.j2 | 2 +- templates/bind/named.conf.options.j2 | 2 +- .../bind/named.conf.local.j2 | 79 +++++++++++++------ .../bind/named.conf.options.j2 | 14 +++- 6 files changed, 158 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 30eaf57..e82c175 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ zones_my_domains: 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 - primary: ns1.dyn_domain.org # Optional, if you don't define it, firs NS is taken + 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 @@ -119,15 +119,15 @@ And similarly `zone_my_reverse_inaddr_arpa` and `zone_my_reverse_ip6_arpa` for I Basically the role builds bind9 configuration, i.e. `/etc/bind/named.conf,*` files, as well aa zone definition files, whicha are placed in `/etc/bind/zones/` directory. -Configuration is based on a set of themplates, and the role can handle several set of templates. Presently two sets of templates are proposed: +Configuration is based on a set of templates, and the role can handle several set of templates. 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. -Templates' set is defined by variable `bind9_templates`. For [strict authoritative NS config](templates/strict_authoritative/), you should set: +Templates' set is defined by variable `bind9_templates`. You should set it to the absolute path ot the relative one to the `templates/` directory of the role. For [strict authoritative NS config](templates/strict_authoritative/), define in your vartiables: ```yaml bind9_templates: strict_authoritative/ ``` -Note that the same variable of the role may have different meanings, or no meaning at all, depending on the choosen set of templates. +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: ```yaml @@ -135,7 +135,64 @@ bind9_templates: "{{ playbook_dir }}/host_vars//templates/" ``` PRs with good bind9 configs templates are welcome! -## Role and templates varibles +### Role templates' variables + +#### `strict_authoritative` templates' set + +This template is designed to configure strict [Authoritative Name Servers](https://bind9.readthedocs.io/en/latest/chapter3.html#config-auth-samples), 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). +* customization proposed does it best to guess hosts that must be allowed zone transfer (secundaries and also-notify elements) and tries to implement all kind of sets of primaries or secudaries, visible or hideden. + +Therefore, when you set `bind9_templates: strict_authoritative/`, in `options` BIND configuration section, this templates always set: +``` +recursion no; +allow-query { none; }; +allow-transfer { none; }; +allow-recursion { none; }; +``` + +Default configuration values are set with `bind9_` role variables, that can be overwritten for each zone with specific values in the `.` field in the corresponding element of `bind9_zones_static` or `bind9_zones_static`. + +Depending on thee parameter considered, the 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 specific values per zone, the role can handle all sort of particular cases for some zones. + +The role does it best to also include secundaries NS IPs and also-notify IPs either default one or specific values overwritten for the zone in the zone's `allow-transfer` configuration directive. + +`bind9_masters` and `bind9_slaves` should be enough for standard internet zones and if you have the same set of NS authoritative servers for all your zones. Use `bind9_also_notify` if you have some hidden NS servers, but only put there a list of IPs if you want to take advantage of different benefits of the role setting appropiate values wherever needed. If you have some specific configuration of some zones, `bind9_masters_extra` can help you for different sets of masters for slave secundary zones. `bind9_acl` and specific values for zones listed in `bind9_zones_static` and `bind9_zones_dynamic` will help you to set all kind of transfers, notifications and even to restric queries for eventual private zones. + +Explicitely, ou can use the following variables to configure your NS server and its zones: +* `bind9_masters`: default master NS servers for zones we are secondary for. +```yaml +bind9_masters: + my_primariy: + - IPv4_1 + - IPv6_1 + my_fault_back_primary: + - IPv4_1 + - IPv6_1 +``` +With these lists the template builds the [primaries' lists](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) to be used by default as masters for slave zones, when these are not specifically set for the zone. + +`bind9_masters_extra` is a similar structure that also sets primaries' lists, but are not default values for zones. `bind9_masters` and `bind9_masters_extra` can be used anywhere such lists are valid for bind, i.e. to set masters and also-notify zone's lists. + +* `bind9_acl` has a similar structure with kewords and list of IPs but, in BIND configuration, it builds global [Access Control lists](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists), to be used in other appropriate parameters, particularly in the `allow-xxx` zone by zone. + +* `bind9_slaves` defines the default slave NS servers for zones we are master for. It's a list of IPs, or eventually ACLs defined with previous variable, and it's used to set the hosts that are allowed to transfer the zone. + +The YAML structure of ther variables allows to overcome and unify BIND's management of two kind of lists: masters and acl. The templates take advantage of this characteristic for default configuration + +* `bind9_notify` can take the values `explicit`, `yes`, `no`, or any other form of boolean values. It defines the defaut behavior for notification, wich is set in [`options` section](templates/strict_authoritative/bind/named.conf.options.j2#L41). `bind9_notify_explicit` is a legacy boolean variable, false by default, which sets `bind9_notify`'s value to `explicit` when `bind9_notify` is not defined. Letting `bind9_notify` undefined leads to BIND's default behavior, i.e. `notify: yes`. + +* `bind9_also_notify` is a list that defines the global `also-noitfy`. As such, it can contain IPs or masters list, that you can set with the variables `bind9_masters` and `bind9_masters_extra` hereabove. However, the role does it best to also include these IPs in the `allow-transfer` directive of the zone, which doesn't handle masters lists, but ACLs. If you use masters list in this variable, you MUST also overwrite the default definition of `bind9_also_allow_transfer` hereafter. + +* `bind9_also_allow_transfer` is a variable that can contain a list of IPs and ACL names that you can define with + +Zone by zone, in `bind9_zones_static` as well as in `bind9_zones_dynamic` list elements, you can define the following zone configuration parameters: + +* `.allow-query`: a list of IPs and/or acls to restrict the clients that can ask for the zone. Default value is `any`. (breaks the internet: use with care, only for private zones) +* `.notify`: `explicit`, `yes`, `no`, or any other form of boolean values. Sets notification behavior for the zone, +* `.slaves`: can be defined for zones we are master for. It will overwrite `bind9_slaves` for the zone, and the hosts it contains will be allowed for transfer, except if the parameter `.allow_transfer` hereafter is defined. + +https://bind9.readthedocs.io/en/latest/reference.html?highlight=also-notify#zone-options See `defaults/main.yml` for a list of role variables and some doc. diff --git a/defaults/main.yml b/defaults/main.yml index db62cec..b8d1707 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -34,6 +34,9 @@ bind9_hidden_master: no # Necessary to keep traffic between nameservers in private network. bind9_notify_explicit: no +# bind9_notify: '{{ "explicit" if bind9_notify_explicit else undef }}' +# undef doesn't work here. f**k legacy bind9_notify_explicit variable? + # Default zone type bind9_zone_type: master @@ -80,6 +83,31 @@ bind9_rndc_algorithm: hmac-md5 # Let's progressively rename this variable with bind's preferred terminology: # bind9_secondaries: "{{ bind9_slaves }}" +# bind9_acl: +# undefined by default, this variable allows to define a set of several access control lists (ACL) +# with the same format as `bind9_masters`, and use it in slaves. allow-query or allow-transfer definitions + +# bind9_also_notify: +# undefined by default, a list of IPs or masters lists to be defined as global `notify-also` list in configuration. + +# bind9_also_allow_transfer: +# bind9_also_allow_transfer: '{{ bind9_also_notify if bind9_also_notify is defined else undef }}' +# defaults to bind9_also_notify, but this definitio must be overwritten if this vairable contains masters names. +# As far as bind9_also_notify is just a list of IPs, default values of the role take advantage of the similar strucuture +# in YAML for lasters lists and ACLs, and the can by default allow transfer, zone by zone, to slaves and also notify IPS + +# bind9_also_allow_transfer +#bind9_also_allow_transfer: '{{ bind9_also_notify if bind9_also_notify is defined else undef }}' +# for primary zones, except if `allow_transfer` is explicitly defined for the zone, by default an `allow-transfer` list +# will be set, iincluding slave NS of the host and either the list also_allow_transfer defined for the zone, either this +# default list. +# If `bind9_also_notify` is defined by default `bind9_also_allow_transfer` has the same values. +# But be carefull: in BIND9 configuration, `also-notify` may include `masters` lists but not `acl` ones, while +# `allow-transfer` may include `acl` lists but not `masters` ones. In YAML role's variables structures are identical, but +# if they appear in BIND configuration list inclusions it will fail. +# Practically: if you use `masters` lists (defined with `bind9_masters`or `bind9_masters_extra` variables of this role), +# yo must re-define separately `bind9_also_allow_transfer`, probably defining an ACL with same values than master lists. + # Enable BIND's XML statistics-channels (for monitoring purposes) bind9_statistics_enabled: False diff --git a/templates/bind/named.conf.local.j2 b/templates/bind/named.conf.local.j2 index 1e7fb55..d5ecb61 100644 --- a/templates/bind/named.conf.local.j2 +++ b/templates/bind/named.conf.local.j2 @@ -12,7 +12,7 @@ statistics-channels { {% endif %} {% if bind9_masters|default() %} -// masters for zones and alñlow-notify +// masters for zones and allow-notify {% for master in bind9_masters %} masters "{{ master.name }}" { {% for addr in master.addresses %} diff --git a/templates/bind/named.conf.options.j2 b/templates/bind/named.conf.options.j2 index 1f2df03..a0a33b3 100644 --- a/templates/bind/named.conf.options.j2 +++ b/templates/bind/named.conf.options.j2 @@ -35,7 +35,7 @@ options { recursion {{ bind9_recursor|default()|ternary('yes', 'no') }}; allow-recursion { {{ bind9_recursor|default()|ternary('our_networks', 'none') }}; }; - allow-query { {% if bind9_hidden_master|default() %}our_neighbors{% elif bind9_authoritative|default() %}none{% else %}our_networks{% endif %}; }; + allow-query { {% if bind9_hidden_master|default() %}our_neighbors{% elif bind9_authoritative|default() %}any{% else %}our_networks{% endif %}; }; {% if bind9_authoritative|default() %} allow-transfer { our_neighbors; }; diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 index cf5388d..5f7e990 100644 --- a/templates/strict_authoritative/bind/named.conf.local.j2 +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -12,22 +12,22 @@ statistics-channels { inet 127.0.0.1 port 8053 allow { 127.0.0.1; }; }; {% endif %} -{% if bind9_masters|default() %} -{% for master in bind9_masters %} +{% if bind9_masters is defined or bind9_masters_extra is defined %} + +// masters clause lists for masters secondary zones and also-notify statements +// and ACLs with same name and content, to be used in allow-transfer statements +{% for master in bind9_masters | default ([]) + bind9_masters_extra | default ([]) %} masters "{{ master.name }}" { {% for addr in master.addresses %} {{ addr }}; {% endfor %} }; -{% endfor %} -{% endif %} -{% if bind9_masters_extra|default() %} -{% for master in bind9_masters_extra %} -masters "{{ master.name }}" { +acl "{{ master.name }}" { {% for addr in master.addresses %} {{ addr }}; {% endfor %} }; + {% endfor %} {% endif %} {% if bind9_acl is defined %} @@ -43,8 +43,9 @@ acl "{{ acl_item.name }}" { {% endif %} // The following zones are managed by this DNS Server // -{% for zone in (bind9_zones_static + bind9_zones_dynamic)|sort(attribute='name') %} -{% set zone_type = zone.type|default(bind9_zone_type|default('master')) %} +{% for zone in ( bind9_zones_static + bind9_zones_dynamic ) | sort( attribute='name' ) %} +{% set zone_type = zone.type | default( bind9_zone_type | default( 'master' ) ) %} +{# ############################### Zone is master ####################################### #} zone "{{ zone.name }}" { type {{ zone_type }}; {% if zone_type == 'master' %} @@ -59,30 +60,33 @@ zone "{{ zone.name }}" { any; }; {% endif %} -{% set zone_secondaries = zone.secondaries | default( bind9_secondaries | default( [] ) ) %} -{% set zone_allow_transfer = zone.allow_transfer | default( zone_secondaries + zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) ) %} -{% if zone_allow_transfer %} +{% if zone.notify is defined %} +{% if zone.notify == 'explicit' %} + notify explicit; +{% else %} + notify {{ zone.notify | ternary ('yes','no') }}; +{% endif %} +{% endif %} +{% set zone_also_notify = zone.also_notify | default( bind9_also_notify | default( [] ) ) %} +{% if zone.also_notify is defined and zone.also_notify | length() > 0 %} + also-notify { +{% for also_notify_item in zone.also_notify | list %} + "{{ also_notify_item }}"; +{% endfor %} + }; +{% endif %} +{% set zone_slaves = zone.slaves | default( bind9_slaves | default( [] ) ) %} +{% set zone_also_allow_transfer = zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) %} +{% set zone_allow_transfer = zone.allow_transfer | default( zone_slaves + zone_also_notify + zone_also_allow_transfer ) %} +{% if zone_allow_transfer | bool %} - // allow transfer from secundaries and extra also_allow_transfer hosts + // allow transfer from secundaries and other hosts allow-transfer { {% for allow_transfer_item in zone_allow_transfer %} {{ allow_transfer_item }}; {% endfor %} }; {% endif %} -{% if bind9_notify_explicit %} - notify explicit; -{% else %} - notify {{ zone.notify | default(true) | ternary ('yes','no') }}; -{% endif %} -{% set zone_also_notify = zone.also_notify | default( bind9_also_notify | default() ) %} -{% if zone_also_notify %} - also-notify { -{% for also_notify_item in zone_also_notify %} - {{ also_notify_item }}; -{% endfor %} - }; -{% endif %} {% if (bind9_dnssec or zone.dnssec | default() ) and zone.dnssec | default( bind9_dnssec_zones_default_enabled ) %} auto-dnssec maintain; inline-signing yes; @@ -92,6 +96,7 @@ zone "{{ zone.name }}" { grant {{ zone.name }}_ddns_update {{ zone.update_policy_grant }}; }; {% endif %} +{# ############################### Zone is slave ####################################### #} {% elif zone_type == 'slave' %} file "/var/lib/bind/db.{{ zone.name }}"; {% if zone.masters | default() or bind9_masters | default() %} @@ -106,8 +111,30 @@ zone "{{ zone.name }}" { {{ master.name }}; {% endfor %} {% endif %} + }; +{% endif %} + allow-query { +{% if zone.allow_query is defined and zone.allow_query | length() > 0 %} +{% for allow_query_item in zone.allow_query | list %} + {{ allow_query_item }}; +{% endfor %} + }; +{% else %} + any; + }; {% endif %} +{% set zone_slaves = zone.slaves | default( bind9_slaves | default( [] ) ) %} +{% set zone_allow_transfer = zone.allow_transfer | default( zone_slaves + zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) ) %} +{% if zone_allow_transfer %} + + // allow transfer from secundaries and extra also_allow_transfer hosts + allow-transfer { +{% for allow_transfer_item in zone_allow_transfer %} + {{ allow_transfer_item }}; +{% endfor %} }; +{% endif %} +{# ############################### Zone is forward ####################################### #} {% elif zone_type == 'forward' %} forwarders { {% for fwd in zone.forwarders %} diff --git a/templates/strict_authoritative/bind/named.conf.options.j2 b/templates/strict_authoritative/bind/named.conf.options.j2 index 9472a17..ac0a56a 100644 --- a/templates/strict_authoritative/bind/named.conf.options.j2 +++ b/templates/strict_authoritative/bind/named.conf.options.j2 @@ -37,10 +37,22 @@ options { allow-query { none; }; allow-transfer { none; }; allow-recursion { none; }; -{% if bind9_notify_explicit|default() %} + +{% if bind9_notify is defined %} +{% if bind9_notify == 'explicit' %} // Notify only nameservers from also-notify, not from NS RRs in zones notify explicit; +{% else %} + notify {{ bind9_notify | ternary ('yes','no') }}; +{% endif %} +{% endif %} +{% if bind9_also_notify is defined and bind9_also_notify | length() > 0 %} + also-notify { +{% for notify_item in bind9_also_notify | list %} + "{{ notify_item }}"; +{% endfor %} + }; {% endif %} {% if bind9_dnssec|default() %} From dddd215ff4c4e853c1d6fb751bafac598960128a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Fri, 3 Jun 2022 12:23:06 -0300 Subject: [PATCH 07/15] First running version of redesigned templates and complete doc --- README.md | 45 +++---- .../bind/named.conf.local.j2 | 119 ++++++++---------- .../bind/named.conf.options.j2 | 6 +- 3 files changed, 77 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index e82c175..0dc79c7 100644 --- a/README.md +++ b/README.md @@ -139,8 +139,10 @@ PRs with good bind9 configs templates are welcome! #### `strict_authoritative` templates' set -This template is designed to configure strict [Authoritative Name Servers](https://bind9.readthedocs.io/en/latest/chapter3.html#config-auth-samples), 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). +This templates' set is designed to configure strict [Authoritative Name Servers](https://bind9.readthedocs.io/en/latest/chapter3.html#config-auth-samples), 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), * customization proposed does it best to guess hosts that must be allowed zone transfer (secundaries and also-notify elements) and tries to implement all kind of sets of primaries or secudaries, visible or hideden. Therefore, when you set `bind9_templates: strict_authoritative/`, in `options` BIND configuration section, this templates always set: @@ -151,15 +153,15 @@ allow-transfer { none; }; allow-recursion { none; }; ``` -Default configuration values are set with `bind9_` role variables, that can be overwritten for each zone with specific values in the `.` field in the corresponding element of `bind9_zones_static` or `bind9_zones_static`. +Default configuration values are set with `bind9_` role variables, that can be overwritten for each zone with specific values in the `.` field in the corresponding zone's element in `bind9_zones_static` or `bind9_zones_static`. Depending on thee parameter considered, the 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 specific values per zone, the role can handle all sort of particular cases for some zones. -The role does it best to also include secundaries NS IPs and also-notify IPs either default one or specific values overwritten for the zone in the zone's `allow-transfer` configuration directive. +The YAML structure of ther variables allows to overcome and unify BIND's management of two kind of lists: masters and acl (at least for simplified configurations the role permits). 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` and `bind9_slaves` should be enough for standard internet zones and if you have the same set of NS authoritative servers for all your zones. Use `bind9_also_notify` if you have some hidden NS servers, but only put there a list of IPs if you want to take advantage of different benefits of the role setting appropiate values wherever needed. If you have some specific configuration of some zones, `bind9_masters_extra` can help you for different sets of masters for slave secundary zones. `bind9_acl` and specific values for zones listed in `bind9_zones_static` and `bind9_zones_dynamic` will help you to set all kind of transfers, notifications and even to restric queries for eventual private zones. +`bind9_masters` and `bind9_slaves` should be enough for standard internet zones and if you have the same set of NS authoritative servers for all your zones. Use `bind9_also_notify` if you have some hidden NS servers. If some of your zones have specific configuration, `bind9_masters_extra` can help you for different sets of masters for slave secundary zones, and `bind9_acl` whith specific values per zones, set in `bind9_zones_static` and `bind9_zones_dynamic`, will help to set all kind of transfers, notifications and even to restric queries for eventual private zones. -Explicitely, ou can use the following variables to configure your NS server and its zones: +Explicitely, you can use the following variables to configure your NS server and its zones: * `bind9_masters`: default master NS servers for zones we are secondary for. ```yaml bind9_masters: @@ -170,31 +172,32 @@ bind9_masters: - IPv4_1 - IPv6_1 ``` -With these lists the template builds the [primaries' lists](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) to be used by default as masters for slave zones, when these are not specifically set for the zone. +With these lists the template builds the [primaries' or masters' list(s)](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) to be used by default as `masters` for slave zones, when these are not specifically set for the zone. Note that masters' list can only contain individual IPs. IPv4 or IPv6, but not network IPs range, ending with a / and a mask length. Taking advantage of the similarity of YAML structure, for each element of `bind9_masters` the templates builds, moreover primaries' list, an [Access Control list (ACL](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists) with the same name and the same content. These ACLs may be used to automatically include the IPs set's name in notify-also directives (which require a masters' list) in the allow-transfer ones (which require an ACL). -`bind9_masters_extra` is a similar structure that also sets primaries' lists, but are not default values for zones. `bind9_masters` and `bind9_masters_extra` can be used anywhere such lists are valid for bind, i.e. to set masters and also-notify zone's lists. +* `bind9_masters_extra` is a similar structure that also sets primaries' lists, but are not default values for zones. `bind9_masters` and `bind9_masters_extra` can be used anywhere such lists are valid for bind, i.e. to set masters and also-notify zone's lists. For a similar purpose as `bind9_masters`, ACLs are also built for `bind9_masters_extra` items, similarly to `bind9_masters`. -* `bind9_acl` has a similar structure with kewords and list of IPs but, in BIND configuration, it builds global [Access Control lists](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists), to be used in other appropriate parameters, particularly in the `allow-xxx` zone by zone. +* `bind9_acl` has a quite similar structure with keywords and list of IPs but, in BIND configuration, it builds global [Access Control lists](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists), to be used in appropriate parameters, particularly in the `allow-xxx` per zone. Note that `bind9_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 slave NS servers for zones we are master for. It's a list of IPs, or eventually ACLs defined with previous variable, and it's used to set the hosts that are allowed to transfer the zone. +* `bind9_slaves` defines the default slave NS servers for zones we are master for. It's a list of IPs, or eventually ACLs defined with previous variable. For zones we are masters for, templates also include these secondaries or slaves IPs in those allowed to transfer the zone, except if the `.slaves` or the `.allow_transfer` parameter hereafter is defined for the zone. -The YAML structure of ther variables allows to overcome and unify BIND's management of two kind of lists: masters and acl. The templates take advantage of this characteristic for default configuration +* `bind9_notify` can take the values `master-only`, `explicit`, `yes` or `no`. It defines the defaut behavior for notification, wich is set in [`options` section](templates/strict_authoritative/bind/named.conf.options.j2#L41). Letting `bind9_notify` undefined doesn't set the directive and therefore leads to BIND's default behavior, i.e. `notify: yes`. We don't won't to overwrite BIND's default behavior, but for most purposes of this template, we recomment to set notify to `master-only`. -* `bind9_notify` can take the values `explicit`, `yes`, `no`, or any other form of boolean values. It defines the defaut behavior for notification, wich is set in [`options` section](templates/strict_authoritative/bind/named.conf.options.j2#L41). `bind9_notify_explicit` is a legacy boolean variable, false by default, which sets `bind9_notify`'s value to `explicit` when `bind9_notify` is not defined. Letting `bind9_notify` undefined leads to BIND's default behavior, i.e. `notify: yes`. +* `bind9_also_notify` is a list that defines the global `also-noitfy`. As such, it can contain IPs or masters' lists, that can be set with the variables `bind9_masters` and `bind9_masters_extra` hereabove. Except if `.also_notify` or `.allow_transfer` is explicitely set for the zone, templates include these IPs in the zone's `allow-transfer` directive. Note that names are interpreted as masters' lists in `also-noitfy` statements and as ACLs in `allow-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_notify` is a list that defines the global `also-noitfy`. As such, it can contain IPs or masters list, that you can set with the variables `bind9_masters` and `bind9_masters_extra` hereabove. However, the role does it best to also include these IPs in the `allow-transfer` directive of the zone, which doesn't handle masters lists, but ACLs. If you use masters list in this variable, you MUST also overwrite the default definition of `bind9_also_allow_transfer` hereafter. +* `bind9_also_allow_transfer` is a variable that can contain a list of IPs, network ranges of IPs and ACL names defined with `bind9_acl`, that will be added, by default for zones we manage, to the `allow-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_also_allow_transfer` is a variable that can contain a list of IPs and ACL names that you can define with +* `bind9_allow_transfer` is a variable that can contain a list of IPs, network ranges of IPs and ACL names, defined with `bind9_acl`. If defined, it will cancel the mechanism previously defined to include secundaries and also-notify in allow-transffer zone's statement. Except if `.allow_transfer` is defined for the zone, the content of `bind9_allow_transfer` and only this will populate the `allow-transfer` zone's statement. -Zone by zone, in `bind9_zones_static` as well as in `bind9_zones_dynamic` list elements, you can define the following zone configuration parameters: +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 is `any`. (breaks the internet: use with care, only for private zones) -* `.notify`: `explicit`, `yes`, `no`, or any other form of boolean values. Sets notification behavior for the zone, -* `.slaves`: can be defined for zones we are master for. It will overwrite `bind9_slaves` for the zone, and the hosts it contains will be allowed for transfer, except if the parameter `.allow_transfer` hereafter is defined. +* `.allow-query`: a list of IPs and/or acls to restrict the clients that can ask for the zone. Default value is `any`. (breaks the internet if you publish an NS record: use with care, only for private zones) +* `.notify`: `explicit`, `yes` or `no` (`master-only` has no really useful for a single zone). Sets notification behavior for the zone, +* `.slaves`: can be defined for zones we are master for. It has a similar structure than `bind9_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. +* `.also_notify`: can be defined zone by zone we are master for, with a similar structure than `bind9_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 overwrite `bind9_also_allow_transfer` if defined, wich will be added to the `allow-transfer` statement content inferred by the role as described hereabove. +* `.allow_transfer`: is a list similar to an ACL, that will overwrite `bind9_allow_transfer` for the zone. Its content and only this will populate the `allow-transfer` zone's statement. -https://bind9.readthedocs.io/en/latest/reference.html?highlight=also-notify#zone-options - -See `defaults/main.yml` for a list of role variables and some doc. +See also `defaults/main.yml` for a list of role variables, inluding those which are used by default templates and not by `strict_authoritative/` ones. ## Dependencies diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 index 5f7e990..331ef80 100644 --- a/templates/strict_authoritative/bind/named.conf.local.j2 +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -44,103 +44,84 @@ acl "{{ acl_item.name }}" { // The following zones are managed by this DNS Server // {% for zone in ( bind9_zones_static + bind9_zones_dynamic ) | sort( attribute='name' ) %} -{% set zone_type = zone.type | default( bind9_zone_type | default( 'master' ) ) %} -{# ############################### Zone is master ####################################### #} +{% set zone_type = zone.type | default( bind9_zone_type | default( 'master' ) ) %} zone "{{ zone.name }}" { type {{ zone_type }}; +{# ############################### Type zone specific statements ####################################### #} {% if zone_type == 'master' %} file "/etc/bind/zones/db.{{ zone.name }}"; - allow-query { -{% if zone.allow_query is defined and zone.allow_query | length() > 0 %} -{% for allow_query_item in zone.allow_query | list %} - {{ allow_query_item }}; -{% endfor %} - }; -{% else %} - any; - }; -{% endif %} -{% if zone.notify is defined %} -{% if zone.notify == 'explicit' %} - notify explicit; -{% else %} - notify {{ zone.notify | ternary ('yes','no') }}; -{% endif %} -{% endif %} -{% set zone_also_notify = zone.also_notify | default( bind9_also_notify | default( [] ) ) %} -{% if zone.also_notify is defined and zone.also_notify | length() > 0 %} - also-notify { -{% for also_notify_item in zone.also_notify | list %} - "{{ also_notify_item }}"; -{% endfor %} - }; -{% endif %} -{% set zone_slaves = zone.slaves | default( bind9_slaves | default( [] ) ) %} -{% set zone_also_allow_transfer = zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) %} -{% set zone_allow_transfer = zone.allow_transfer | default( zone_slaves + zone_also_notify + zone_also_allow_transfer ) %} -{% if zone_allow_transfer | bool %} - - // allow transfer from secundaries and other hosts - allow-transfer { -{% for allow_transfer_item in zone_allow_transfer %} - {{ allow_transfer_item }}; -{% endfor %} - }; -{% endif %} -{% if (bind9_dnssec or zone.dnssec | default() ) and zone.dnssec | default( bind9_dnssec_zones_default_enabled ) %} - auto-dnssec maintain; - inline-signing yes; -{% endif %} -{% if zone.update_policy_grant | default() %} - update-policy { - grant {{ zone.name }}_ddns_update {{ zone.update_policy_grant }}; - }; -{% endif %} -{# ############################### Zone is slave ####################################### #} {% elif zone_type == 'slave' %} file "/var/lib/bind/db.{{ zone.name }}"; -{% if zone.masters | default() or bind9_masters | default() %} - notify {{ zone.notify | default ('no') | ternary ('yes','no') }}; +{% if zone.masters is defined or bind9_masters is defined %} masters { {% if zone.masters is defined %} {% for master in zone.masters %} {{ master }}; {% endfor %} -{% elif bind9_masters is defined %} +{% else %} {# so bind9_masters is defined #} {% for master in bind9_masters %} {{ master.name }}; {% endfor %} {% endif %} }; {% endif %} +{% elif zone_type == 'forward' %} + forwarders { +{% for fwd in zone.forwarders %} + {{ fwd }}; +{% endfor %} + }; +{% endif %} +{# ############################### Common statements to all zone types ####################################### #} allow-query { -{% if zone.allow_query is defined and zone.allow_query | length() > 0 %} -{% for allow_query_item in zone.allow_query | list %} +{% if zone.allow_query is defined and zone.allow_query | length() > 0 %} +{% for allow_query_item in zone.allow_query | list %} {{ allow_query_item }}; -{% endfor %} +{% endfor %} }; -{% else %} +{% else %} any; }; -{% endif %} +{% endif %} +{% if zone.notify is defined %} + notify {{ zone.notify }}; +{% endif %} +{% set zone_also_notify = zone.also_notify | default( bind9_also_notify | default( [] ) ) %} +{% if zone.also_notify is defined and zone.also_notify | length() > 0 %} + also-notify { +{% for also_notify_item in zone.also_notify | list %} + "{{ also_notify_item }}"; +{% endfor %} + }; +{% endif %} +{% set zone_also_allow_transfer = zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) %} +{# ############################### Primary zones must consider secundaries ########################################### #} +{% if zone_type == 'master' %} {% set zone_slaves = zone.slaves | default( bind9_slaves | default( [] ) ) %} -{% set zone_allow_transfer = zone.allow_transfer | default( zone_slaves + zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) ) %} -{% if zone_allow_transfer %} +{% set zone_allow_transfer = zone.allow_transfer | default( ( zone_slaves + zone_also_notify + zone_also_allow_transfer ) | unique ) %} +{% else %} +{% set zone_allow_transfer = zone.allow_transfer | default( ( zone_also_notify + zone_also_allow_transfer ) | unique ) %} +{% endif %} +{% if zone_allow_transfer | bool %} - // allow transfer from secundaries and extra also_allow_transfer hosts + // allow transfer from secundaries, also-notify hosts and othe allow-transfer specified allow-transfer { -{% for allow_transfer_item in zone_allow_transfer %} +{% for allow_transfer_item in zone_allow_transfer %} {{ allow_transfer_item }}; -{% endfor %} +{% endfor %} + }; +{% endif %} +{# ############################### Primary zones are concerned by dnssec ########################################### #} +{% if zone_type == 'master' %} +{% if ( bind9_dnssec or zone.dnssec | default() ) and zone.dnssec | default( bind9_dnssec_zones_default_enabled ) %} + auto-dnssec maintain; + inline-signing yes; +{% endif %} +{% if zone.update_policy_grant | default() %} + update-policy { + grant {{ zone.name }}_ddns_update {{ zone.update_policy_grant }}; }; {% endif %} -{# ############################### Zone is forward ####################################### #} -{% elif zone_type == 'forward' %} - forwarders { -{% for fwd in zone.forwarders %} - {{ fwd }}; -{% endfor %} - }; {% endif %} }; {% endfor %} \ No newline at end of file diff --git a/templates/strict_authoritative/bind/named.conf.options.j2 b/templates/strict_authoritative/bind/named.conf.options.j2 index ac0a56a..76e99d6 100644 --- a/templates/strict_authoritative/bind/named.conf.options.j2 +++ b/templates/strict_authoritative/bind/named.conf.options.j2 @@ -60,9 +60,9 @@ options { key-directory "/etc/bind/keys"; {% endif %} }; -{% if bind9_zones_static|selectattr('update_keyfile','defined')|list|default() %} -{% for zone in bind9_zones_static|selectattr('update_keyfile','defined')|list|default([]) %} -{% if zone_type|default(bind9_zone_type|default('master')) == 'master' %} +{% if bind9_zones_static | selectattr( 'update_keyfile', 'defined' ) | list | default() %} +{% for zone in bind9_zones_static | selectattr('update_keyfile','defined') | list | default([]) %} +{% if zone_type | default( bind9_zone_type | default('master') ) == 'master' %} {% if loop.first %} // The following keys are used for dynamic DNS updates From c94073fbb246e44dabfc25e77db29928c216f519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Mon, 6 Jun 2022 23:47:28 -0300 Subject: [PATCH 08/15] WIP debugging templates with example --- README.md | 87 +++++++++++-------- .../bind/named.conf.local.j2 | 6 +- 2 files changed, 55 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 0dc79c7..b3c9086 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,13 @@ [![Build Status](https://github.com/systemli/ansible-role-bind9/workflows/Integration/badge.svg?branch=main)](https://github.com/systemli/ansible-role-bind9/actions?query=workflow%3AIntegration) [![Ansible Galaxy](http://img.shields.io/badge/ansible--galaxy-bind9-blue.svg)](https://galaxy.ansible.com/systemli/bind9/) -This role installs and configures the Bind9 nameserver on Debian. +This role installs and configures [BIND9](https://www.isc.org/bind/) on Debian to set a Name Server. Features: -* Support for configuring an authoritative nameserver for DNS zones and/or a DNS recursor +* 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 @@ -19,11 +21,11 @@ Features: ## Basic server configuration -Lest's start by a simple but complete configuration: +Lest's start by a simple but complete configuration of two servers: ### Master server -* set vars for your master server, for instance in `host_vars/master_name/vars/XX_bind.yml`, here with an example.com static zones and forwarder: +* 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: ```yaml bind9_authoritative: yes bind9_zones_static: @@ -41,7 +43,7 @@ bind9_our_neighbors: - 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. +* 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. ### Slave servers @@ -64,8 +66,9 @@ bind9_recursor: our_network In previous example, zones' ressource records are defined by a classic BIND9 zone file, which validity is checked, but that you have to maintain. These are the so called "static zones", raw defined by a `db.` file. -So called "dynamic" zones' files are built form ansible variables. Theire ressource records are defined through YAML ansible structure `bind9_zones_dynamic` which is parsed by [`bind/zones/db.template.j2`](templates/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 splited in several variables, that can bie defined in specific files. In `YY_zones.yml` we may have: +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`](templates/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 splited in several variables, that can be defined in specific files. In `YY_zones.yml` we may have: ```yaml bind9_zones_dynamic: > {{ zones_my_domains @@ -82,7 +85,7 @@ bind9_zones_static: - name: static_dom3.org type: slave ``` -And in other vars files: +And in other vars' files: ```yaml zones_my_domains: # This is the variables set for my domain @@ -112,18 +115,20 @@ zones_my_domains: - {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 we adopted for generic NS records the terminology defined in [RFC 1034, Section 3.6](https://datatracker.ietf.org/doc/html/rfc1034#section-3.6) +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](https://datatracker.ietf.org/doc/html/rfc1034#section-3.6) ## Configurable templates' set -Basically the role builds bind9 configuration, i.e. `/etc/bind/named.conf,*` files, as well aa zone definition files, whicha are placed in `/etc/bind/zones/` directory. +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 set of templates. Presently two sets of templates are proposed: +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. +* 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 ot the relative one to the `templates/` directory of the role. For [strict authoritative NS config](templates/strict_authoritative/), define in your vartiables: +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](templates/strict_authoritative/), define in your vartiables: ```yaml bind9_templates: strict_authoritative/ ``` @@ -133,17 +138,16 @@ You can develop your own set of templates and set, for instance: ```yaml bind9_templates: "{{ playbook_dir }}/host_vars//templates/" ``` -PRs with good bind9 configs templates are welcome! - -### Role templates' variables +PRs with good BIND9 configs templates are welcome! -#### `strict_authoritative` templates' set +### `strict_authoritative` templates' set This templates' set is designed to configure strict [Authoritative Name Servers](https://bind9.readthedocs.io/en/latest/chapter3.html#config-auth-samples), 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), -* customization proposed does it best to guess hosts that must be allowed zone transfer (secundaries and also-notify elements) and tries to implement all kind of sets of primaries or secudaries, visible or hideden. +* 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, this templates always set: ``` @@ -155,34 +159,45 @@ allow-recursion { none; }; Default configuration values are set with `bind9_` role variables, that can be overwritten for each zone with specific values in the `.` field in the corresponding zone's element in `bind9_zones_static` or `bind9_zones_static`. -Depending on thee parameter considered, the 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 specific values per zone, the role can handle all sort of particular cases for some zones. +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 BIND's management of two kind of lists: masters and acl (at least for simplified configurations the role permits). 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. +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` and `bind9_slaves` should be enough for standard internet zones and if you have the same set of NS authoritative servers for all your zones. Use `bind9_also_notify` if you have some hidden NS servers. If some of your zones have specific configuration, `bind9_masters_extra` can help you for different sets of masters for slave secundary zones, and `bind9_acl` whith specific values per zones, set in `bind9_zones_static` and `bind9_zones_dynamic`, will help to set all kind of transfers, notifications and even to restric queries for eventual private zones. +### `strict_authoritative` use cases -Explicitely, you can use the following variables to configure your NS server and its zones: -* `bind9_masters`: default master NS servers for zones we are secondary for. -```yaml -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)](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) to be used by default as `masters` for slave zones, when these are not specifically set for the zone. Note that masters' list can only contain individual IPs. IPv4 or IPv6, but not network IPs range, ending with a / and a mask length. Taking advantage of the similarity of YAML structure, for each element of `bind9_masters` the templates builds, moreover primaries' list, an [Access Control list (ACL](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists) with the same name and the same content. These ACLs may be used to automatically include the IPs set's name in notify-also directives (which require a masters' list) in the allow-transfer ones (which require an ACL). +* `bind9_masters` and `bind9_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 about `allow-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 about `allow-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 in `bind9_zones_static` or `bind9_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. -* `bind9_masters_extra` is a similar structure that also sets primaries' lists, but are not default values for zones. `bind9_masters` and `bind9_masters_extra` can be used anywhere such lists are valid for bind, i.e. to set masters and also-notify zone's lists. For a similar purpose as `bind9_masters`, ACLs are also built for `bind9_masters_extra` items, similarly to `bind9_masters`. +### Role's variables for `strict_authoritative` templates + +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. + ```yaml + 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)](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) 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 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 of `bind9_masters` the templates build, moreover the primaries' list, an [Access Control List (ACL)](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists) 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` or `also-notify` statements of a zone, but also in [the variables that define] statements which work with ACLs, such as `allow-transfer` or `allow-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. For similar purposes than `bind9_masters`, ACLs are also built for `bind9_masters_extra` items. Similarly than `bind9_masters`, `bind9_masters_extra` elements can be used, not only where such lists are valid for, i.e. to set masters and also-notify zone's lists, but also where ACLs are needed, such as `allow-transfer` or `allow-query`. * `bind9_acl` has a quite similar structure with keywords and list of IPs but, in BIND configuration, it builds global [Access Control lists](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists), to be used in appropriate parameters, particularly in the `allow-xxx` per zone. Note that `bind9_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 slave NS servers for zones we are master for. It's a list of IPs, or eventually ACLs defined with previous variable. For zones we are masters for, templates also include these secondaries or slaves IPs in those allowed to transfer the zone, except if the `.slaves` or the `.allow_transfer` parameter hereafter is defined for the zone. +* `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 values `master-only`, `explicit`, `yes` or `no`. It defines the defaut behavior for notification, wich is set in [`options` section](templates/strict_authoritative/bind/named.conf.options.j2#L41). Letting `bind9_notify` undefined doesn't set the directive and therefore leads to BIND's default behavior, i.e. `notify: yes`. We don't won't to overwrite BIND's default behavior, but for most purposes of this template, we recomment to set notify to `master-only`. -* `bind9_also_notify` is a list that defines the global `also-noitfy`. As such, it can contain IPs or masters' lists, that can be set with the variables `bind9_masters` and `bind9_masters_extra` hereabove. Except if `.also_notify` or `.allow_transfer` is explicitely set for the zone, templates include these IPs in the zone's `allow-transfer` directive. Note that names are interpreted as masters' lists in `also-noitfy` statements and as ACLs in `allow-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_notify` is a list that defines the global `also-noitfy`. As such, it can contain IPs or masters' lists, that can be set with the variables `bind9_masters` and `bind9_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 for `bind9_masters` and `bind9_masters_extra` to include the content of `bind9_also_notify` in the zone's `allow-transfer` directive, what would not be possible with BIND's syntax and grammar alone. Names are interpreted as masters' lists in `also-noitfy` statements and as ACLs in `allow-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 with `bind9_acl`, that will be added, by default for zones we manage, to the `allow-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. diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 index 331ef80..57182ec 100644 --- a/templates/strict_authoritative/bind/named.conf.local.j2 +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -97,11 +97,13 @@ zone "{{ zone.name }}" { {% set zone_also_allow_transfer = zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) %} {# ############################### Primary zones must consider secundaries ########################################### #} {% if zone_type == 'master' %} +{% set zone_calc_allow_transfer = zone.slaves | default( bind9_slaves | default( [] ) ) + zone_also_notify + zone_also_allow_transfer %} + {% set zone_slaves = zone.slaves | default( bind9_slaves | default( [] ) ) %} -{% set zone_allow_transfer = zone.allow_transfer | default( ( zone_slaves + zone_also_notify + zone_also_allow_transfer ) | unique ) %} {% else %} -{% set zone_allow_transfer = zone.allow_transfer | default( ( zone_also_notify + zone_also_allow_transfer ) | unique ) %} +{% set zone_calc_allow_transfer = zone_also_notify + zone_also_allow_transfer %} {% endif %} +{% set zone_allow_transfer = zone.allow_transfer | default ( bind9_allow_transfer | default( ( zone_calc_allow_transfer ) | unique ) %} {% if zone_allow_transfer | bool %} // allow transfer from secundaries, also-notify hosts and othe allow-transfer specified From 3d958f30858153b71f8b6839bbb1e26b61e3c8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Mon, 6 Jun 2022 23:54:05 -0300 Subject: [PATCH 09/15] customizable zones' files directory and list union syntax --- defaults/main.yml | 5 +++++ tasks/main.yml | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index b8d1707..0877a74 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -118,6 +118,11 @@ bind9_statistics_enabled: False bind9_zones_dynamic: [] bind9_zones_static: [] +# With this value, the `copy` module will look for zone files in `files/bind/zones/` in the playbook directory +bind9_zone_files: bind/zones/ +# Overwrite, for instance if you want to put your db.* zone files in your host vars: +# bind9_zone_files: '{{ playbook_dir }}/host_vars/{{ ansible_hostname }}/files/bind/zones/' + # Authoritative include files bind9_authoritative_includes: [] diff --git a/tasks/main.yml b/tasks/main.yml index 0f201ce..692d5f0 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -143,6 +143,18 @@ - item.type|default(bind9_zone_type) == 'master' - item.update_keyfile|default() +- debug: + var: item + verbosity: 2 + with_items: + - '{{ bind9_zones_dynamic | union( bind9_zones_static ) }}' + when: + - bind9_authoritative|default() + - bind9_dnssec|default() or item.dnssec|default(bind9_dnssec_zones_default_enabled) + - item.dnssec|default(bind9_dnssec_zones_default_enabled) + tags: + - role:bind9:dnssec + # TODO: DNSSEC: implement key rollover - name: determine if DNSSEC keys for zones already exist find: @@ -150,7 +162,7 @@ patterns: "K{{ item.name }}.+008+*" register: bind9_reg_dnssec_keys_tmp with_items: - - "{{ bind9_zones_dynamic }} + {{ bind9_zones_static }}" + - '{{ bind9_zones_dynamic | union( bind9_zones_static ) }}' when: - bind9_authoritative|default() - bind9_dnssec|default() or item.dnssec|default(bind9_dnssec_zones_default_enabled) @@ -313,7 +325,7 @@ - name: install static bind9 zone files copy: - src: bind/zones/db.{{ item.name }} + src: '{{ bind9_zone_files }}db.{{ item.name }}' dest: /etc/bind/zones/db.{{ item.name }} owner: root group: "{{ bind9_group }}" From 9e4c4f4243c501ed8da759e2b90a144c6ae29b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Tue, 7 Jun 2022 11:59:53 -0300 Subject: [PATCH 10/15] allow_transfer debug 1 --- .../strict_authoritative/bind/named.conf.local.j2 | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 index 57182ec..bb874ad 100644 --- a/templates/strict_authoritative/bind/named.conf.local.j2 +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -97,14 +97,12 @@ zone "{{ zone.name }}" { {% set zone_also_allow_transfer = zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) %} {# ############################### Primary zones must consider secundaries ########################################### #} {% if zone_type == 'master' %} -{% set zone_calc_allow_transfer = zone.slaves | default( bind9_slaves | default( [] ) ) + zone_also_notify + zone_also_allow_transfer %} - -{% set zone_slaves = zone.slaves | default( bind9_slaves | default( [] ) ) %} +{% set zone_calc_allow_transfer = zone.slaves | default( bind9_slaves | default( [] ) ) | union( zone_also_notify | union ( zone_also_allow_transfer ) ) %} {% else %} -{% set zone_calc_allow_transfer = zone_also_notify + zone_also_allow_transfer %} +{% set zone_calc_allow_transfer = zone_also_notify | union( zone_also_allow_transfer ) %} {% endif %} -{% set zone_allow_transfer = zone.allow_transfer | default ( bind9_allow_transfer | default( ( zone_calc_allow_transfer ) | unique ) %} -{% if zone_allow_transfer | bool %} +{% set zone_allow_transfer = zone.allow_transfer | default ( bind9_allow_transfer | default( ( zone_calc_allow_transfer ) | unique ) ) %} +{% if zone_allow_transfer | length > 0 %} // allow transfer from secundaries, also-notify hosts and othe allow-transfer specified allow-transfer { From 01fca784dfabf5a8f220edbd75d7a31ab92b8fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Wed, 8 Jun 2022 14:08:30 -0300 Subject: [PATCH 11/15] no quotes in statements names --- templates/strict_authoritative/bind/named.conf.local.j2 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 index bb874ad..c72059c 100644 --- a/templates/strict_authoritative/bind/named.conf.local.j2 +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -17,12 +17,12 @@ statistics-channels { // masters clause lists for masters secondary zones and also-notify statements // and ACLs with same name and content, to be used in allow-transfer statements {% for master in bind9_masters | default ([]) + bind9_masters_extra | default ([]) %} -masters "{{ master.name }}" { +masters {{ master.name }} { {% for addr in master.addresses %} {{ addr }}; {% endfor %} }; -acl "{{ master.name }}" { +acl {{ master.name }} { {% for addr in master.addresses %} {{ addr }}; {% endfor %} @@ -34,7 +34,7 @@ acl "{{ master.name }}" { // Custom acls {% for acl_item in bind9_acl %} -acl "{{ acl_item.name }}" { +acl {{ acl_item.name }} { {% for acl_address in acl_item.addresses %} {{ acl_address }}; {% endfor %} @@ -90,7 +90,7 @@ zone "{{ zone.name }}" { {% if zone.also_notify is defined and zone.also_notify | length() > 0 %} also-notify { {% for also_notify_item in zone.also_notify | list %} - "{{ also_notify_item }}"; + {{ also_notify_item }}; {% endfor %} }; {% endif %} From 1467fd200ad5c5d8c7c550dc432b7aa6ba7d330c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Tue, 21 Jun 2022 18:11:24 -0300 Subject: [PATCH 12/15] bind9_authoritative is also conditional --- README.md | 21 ++++++++++++++------- defaults/main.yml | 5 +++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b3c9086..b63e0c0 100644 --- a/README.md +++ b/README.md @@ -64,11 +64,11 @@ bind9_recursor: our_network ## Static zones and Dynamic zones -In previous example, zones' ressource records are defined by a classic BIND9 zone file, which validity is checked, but that you have to maintain. These are the so called "static zones", raw defined by a `db.` file. +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.` 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`](templates/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 splited in several variables, that can be defined in specific files. In `YY_zones.yml` we may have: +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: ```yaml bind9_zones_dynamic: > {{ zones_my_domains @@ -142,14 +142,14 @@ PRs with good BIND9 configs templates are welcome! ### `strict_authoritative` templates' set -This templates' set is designed to configure strict [Authoritative Name Servers](https://bind9.readthedocs.io/en/latest/chapter3.html#config-auth-samples), primaries or secondaries: +[This templates' set](templates/strict_authoritative) is designed to configure strict [Authoritative Name Servers](https://bind9.readthedocs.io/en/latest/chapter3.html#config-auth-samples), 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, this templates always set: +Therefore, when you set `bind9_templates: strict_authoritative/`, in `options` BIND configuration section, these templates always set: ``` recursion no; allow-query { none; }; @@ -185,7 +185,7 @@ Explicitely, you can use the following variables to configure your NS server and - IPv4_1 - IPv6_1 ``` - With these lists the template builds the [primaries' or masters' list(s)](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) 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 individual IPs. IPv4 or IPv6, but not network IPs range, ending with a / and a mask length. + With these lists the template builds the [primaries' or masters' list(s)](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) 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 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 of `bind9_masters` the templates build, moreover the primaries' list, an [Access Control List (ACL)](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists) 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` or `also-notify` statements of a zone, but also in [the variables that define] statements which work with ACLs, such as `allow-transfer` or `allow-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. @@ -195,7 +195,7 @@ Explicitely, you can use the following variables to configure your NS server and * `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 values `master-only`, `explicit`, `yes` or `no`. It defines the defaut behavior for notification, wich is set in [`options` section](templates/strict_authoritative/bind/named.conf.options.j2#L41). Letting `bind9_notify` undefined doesn't set the directive and therefore leads to BIND's default behavior, i.e. `notify: yes`. We don't won't to overwrite BIND's default behavior, but for most purposes of this template, we recomment to set notify to `master-only`. +* `bind9_notify` can take the values `master-only`, `explicit`, `yes` or `no`. It defines the defaut behavior for notification, wich is set in [`options` section](templates/strict_authoritative/bind/named.conf.options.j2#L41). Letting `bind9_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 to `master-only`. * `bind9_also_notify` is a list that defines the global `also-noitfy`. As such, it can contain IPs or masters' lists, that can be set with the variables `bind9_masters` and `bind9_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 for `bind9_masters` and `bind9_masters_extra` to include the content of `bind9_also_notify` in the zone's `allow-transfer` directive, what would not be possible with BIND's syntax and grammar alone. Names are interpreted as masters' lists in `also-noitfy` statements and as ACLs in `allow-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. @@ -212,7 +212,14 @@ Zone by zone, in `bind9_zones_static` as well as in `bind9_zones_dynamic` list's * `.also_allow_transfer`: is a list similar to an ACL, that will overwrite `bind9_also_allow_transfer` if defined, wich will be added to the `allow-transfer` statement content inferred by the role as described hereabove. * `.allow_transfer`: is a list similar to an ACL, that will overwrite `bind9_allow_transfer` for the zone. Its content and only this will populate the `allow-transfer` zone's statement. -See also `defaults/main.yml` for a list of role variables, inluding those which are used by default templates and not by `strict_authoritative/` ones. +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 and other roles's variables + +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`](defaults/main.yml) for a list of role's variables, including those which are used by default templates and not by `strict_authoritative/` ones. + ## Dependencies diff --git a/defaults/main.yml b/defaults/main.yml index 0877a74..520d5de 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -12,8 +12,9 @@ bind9_ipv6: yes bind9_recursor: no # Run bind as authoritative nameserver? -# variable used only by default templates, not strict_authoritative -bind9_authoritative: no +# variable by default templates and as conditionnal of several tasks +# If using `strict_authoritative/` templates, this variable _must_ be true +bind9_authoritative: "{{ true if bind9_templates == 'strict_authoritative/' else false }}" # run bind with forwarding? bind9_forward: no From 6828f698981e57337445033b849eef0891383bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Fri, 1 Jul 2022 16:09:58 -0300 Subject: [PATCH 13/15] from @apias review --- templates/strict_authoritative/bind/named.conf.local.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 index c72059c..9fe1489 100644 --- a/templates/strict_authoritative/bind/named.conf.local.j2 +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -104,7 +104,7 @@ zone "{{ zone.name }}" { {% set zone_allow_transfer = zone.allow_transfer | default ( bind9_allow_transfer | default( ( zone_calc_allow_transfer ) | unique ) ) %} {% if zone_allow_transfer | length > 0 %} - // allow transfer from secundaries, also-notify hosts and othe allow-transfer specified + // allow transfer from secundaries, also-notify hosts and other allow-transfer specified allow-transfer { {% for allow_transfer_item in zone_allow_transfer %} {{ allow_transfer_item }}; From ca8bf8059f55550f460bea634986a68ac7a8e590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Tue, 5 Jul 2022 17:24:06 -0300 Subject: [PATCH 14/15] taking into account @xshadow code review --- README.md | 16 +-- defaults/main.yml | 115 +++++++++--------- meta/main.yml | 2 - molecule/docker/Dockerfile.j2 | 3 - molecule/docker/INSTALL.rst | 39 ------ molecule/docker/molecule.yml | 16 --- templates/bind/named.conf.local.j2 | 6 +- .../bind/named.conf.local.j2 | 6 +- 8 files changed, 74 insertions(+), 129 deletions(-) delete mode 100644 molecule/docker/Dockerfile.j2 delete mode 100644 molecule/docker/INSTALL.rst delete mode 100644 molecule/docker/molecule.yml diff --git a/README.md b/README.md index b63e0c0..1c57f9d 100644 --- a/README.md +++ b/README.md @@ -186,10 +186,10 @@ Explicitely, you can use the following variables to configure your NS server and - IPv6_1 ``` With these lists the template builds the [primaries' or masters' list(s)](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) 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 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 of `bind9_masters` the templates build, moreover the primaries' list, an [Access Control List (ACL)](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists) 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` or `also-notify` statements of a zone, but also in [the variables that define] statements which work with ACLs, such as `allow-transfer` or `allow-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. For similar purposes than `bind9_masters`, ACLs are also built for `bind9_masters_extra` items. Similarly than `bind9_masters`, `bind9_masters_extra` elements can be used, not only where such lists are valid for, i.e. to set masters and also-notify zone's lists, but also where ACLs are needed, such as `allow-transfer` or `allow-query`. +* `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 of `bind9_masters` and `bind9_masters_extra` the templates build, moreover the primaries' list, an [Access Control List (ACL)](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists) 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` or `also-notify` clauses of a zone, but also in [the variables that define] clauses which work with ACLs, such as `allow-transfer` or `allow-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](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists), to be used in appropriate parameters, particularly in the `allow-xxx` per zone. Note that `bind9_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. @@ -197,20 +197,22 @@ Explicitely, you can use the following variables to configure your NS server and * `bind9_notify` can take the values `master-only`, `explicit`, `yes` or `no`. It defines the defaut behavior for notification, wich is set in [`options` section](templates/strict_authoritative/bind/named.conf.options.j2#L41). Letting `bind9_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 to `master-only`. -* `bind9_also_notify` is a list that defines the global `also-noitfy`. As such, it can contain IPs or masters' lists, that can be set with the variables `bind9_masters` and `bind9_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 for `bind9_masters` and `bind9_masters_extra` to include the content of `bind9_also_notify` in the zone's `allow-transfer` directive, what would not be possible with BIND's syntax and grammar alone. Names are interpreted as masters' lists in `also-noitfy` statements and as ACLs in `allow-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_notify` is a list that defines the global `also-noitfy`. As such, it can contain IPs or masters' lists, that can be set with the variables `bind9_masters` and `bind9_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 for `bind9_masters` and `bind9_masters_extra` to include the content of `bind9_also_notify` in the zone's `allow-transfer` directive, what would not be possible with BIND's syntax and grammar alone. Names are interpreted as masters' lists in `also-noitfy` clauses and as ACLs in `allow-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 with `bind9_acl`, that will be added, by default for zones we manage, to the `allow-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 with `bind9_acl`. If defined, it will cancel the mechanism previously defined to include secundaries and also-notify in allow-transffer zone's statement. Except if `.allow_transfer` is defined for the zone, the content of `bind9_allow_transfer` and only this will populate the `allow-transfer` zone's statement. +* `bind9_allow_transfer` is a variable that can contain a list of IPs, network ranges of IPs and ACL names, defined with `bind9_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 of `bind9_allow_transfer` and only this will populate the `allow-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 is `any`. (breaks the internet if you publish an NS record: use with care, only for private zones) -* `.notify`: `explicit`, `yes` or `no` (`master-only` has no really useful for a single zone). Sets notification behavior for the zone, +* `.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 in `bind9_masters` and `bind9_masters_extra`, and reference them by name. * `.slaves`: can be defined for zones we are master for. It has a similar structure than `bind9_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` or `no` (`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 than `bind9_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 overwrite `bind9_also_allow_transfer` if defined, wich will be added to the `allow-transfer` statement content inferred by the role as described hereabove. -* `.allow_transfer`: is a list similar to an ACL, that will overwrite `bind9_allow_transfer` for the zone. Its content and only this will populate the `allow-transfer` zone's statement. +* `.allow_transfer`: is a list similar to an ACL, that will overwrite `bind9_allow_transfer` for the zone. Its content and only this will populate the `allow-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). diff --git a/defaults/main.yml b/defaults/main.yml index 520d5de..4800d58 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -7,12 +7,34 @@ bind9_group: bind # Listen on IPv6 interfaces bind9_ipv6: yes +# bind9_templates: Directory for bind9 files templates +# The role can handle different sets of templates for bind and zones configuration. +# It presently proposes two sets of templates: +# +# * the defaults one, "", wich is a general purpose configuration set, that has evolved with the role. +# It's files live in {{ role_path }}/templates/ directory +# * a second new set for a strict authoritative bind NS server: `strict_authoritative` It accepts DNS queries +# only for zones it is authoritative for. Templates try to be smart: `allow-transfer` for secunday NS servers +# and `notify-also` for hidden slaves are automatically set, and can be overwitten zone by zone, as well as +# `allow-query` and `notify` clauses. +# It's files live in {{ role_path }}/templates/strict_authoritative/ directory +# Note that several default variables `bind9_*` have different meanings than with default templates' set. +# +# bind9_templates must be set as an absolute directory or relative to the `templates` directory of the role, and +# must include it's trailing "/". For instance, for the `strict_authoritative` set of templates, you can define: +# +# bind9_templates: strict_authoritative/ +# +# You can design and set your own templates (PRs welcome!), for example with: +# bind9_templates: "{{ playbook_dir }}/host_vars//templates/" +bind9_templates: "" + # Run bind as a DNS recursor? # variable used only by default templates, not strict_authoritative bind9_recursor: no # Run bind as authoritative nameserver? -# variable by default templates and as conditionnal of several tasks +# variable used by default templates and as conditionnal of several tasks # If using `strict_authoritative/` templates, this variable _must_ be true bind9_authoritative: "{{ true if bind9_templates == 'strict_authoritative/' else false }}" @@ -35,9 +57,6 @@ bind9_hidden_master: no # Necessary to keep traffic between nameservers in private network. bind9_notify_explicit: no -# bind9_notify: '{{ "explicit" if bind9_notify_explicit else undef }}' -# undef doesn't work here. f**k legacy bind9_notify_explicit variable? - # Default zone type bind9_zone_type: master @@ -61,53 +80,52 @@ bind9_rndc_algorithm: hmac-md5 # bind9_rndc_key: # Global primaries for all zones (if configured as secondary), default masters if not defined in the zone -# bind9_masters: -# - name: ns-primary -# addresses: -# - 1.2.3.4 -# For BIND 9.17.3 (not yet in debian): https://downloads.isc.org/isc/bind9/9.17.3/doc/arm/html/notes.html#feature-changes -# Let's progressively rename this variable with bind's preferred terminology: -# bind9_primaries: "{{ bind9_masters }}" +# bind9_masters: +# - name: ns-primary +# addresses: +# - 1.2.3.4 # Primaries for particular zones (if configured as secondary), that can also be used in also-notify directives -# bind9_masters_extra: -# - name: "ns-primary" -# addresses: -# - 1.2.3.4 -# Let's progressively rename this variable with bind's preferred terminology: -# bind9_primaries_extra: "{{ bind9_masters_extra }}" +# bind9_masters_extra: +# - name: "ns-primary" +# addresses: +# - 1.2.3.4 +# - name: ... +# addresses: +# - ... + +# Note that the role wil create masters lists _as well as_ ACLs for each element of `bind9_masters` and `bind9_masters_extra` +# allowing the magic to be able to put the same _names_ in the following parameters # Global secondaries for all zones (if configured as primary), default slaves if not specifically defined for the zone -# bind9_slaves: -# - 1.2.3.4 -# -# Let's progressively rename this variable with bind's preferred terminology: -# bind9_secondaries: "{{ bind9_slaves }}" +# bind9_slaves: +# - 1.2.3.4 +# - ns-primary +# - ... +# This variable, that can be overwritten zone by zone (see README) is mainly used to build the `allow-transfer` clause of +# each zone. +# Notice that we set here the name `ns-primary` defined above. This wouldn't be possible in BIND9 configuration, if +# `ns-primary` is a masters list. Here, for slaves, i.e. to set `allow-transfer` at the masters level, we are in fact +# referring to the ACL weith the same name. # bind9_acl: -# undefined by default, this variable allows to define a set of several access control lists (ACL) -# with the same format as `bind9_masters`, and use it in slaves. allow-query or allow-transfer definitions +# undefined by default, this variable allows to define a set of access control lists (ACL) to use in slaves, allow-query +# or allow-transfer definitions. In YAML, `bind9_acl` has the same format as `bind9_masters`, except that, morover IPs, it can +# contain networks definitions (IP/MASK). + +## The following variables are default values for all zones, that can be overwritten zone by zone. # bind9_also_notify: -# undefined by default, a list of IPs or masters lists to be defined as global `notify-also` list in configuration. +# undefined by default, a list of IPs or masters lists that defines the global `also-notify` clause in configuration. +# By default, `bind9_also_notify` items are automatically included in `allow-transfer` clause in each zone. # bind9_also_allow_transfer: -# bind9_also_allow_transfer: '{{ bind9_also_notify if bind9_also_notify is defined else undef }}' -# defaults to bind9_also_notify, but this definitio must be overwritten if this vairable contains masters names. -# As far as bind9_also_notify is just a list of IPs, default values of the role take advantage of the similar strucuture -# in YAML for lasters lists and ACLs, and the can by default allow transfer, zone by zone, to slaves and also notify IPS - -# bind9_also_allow_transfer -#bind9_also_allow_transfer: '{{ bind9_also_notify if bind9_also_notify is defined else undef }}' -# for primary zones, except if `allow_transfer` is explicitly defined for the zone, by default an `allow-transfer` list -# will be set, iincluding slave NS of the host and either the list also_allow_transfer defined for the zone, either this -# default list. -# If `bind9_also_notify` is defined by default `bind9_also_allow_transfer` has the same values. -# But be carefull: in BIND9 configuration, `also-notify` may include `masters` lists but not `acl` ones, while -# `allow-transfer` may include `acl` lists but not `masters` ones. In YAML role's variables structures are identical, but -# if they appear in BIND configuration list inclusions it will fail. -# Practically: if you use `masters` lists (defined with `bind9_masters`or `bind9_masters_extra` variables of this role), -# yo must re-define separately `bind9_also_allow_transfer`, probably defining an ACL with same values than master lists. +# As stated above, by default, slaves and also-notify hosts are automatically included in the allow-transfer clauses of zones. +# You can define here any _additional_ IP or ACL you would like, by default, to also allow transfer. + +# bind9_allow_transfer: +# Defining this variables bypasses the previous mechanism of including slaves and also-notify hosts in the allow-transfer clause +# of the zone in its master servers, and sets the `allow-transfer` to its content. # Enable BIND's XML statistics-channels (for monitoring purposes) bind9_statistics_enabled: False @@ -160,21 +178,6 @@ bind9_packages: - bind9 - dnsutils -# Directory for bind9 files templates -bind9_templates: "" -# The role can handle different sets of templates for bind and zones configuration. -# It presently proposes two sets of templates: -# * the defaults one, "", wich is a general purpose configuration set, that has evolved with the role. -# It's files live in {{ role_path }}/templates/ directory -# * a second new set for a strict authoritative bind NS server: `strict_authoritative` It accepts DNS queries only for zones it is authoritative for. -# allow-transfer for secunday NS servers, notify-also for hidden slaves, and even allow-query and notify can be defined zone by zone. -# It's files live in {{ role_path }}/templates/strict_authoritative/ directory -# Note that several default variables `bind9_*` have different meanings than with default templates' set. -# bind9_templates nust be set as a relative or absolute directory, including it's trailing "/": -# bind9_templates: strict_authoritative/ -# You can set your own templates, for example with: -# bind9_templates: "{{ playbook_dir }}/host_vars//templates/" - # Logging bind9_named_logging: False bind9_log_path: /var/log/bind diff --git a/meta/main.yml b/meta/main.yml index f9d17d3..a97d143 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -16,5 +16,3 @@ galaxy_info: versions: - bullseye - buster - notifications: - webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/molecule/docker/Dockerfile.j2 b/molecule/docker/Dockerfile.j2 deleted file mode 100644 index 39a5f17..0000000 --- a/molecule/docker/Dockerfile.j2 +++ /dev/null @@ -1,3 +0,0 @@ -FROM {{ item.image }} - -RUN apt-get update && apt-get upgrade -y && apt-get install -y python sudo bash ca-certificates && apt-get clean diff --git a/molecule/docker/INSTALL.rst b/molecule/docker/INSTALL.rst deleted file mode 100644 index 1a063f0..0000000 --- a/molecule/docker/INSTALL.rst +++ /dev/null @@ -1,39 +0,0 @@ -******* -Install -******* - -This set of playbooks have specific dependencies on Ansible due to the modules -being used. - -Requirements -============ - -* Ansible 2.2 or higher -* Docker Engine -* docker-py - -Install OS dependencies on Debian 9 (Stretch) - -.. code-block:: bash - - # apt-get update - # apt-get install -y python-pip libssl-dev python-docker - ## If installing Molecule from source. - # apt-get install -y libffi-dev git - -Install OS dependencies on Ubuntu 16.x - -.. code-block:: bash - - $ sudo apt-get update - $ sudo apt-get install -y python-pip libssl-dev docker-engine - # If installing Molecule from source. - $ sudo apt-get install -y libffi-dev git - -Install using pip: - -.. code-block:: bash - - $ sudo pip install ansible - $ sudo pip install docker-py - $ sudo pip install molecule --pre diff --git a/molecule/docker/molecule.yml b/molecule/docker/molecule.yml deleted file mode 100644 index f19014c..0000000 --- a/molecule/docker/molecule.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -driver: - name: docker -platforms: - - name: instance - image: "geerlingguy/docker-${MOLECULE_DISTRO:-debian11}-ansible:latest" - command: ${MOLECULE_DOCKER_COMMAND:-""} - volumes: - - /sys/fs/cgroup:/sys/fs/cgroup:ro - privileged: true - pre_build_image: true -lint: yamllint . -provisioner: - name: ansible - playbooks: - converge: ../default/converge.yml diff --git a/templates/bind/named.conf.local.j2 b/templates/bind/named.conf.local.j2 index d5ecb61..a2d5ebb 100644 --- a/templates/bind/named.conf.local.j2 +++ b/templates/bind/named.conf.local.j2 @@ -14,7 +14,7 @@ statistics-channels { {% if bind9_masters|default() %} // masters for zones and allow-notify {% for master in bind9_masters %} -masters "{{ master.name }}" { +masters {{ master.name }} { {% for addr in master.addresses %} {{ addr }}; {% endfor %} @@ -23,7 +23,7 @@ masters "{{ master.name }}" { {% endif %} {% if bind9_masters_extra|default() %} {% for master in bind9_masters_extra %} -masters "{{ master.name }}" { +masters {{ master.name }} { {% for addr in master.addresses %} {{ addr }}; {% endfor %} @@ -34,7 +34,7 @@ masters "{{ master.name }}" { // Custom acls {% for acl_item in bind9_acl %} -acl "{{ acl_item.name }}" { +acl {{ acl_item.name }} { {% for item_address in acl_item.addresses %} {{ item_address }}; {% endfor %} diff --git a/templates/strict_authoritative/bind/named.conf.local.j2 b/templates/strict_authoritative/bind/named.conf.local.j2 index 9fe1489..84b5fc9 100644 --- a/templates/strict_authoritative/bind/named.conf.local.j2 +++ b/templates/strict_authoritative/bind/named.conf.local.j2 @@ -14,8 +14,8 @@ statistics-channels { {% endif %} {% if bind9_masters is defined or bind9_masters_extra is defined %} -// masters clause lists for masters secondary zones and also-notify statements -// and ACLs with same name and content, to be used in allow-transfer statements +// masters lists for masters' secondary zones and also-notify statements +// and ACLs with same name and content, to be used in allow-transfer clauses {% for master in bind9_masters | default ([]) + bind9_masters_extra | default ([]) %} masters {{ master.name }} { {% for addr in master.addresses %} @@ -97,7 +97,7 @@ zone "{{ zone.name }}" { {% set zone_also_allow_transfer = zone.also_allow_transfer | default( bind9_also_allow_transfer | default( [] ) ) %} {# ############################### Primary zones must consider secundaries ########################################### #} {% if zone_type == 'master' %} -{% set zone_calc_allow_transfer = zone.slaves | default( bind9_slaves | default( [] ) ) | union( zone_also_notify | union ( zone_also_allow_transfer ) ) %} +{% set zone_calc_allow_transfer = zone.q | default( bind9_slaves | default( [] ) ) | union( zone_also_notify | union ( zone_also_allow_transfer ) ) %} {% else %} {% set zone_calc_allow_transfer = zone_also_notify | union( zone_also_allow_transfer ) %} {% endif %} From b0aba0fb25a17cb11b844247d02222e1d97b29c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vi=C3=B1ar=20Ulriksen?= Date: Thu, 11 Aug 2022 19:39:16 -0300 Subject: [PATCH 15/15] README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c57f9d..2cc8728 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,9 @@ Explicitely, you can use the following variables to configure your NS server and - IPv4_1 - IPv6_1 ``` - With these lists the template builds the [primaries' or masters' list(s)](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) 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 other masters' lists names or individual IPs. IPv4 or IPv6, but not network IPs range, ending with a / and a mask length. + With these lists the template builds the [primaries' or masters' list(s)](https://bind9.readthedocs.io/en/latest/reference.html?highlight=primaries%20list#primaries-statement-grammar) 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 of `bind9_masters` the templates build, moreover the primaries' list, an [Access Control List (ACL)](https://bind9.readthedocs.io/en/latest/chapter6.html#access-control-lists) 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` or `also-notify` statements of a zone, but also in [the variables that define] statements which work with ACLs, such as `allow-transfer` or `allow-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.