Skip to content
This repository has been archived by the owner on Dec 27, 2023. It is now read-only.

Feature issue5 - new set of templates, strict authoritative NS #6

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 174 additions & 14 deletions README.md

Large diffs are not rendered by default.

70 changes: 64 additions & 6 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ 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?
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
Expand All @@ -32,15 +35,23 @@ 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

## //!\\ 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)
# 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
Expand All @@ -49,21 +60,54 @@ 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
# 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
# - 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)
# 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_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
Expand All @@ -75,6 +119,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: []

Expand Down Expand Up @@ -113,7 +162,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/<my_host>/templates/"

Expand Down
16 changes: 14 additions & 2 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,26 @@
- 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:
paths: /etc/bind/keys
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)
Expand Down Expand Up @@ -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 }}"
Expand Down
66 changes: 48 additions & 18 deletions templates/bind/named.conf.local.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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 allow-notify
{% for master in bind9_masters %}
masters {{ master.name }} {
masters "{{ master.name }}" {
{% for addr in master.addresses %}
{{ addr }};
{% endfor %}
Expand All @@ -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 %}
ulvida marked this conversation as resolved.
Show resolved Hide resolved

{% 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 //
Expand All @@ -38,44 +49,63 @@ 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 is defined %}
allow-query {
{% for allow_query_item in zone.allow_query %}
{{ allow_query_item }};
{% endfor %}
};
{% endif %}
{% 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 %}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bind9_notify_explicit is a boolean that sets a forced value, not a default value as many other global variables. It must be documented for the default template. I don't understand the reason of this behavior, so in other templates we may change it, to manage a default value and not a forced value, with a bind9_notify, eventually distinguishing masters and slaves.

notify explicit;
{% elif zone.notify|default(true) %}
notify yes;
{% elif zone.notify | default(true) %}
notify {{ zone.notify | default(true) | ternary ('yes','no') }};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the order filters are applied: What about if zone.notify is set to explicit? I guess the value will fall to yes. the ternary should apply only if something clearly true or false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case, before proposing the PR I will bring back the default templates to their previous content.

{% endif %}
{% if (bind9_dnssec|default() or zone.dnssec|default()) and zone.dnssec|default(bind9_dnssec_zones_default_enabled) %}
{% 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 ) %}
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 %}
{% 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 %}
13 changes: 8 additions & 5 deletions templates/bind/named.conf.options.j2
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -12,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 %}

Expand Down Expand Up @@ -89,8 +92,8 @@ acl our_neighbors {
{% endfor %}
{% endif %}
};

{% if bind9_named_logging %}

logging {
channel bind_log {
file "{{ bind9_log_path }}/bind.log" versions {{ bind9_log_versions }} size {{ bind9_log_size }};
Expand All @@ -99,8 +102,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 %}
5 changes: 3 additions & 2 deletions templates/bind/zones/db.template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions templates/strict_authoritative/bind/default.j2
Loading