From 36dc7429a37927b71652a3bb6d4ce32ff46d1f55 Mon Sep 17 00:00:00 2001 From: esum & shirenn Date: Mon, 6 Jun 2022 21:59:11 +0200 Subject: [PATCH] [bind9] At last usable ! --- group_vars/dns_authoritative.yml | 24 +++ host_vars/silice.adm.crans.org.yml | 26 +++ host_vars/sputnik.adm.crans.org.yml | 5 + hosts | 7 +- plays/dns-authoritative.yml | 17 +- roles/bind-authoritative/handlers/main.yml | 2 +- roles/bind-authoritative/tasks/dnssec.yml | 4 - roles/bind-authoritative/tasks/main.yml | 12 +- .../templates/bind/named.conf.key.j2 | 9 ++ .../templates/bind/named.conf.local.j2 | 149 +++--------------- .../templates/bind/named.conf.options.j2 | 18 +-- .../templates/update-motd.d/05-service.j2 | 6 +- 12 files changed, 99 insertions(+), 180 deletions(-) create mode 100644 group_vars/dns_authoritative.yml delete mode 100644 roles/bind-authoritative/tasks/dnssec.yml create mode 100644 roles/bind-authoritative/templates/bind/named.conf.key.j2 diff --git a/group_vars/dns_authoritative.yml b/group_vars/dns_authoritative.yml new file mode 100644 index 00000000..42248b65 --- /dev/null +++ b/group_vars/dns_authoritative.yml @@ -0,0 +1,24 @@ +--- +glob_bind: + default: + format: 'bak.%s' + zones: + '_acme-challenge.crans.org': + '_acme-challenge.adm.crans.org': + 'adh.crans.org': {} + 'adm.crans.org': {} + 'cachan-adm.crans.org': {} + 'crans.eu': {} + 'crans.fr': {} + 'crans.org': {} + 'lists.crans.org': {} + 'san.crans.org': {} + 'renater.crans.org': {} + 'ens.crans.org': {} + 'lp.crans.org': {} + 'admissibles.crans.org': {} + '76.230.185.in-addr.arpa': {} + '77.230.185.in-addr.arpa': {} + '78.230.185.in-addr.arpa': {} + '79.230.185.in-addr.arpa': {} + '0.0.7.0.c.0.a.2.ip6.arpa': {} diff --git a/host_vars/silice.adm.crans.org.yml b/host_vars/silice.adm.crans.org.yml index 736408c8..deb491cf 100644 --- a/host_vars/silice.adm.crans.org.yml +++ b/host_vars/silice.adm.crans.org.yml @@ -2,3 +2,29 @@ interfaces: adm: eth1 srv: eth0 + +loc_bind: + options: + secondaries: "{{ query('ldap', 'ip', 'sputnik', 'adm') }}" + key_directory: "/var/cache/bind/keys" + default: + format: 'generated/%s.db' + type: primary + notify: 'yes' + dnssec: true + zones: + '_acme-challenge.crans.org': + update_policy: + - 'grant certbot_challenge. name _acme-challenge.crans.org. txt' + format: 'bak.%s' + '_acme-challenge.adm.crans.org': + update_policy: + - 'grant certbot_adm_challenge. name _acme-challenge.adm.crans.org. txt' + format: 'bak.%s' + rfc2136_keys: + 'certbot_challenge.': + algorithm: hmac-sha512 + secret: "{{ vault.bind.rfc2136_keys['certbot_challenge.'].secret }}" + 'certbot_adm_challenge.': + algorithm: hmac-sha512 + secret: "{{ vault.bind.rfc2136_keys['certbot_adm_challenge.'].secret }}" diff --git a/host_vars/sputnik.adm.crans.org.yml b/host_vars/sputnik.adm.crans.org.yml index 0214a0f9..f9bd8666 100644 --- a/host_vars/sputnik.adm.crans.org.yml +++ b/host_vars/sputnik.adm.crans.org.yml @@ -111,3 +111,8 @@ loc_reverseproxy: redirect_sites: [] static_sites: [] + +loc_bind: + default: + type: slave + primaries: "{{ query('ldap', 'ip', 'silice', 'adm') }}" diff --git a/hosts b/hosts index e5d3aa92..6e630f60 100644 --- a/hosts +++ b/hosts @@ -55,12 +55,9 @@ gitlab_runner [django_cas] cas.adm.crans.org -[dns_auth_master] +[dns_authoritative] silice.adm.crans.org - -[dns_authoritative:children] -dns_auth_master -ovh_physical +sputnik.adm.crans.org [dns_recursive:children] routeurs_vm diff --git a/plays/dns-authoritative.yml b/plays/dns-authoritative.yml index 928a751e..8996f396 100755 --- a/plays/dns-authoritative.yml +++ b/plays/dns-authoritative.yml @@ -3,21 +3,6 @@ # Deploy authoritative DNS server - hosts: dns_authoritative vars: - certbot_dns_secret: "{{ vault.certbot_dns_secret }}" - certbot_adm_dns_secret: "{{ vault.certbot_adm_dns_secret }}" - bind: - masters: "{{ query('ldap', 'role', 'dns-primary') }}" - slaves: "{{ query('ldap', 'role', 'dns-secondary') }}" - zones: "{{ (lookup('re2oapi', 'dnszones') + query('ldap', 'zones')) | unique }}" - reverse: "{{ lookup('re2oapi', 'dnsreverse') }}" + bind: '{{ glob_bind | default({}) | combine(loc_bind | default({}), recursive=True) }}' roles: - bind-authoritative - -- hosts: dns_auth_master - vars: - re2o: - server: re2o.adm.crans.org - service_user: "{{ vault.re2o_service_user }}" - service_password: "{{ vault.re2o_service_password }}" - roles: - - dns diff --git a/roles/bind-authoritative/handlers/main.yml b/roles/bind-authoritative/handlers/main.yml index 0f5025c5..ce766928 100644 --- a/roles/bind-authoritative/handlers/main.yml +++ b/roles/bind-authoritative/handlers/main.yml @@ -1,5 +1,5 @@ --- -- name: Reload Bind9 +- name: systemctl reload bind9.service systemd: name: bind9 state: reloaded diff --git a/roles/bind-authoritative/tasks/dnssec.yml b/roles/bind-authoritative/tasks/dnssec.yml deleted file mode 100644 index f01f4353..00000000 --- a/roles/bind-authoritative/tasks/dnssec.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- name: TODO - debug: - msg: "Hey some work is being done here!" diff --git a/roles/bind-authoritative/tasks/main.yml b/roles/bind-authoritative/tasks/main.yml index 1c6daf7f..649d8415 100644 --- a/roles/bind-authoritative/tasks/main.yml +++ b/roles/bind-authoritative/tasks/main.yml @@ -7,11 +7,6 @@ retries: 3 until: apt_result is succeeded -- name: Is this the master? - set_fact: - is_master: "{{ ansible_hostname in query('ldap', 'role', 'dns-primary') }}" - cacheable: true - - name: Deploy Bind9 configuration template: src: bind/{{ item }}.j2 @@ -22,11 +17,10 @@ loop: - named.conf - named.conf.local + - named.conf.key - named.conf.options - notify: Reload Bind9 - -- include_tasks: dnssec.yml - when: is_master + when: item != "named.conf.key" or bind.rfc2136_keys is defined + notify: systemctl reload bind9.service - name: Indicate role in motd template: diff --git a/roles/bind-authoritative/templates/bind/named.conf.key.j2 b/roles/bind-authoritative/templates/bind/named.conf.key.j2 new file mode 100644 index 00000000..6d16ebeb --- /dev/null +++ b/roles/bind-authoritative/templates/bind/named.conf.key.j2 @@ -0,0 +1,9 @@ +{{ ansible_header | comment(decoration='// ') }} + +// Let's Encrypt Challenge DNS-01 key +{% for keyname,key in bind.rfc2136_keys.items() %} +key "{{ keyname }}" { + algorithm {{ key.algorithm }}; + secret "{{ key.secret }}"; +}; +{% endfor %} diff --git a/roles/bind-authoritative/templates/bind/named.conf.local.j2 b/roles/bind-authoritative/templates/bind/named.conf.local.j2 index a91863c7..ccb3e1fd 100644 --- a/roles/bind-authoritative/templates/bind/named.conf.local.j2 +++ b/roles/bind-authoritative/templates/bind/named.conf.local.j2 @@ -3,148 +3,35 @@ // Consider adding the 1918 zones here, if they are not used in your // organization //include "/etc/bind/zones.rfc1918"; +{% if bind.rfc2136_keys is defined %} -{% if is_master -%} -// Let's Encrypt Challenge DNS-01 key -key "certbot_challenge." { - algorithm hmac-sha512; - secret "{{ certbot_dns_secret }}"; -}; -key "certbot_adm_challenge." { - algorithm hmac-sha512; - secret "{{ certbot_adm_dns_secret }}"; -}; +include "/etc/bind/named.conf.key"; {% endif %} -// Let's Encrypt Challenge DNS-01 zone -zone "_acme-challenge.crans.org" { -{% if is_master %} - type master; - notify yes; +{% for zonename,zone in bind.zones.items() %} +zone "{{ zonename }}" { +{% set zone = bind.default | combine(zone) %} + type {{ zone.type | default('primary') }}; +{% if zone.update_policy is defined %} update-policy { - grant certbot_challenge. name _acme-challenge.crans.org. txt; - }; -{% else %} - type slave; - masters { -{% for host in bind.masters %} -{% for ip in query('ldap', 'ip', host, 'adm') %} - {{ ip }}; -{% endfor -%} +{% for policy in zone.update_policy %} + {{ policy }}; {% endfor %} }; - notify no; {% endif %} - file "bak._acme-challenge.crans.org"; -}; - -// Let's Encrypt Challenge DNS-01 zone -zone "_acme-challenge.adm.crans.org" { -{% if is_master %} - type master; - notify yes; - update-policy { - grant certbot_adm_challenge. name _acme-challenge.adm.crans.org. txt; - }; -{% else %} - type slave; + file "{{ zone.format | default('') | format(zonename) }}"; +{% if zone.primaries is defined and zone.primaries != False %} masters { -{% for host in bind.masters %} -{% for ip in query('ldap', 'ip', host, 'adm') %} - {{ ip }}; -{% endfor -%} +{% for primary in zone.primaries %} + {{ primary }}; {% endfor %} }; - notify no; {% endif %} - file "bak._acme-challenge.adm.crans.org"; -}; - -zone "_acme-challenge.crans.fr" { -{% if is_master %} - type master; - notify yes; - update-policy { - grant certbot_challenge. name _acme-challenge.crans.fr. txt; - }; -{% else %} - type slave; - masters { -{% for host in bind.masters %} -{% for ip in query('ldap', 'ip', host, 'adm') %} - {{ ip }}; -{% endfor -%} -{% endfor %} - }; - notify no; -{% endif %} - file "bak._acme-challenge.crans.fr"; -}; - -zone "_acme-challenge.crans.eu" { -{% if is_master %} - type master; - notify yes; - update-policy { - grant certbot_challenge. name _acme-challenge.crans.eu. txt; - }; -{% else %} - type slave; - masters { -{% for host in bind.masters %} -{% for ip in query('ldap', 'ip', host, 'adm') %} - {{ ip }}; -{% endfor -%} -{% endfor %} - }; - notify no; -{% endif %} - file "bak._acme-challenge.crans.eu"; -}; - -// Crans zones -{% for zone in bind.zones|sort %} -zone "{{ zone }}" { -{% if is_master %} - type master; - // Apparmor: Need to ln -s /var/cache/bind/generated /var/local/re2o-services/dns/generated - file "generated/{{ zone }}.db"; - notify yes; -{% else %} - type slave; - file "bak.{{ zone }}"; - masters { -{% for host in bind.masters %} -{% for ip in query('ldap', 'ip', host, 'adm') %} - {{ ip }}; -{% endfor -%} -{% endfor %} - }; - notify no; -{% endif %} -}; - -{% endfor %} - -// Crans reverse zones -{% for zone in bind.reverse %} -zone "{{ zone }}" { -{% if is_master %} - type master; - // Apparmor: Need to ln -s /var/cache/bind/generated /var/local/re2o-services/dns/generated - file "generated/{{ zone }}.db"; - notify yes; -{% else %} - type slave; - file "bak.{{ zone }}"; - masters { -{% for host in bind.masters %} -{% for ip in query('ldap', 'ip', host, 'adm') %} - {{ ip }}; -{% endfor -%} -{% endfor %} - }; - notify no; + notify {{ zone.notify | default('no') }}; +{% if zone.dnssec is defined and zone.dnssec %} + inline-signing yes; + auto-dnssec maintain; + serial-update-method increment; {% endif %} }; diff --git a/roles/bind-authoritative/templates/bind/named.conf.options.j2 b/roles/bind-authoritative/templates/bind/named.conf.options.j2 index f76d7e20..f972196b 100644 --- a/roles/bind-authoritative/templates/bind/named.conf.options.j2 +++ b/roles/bind-authoritative/templates/bind/named.conf.options.j2 @@ -2,6 +2,10 @@ options { directory "/var/cache/bind"; +{% if bind.options.key_directory is defined %} + + key-directory "{{ bind.options.key_directory }}"; +{% endif %} // If there is a firewall between you and nameservers you want // to talk to, you may need to fix the firewall to allow multiple @@ -30,20 +34,16 @@ options { // Hide version from clients version "not currently available"; -{% if is_master %} +{% if bind.options.secondaries is defined %} allow-transfer { -{% for host in bind.slaves %} -{% for ip in query('ldap', 'ip', host, 'adm') %} - {{ ip }}; -{% endfor %} +{% for host in bind.options.secondaries %} + {{ host }}; {% endfor %} }; also-notify { -{% for host in bind.slaves %} -{% for ip in query('ldap', 'ip', host, 'adm') %} - {{ ip }}; -{% endfor %} +{% for host in bind.options.secondaries %} + {{ host }}; {% endfor %} }; {% else %} diff --git a/roles/bind-authoritative/templates/update-motd.d/05-service.j2 b/roles/bind-authoritative/templates/update-motd.d/05-service.j2 index 39aab850..e36d04f5 100755 --- a/roles/bind-authoritative/templates/update-motd.d/05-service.j2 +++ b/roles/bind-authoritative/templates/update-motd.d/05-service.j2 @@ -1,7 +1,3 @@ #!/usr/bin/tail +14 {{ ansible_header | comment }} -{% if is_master %} -> Bind9 (autoritaire, maître) a été déployé sur cette machine. Voir /etc/bind/. -{% else %} -> Bind9 (autoritaire, esclave) a été déployé sur cette machine. Voir /etc/bind/. -{% endif %} +> Bind9 (authoritative) a été déployé sur cette machine. Voir /etc/bind/.