From ae42f963a2f8cc9582843d9067f234c51c65ecb6 Mon Sep 17 00:00:00 2001 From: Felix Stupp Date: Sun, 14 Jun 2020 16:04:17 +0200 Subject: [PATCH] dns: Transfered master zones from makefile approach to dynamic updates approach --- group_vars/all/vars.yml | 3 +- playbooks/dns.yml | 67 +++++++++++-------- roles/dns/application/defaults/main.yml | 4 -- roles/dns/application/handlers/main.yml | 5 -- roles/dns/application/tasks/main.yml | 24 ------- .../application/templates/aa-profile.local | 10 --- .../dns/application/templates/zones.makefile | 11 --- roles/dns/entries/defaults/main.yml | 7 +- roles/dns/entries/tasks/main.yml | 49 ++++++++------ roles/dns/entries/vars/main.yml | 3 - roles/dns/handlers/handlers/main.yml | 7 -- roles/dns/master/defaults/main.yml | 5 +- roles/dns/master/tasks/main.yml | 35 ++++++---- roles/dns/master/templates/zone.conf | 5 ++ roles/dns/master/templates/zone.db | 7 +- roles/dns/master/vars/main.yml | 3 - roles/dns/server_entries/defaults/main.yml | 19 +++--- 17 files changed, 120 insertions(+), 144 deletions(-) delete mode 100644 roles/dns/application/handlers/main.yml delete mode 100644 roles/dns/application/templates/aa-profile.local delete mode 100644 roles/dns/application/templates/zones.makefile delete mode 100644 roles/dns/entries/vars/main.yml delete mode 100644 roles/dns/master/vars/main.yml diff --git a/group_vars/all/vars.yml b/group_vars/all/vars.yml index 5333be2..b8db4f1 100644 --- a/group_vars/all/vars.yml +++ b/group_vars/all/vars.yml @@ -36,6 +36,7 @@ global_credentials_directory: "credentials" global_public_key_directory: "public_keys" global_dns_list_directory: "{{ global_public_key_directory }}/dns" +global_dns_changes_directory: "{{ global_public_key_directory }}/dns_changes" # TODO merge with global_dns_list_directory global_dns_session_key_name: "local-ddns" global_dns_session_key_path: "/var/run/named/session.key" global_dns_session_key_algorithm: "hmac-sha512" @@ -79,7 +80,7 @@ global_apt_sources_directory: "/etc/apt/sources.list.d" global_bind_service_name: "named.service" global_bind_configuration_directory: "/etc/bind" -global_dns_zones_environment_directory: "{{ global_configuration_environment_directory }}/dns-zones" +global_bind_data_directory: "/var/lib/bind" global_dns_upstream_servers: - "9.9.9.11" diff --git a/playbooks/dns.yml b/playbooks/dns.yml index 4ebc3ea..ce947e5 100644 --- a/playbooks/dns.yml +++ b/playbooks/dns.yml @@ -4,35 +4,48 @@ nvak_dns_slaves: [] roles: - role: dns/master - domain: banananet.work - main_nameserver_domain: ns1.banananet.work - responsible_mail_name: admin.banananet.work - slaves: "{{ nvak_dns_slaves }}" - entries: | - ; Name Servers - @ IN NS ns1 - ns1 IN A {{ ansible_default_ipv4.address }} - ns1 IN AAAA {{ ansible_default_ipv6.address }} - ; Public use domains - _minecraft._tcp.wg IN SRV 10 10 25565 mc.wg - mc.wg IN A 85.131.171.106 - _minecraft._tcp.mc.wg IN SRV 10 10 25565 mc.wg + vars: + domain: banananet.work + responsible_mail_name: admin.banananet.work + slaves: "{{ nvak_dns_slaves }}" + entries: + # limit CA + - type: CAA + data: 0 issue "letsencrypt.org" + # other entries + - domain: mc.wg + type: A + data: 85.131.171.106 + - domain: _minecraft._tcp.wg + type: SRV + data: 10 10 25565 mc.wg + - domain: _minecraft._tcp.mc.wg + type: SRV + data: 10 10 25565 mc.wg - role: dns/master - domain: forumderschan.de - main_nameserver_domain: ns1.banananet.work - responsible_mail_name: admin.banananet.work - slaves: "{{ nvak_dns_slaves }}" - entries: | - ; Name Servers - @ IN NS ns1.banananet.work. + vars: + domain: forumderschan.de + responsible_mail_name: admin.banananet.work + slaves: "{{ nvak_dns_slaves }}" + entries: + # Glue record + - type: NS + data: ns1.banananet.work. + # limit CA + - type: CAA + data: 0 issue "letsencrypt.org" - role: dns/master - domain: stadtpiraten-karlsruhe.de - main_nameserver_domain: ns1.banananet.work - responsible_mail_name: admin.banananet.work - slaves: "{{ nvak_dns_slaves }}" - entries: | - ; Name Servers - @ IN NS ns1.banananet.work. + vars: + domain: stadtpiraten-karlsruhe.de + responsible_mail_name: admin.banananet.work + slaves: "{{ nvak_dns_slaves }}" + entries: + # Glue record + - type: NS + data: ns1.banananet.work. + # limit CA + - type: CAA + data: 0 issue "letsencrypt.org" - name: Add public available hosts to dns zones hosts: public_available diff --git a/roles/dns/application/defaults/main.yml b/roles/dns/application/defaults/main.yml index 7a049d6..0cf46e0 100644 --- a/roles/dns/application/defaults/main.yml +++ b/roles/dns/application/defaults/main.yml @@ -5,10 +5,6 @@ options_configuration: "{{ global_bind_configuration_directory }}/named.conf.opt zones_configuration: "{{ global_bind_configuration_directory }}/named.conf.local" zones_directory: "{{ global_bind_configuration_directory }}/zones" -zones_environment_link_name: "conf" -zones_environment_link: "{{ global_dns_zones_environment_directory }}/{{ zones_environment_link_name }}" -zones_environment_database_name: "zone.db" - apparmor_profile_name: "usr.sbin.named" apparmor_profile: "{{ global_apparmor_profiles_directory }}/{{ apparmor_profile_name }}" apparmor_profile_local: "{{ global_apparmor_profiles_local_directory }}/{{ apparmor_profile_name }}" diff --git a/roles/dns/application/handlers/main.yml b/roles/dns/application/handlers/main.yml deleted file mode 100644 index a18bb8d..0000000 --- a/roles/dns/application/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: reload apparmor profile - command: "/usr/sbin/apparmor_parser -r {{ apparmor_profile }}" - notify: restart bind9 diff --git a/roles/dns/application/tasks/main.yml b/roles/dns/application/tasks/main.yml index 436b663..93c8a3a 100644 --- a/roles/dns/application/tasks/main.yml +++ b/roles/dns/application/tasks/main.yml @@ -28,21 +28,6 @@ mode: u=rwx,g=rx,o= loop: - "{{ zones_directory }}" - - "{{ global_dns_zones_environment_directory }}" - -- name: Upload makefile to domain zones configuration environment - template: - src: zones.makefile - dest: "{{ global_dns_zones_environment_directory }}/makefile" - owner: root - group: root - mode: u=rw,g=r,o=r - -- name: Create link in domain zone configuration environment - file: - state: link - src: "{{ zones_directory }}" - dest: "{{ zones_environment_link }}" - name: Configure bind9 options template: @@ -53,15 +38,6 @@ mode: "u=rw,g=r,o=r" notify: reload bind9 -- name: Allow bind using apparmor to write zone files - template: - src: aa-profile.local - dest: "{{ apparmor_profile_local }}" - owner: root - group: root - mode: "u=rw,g=r,o=" - notify: reload apparmor profile - - name: Enable bind9 service systemd: name: "{{ global_bind_service_name }}" diff --git a/roles/dns/application/templates/aa-profile.local b/roles/dns/application/templates/aa-profile.local deleted file mode 100644 index 49c6919..0000000 --- a/roles/dns/application/templates/aa-profile.local +++ /dev/null @@ -1,10 +0,0 @@ -{{ zones_directory }}/* rw, -{{ zones_directory }}/*/tmp-* rwk, -# Journal files required by Bind to save temporary changes -{{ zones_directory }}/*/zone.db.jbk rwk, -{{ zones_directory }}/*/zone.db.jnl rwk, -{{ zones_directory }}/*/zone.db.jnw rwk, -{{ zones_directory }}/*/zone.db.signed rwk, -{{ zones_directory }}/*/zone.db.signed.jbk rwk, -{{ zones_directory }}/*/zone.db.signed.jnl rwk, -{{ zones_directory }}/*/zone.db.signed.jnw rwk, diff --git a/roles/dns/application/templates/zones.makefile b/roles/dns/application/templates/zones.makefile deleted file mode 100644 index 767f637..0000000 --- a/roles/dns/application/templates/zones.makefile +++ /dev/null @@ -1,11 +0,0 @@ -dest:={{ zones_environment_link_name }} -db_name:={{ zones_environment_database_name }} - -zone_dirs:=$(wildcard *.*/) -zones:=$(zone_dirs:/=) - -.PHONY: all -all: $(addprefix ${dest}/,$(addsuffix /${db_name},${zones})) - -${dest}/%/${db_name}: %/*.db - cat $(sort $^) | sed '0,/^ 0$$/s// '"$$(($$(date +%s) / 60))"'/' > "$@"; diff --git a/roles/dns/entries/defaults/main.yml b/roles/dns/entries/defaults/main.yml index 2010e4d..333c218 100644 --- a/roles/dns/entries/defaults/main.yml +++ b/roles/dns/entries/defaults/main.yml @@ -5,7 +5,10 @@ dns_zone_domain: "{{ lookup('pipe', global_public_key_directory|quote + '/dns_zo dns_system_domain: "{{ lookup('file', global_dns_list_directory + '/' + dns_zone_domain) }}" # domain of dns authority server entries_name: "server:{{ domain }}" # Name for zone part file +local_file: "{{ global_dns_changes_directory }}/{{ entries_name }}" -domain_zone_file: "{{ domain_environment_directory }}/{{ entries_name }}.db" +ttl_default: "{{ global_dns_ttl }}" # TTL for all entries where none was given -# entries (in bind zone file format) +# entries (example: [{domain: "example.com.", ttl: 86400, class: "IN", type: "A", data: "0.0.0.0"},"example.com. IN AAAA ::",…], type/data or raw required) +entries_delete: yes # delete similar records as given before +entries_delete_all_types: no # For all given domains delete all records, not just of the types set diff --git a/roles/dns/entries/tasks/main.yml b/roles/dns/entries/tasks/main.yml index ac09fc4..876409c 100644 --- a/roles/dns/entries/tasks/main.yml +++ b/roles/dns/entries/tasks/main.yml @@ -1,25 +1,34 @@ --- -- name: Store dns entries at dns host +- name: Store changes in dns entries locally copy: - content: "{{ entries }}" - dest: "{{ domain_zone_file }}" - owner: root - group: root - mode: u=rw,g=r,o= - register: result_store_entries - delegate_to: "{{ dns_system_domain }}" - -- name: Rebuild zone files - make: - chdir: "{{ global_dns_zones_environment_directory }}" - when: result_store_entries.changed - register: result_rebuild_zone - delegate_to: "{{ dns_system_domain }}" + content: | + #jinja2:trim_blocks: False + zone {{ dns_zone_domain }}. + ttl {{ ttl_default }} + {%- if entries_delete %}{% for entry in entries %}{% if entry|mapping %} + update delete {{ entry.domain | default('@') | domain_relative_to(domain) }} 0 {{ entry.class | default('IN') }}{% if not entries_delete_all_types %} {{ entry.type }}{% endif %} + {%- endif %}{% endfor %}{% endif %} + {% for entry in entries %}{% if entry|mapping -%} + update add {{ entry.domain | default('@') | domain_relative_to(domain) }} {{ entry.ttl | default(ttl_default) }} {{ entry.class | default('IN') }} {{ entry.type }} {{ entry.data }} + {% else -%} + {% if not entry|regex_search('^(update )?(add|del(ete)?) ') %}update add {% endif %}{{ entry }} + {% endif %}{% endfor %} + send + dest: "{{ local_file }}" + owner: "{{ global_local_user }}" + group: "{{ global_local_user }}" + mode: u=rw,g=r,o=r + delegate_to: localhost + register: entries_changes_file + tags: + - dns_entries -- name: Reload bind9 - systemd: - name: "{{ global_bind_service_name }}" - state: reloaded - when: result_rebuild_zone.changed +- name: Update dns entries at dns host + command: + cmd: nsupdate -l # local mode + stdin: "{{ lookup('file', local_file) }}\n" delegate_to: "{{ dns_system_domain }}" + when: entries_changes_file.changed + tags: + - dns_entries diff --git a/roles/dns/entries/vars/main.yml b/roles/dns/entries/vars/main.yml deleted file mode 100644 index c0338c2..0000000 --- a/roles/dns/entries/vars/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -domain_environment_directory: "{{ global_dns_zones_environment_directory }}/{{ dns_zone_domain }}" # Given by dns/master diff --git a/roles/dns/handlers/handlers/main.yml b/roles/dns/handlers/handlers/main.yml index 127f759..3dc3e60 100644 --- a/roles/dns/handlers/handlers/main.yml +++ b/roles/dns/handlers/handlers/main.yml @@ -5,14 +5,7 @@ name: "{{ global_bind_service_name }}" state: restarted -# SYNC following with handlers of role dns/server_entries - - name: reload bind9 systemd: name: "{{ global_bind_service_name }}" state: reloaded - -- name: rebuild dns zones - make: - chdir: "{{ global_dns_zones_environment_directory }}" - notify: reload bind9 diff --git a/roles/dns/master/defaults/main.yml b/roles/dns/master/defaults/main.yml index cd0e5d1..c1e8971 100644 --- a/roles/dns/master/defaults/main.yml +++ b/roles/dns/master/defaults/main.yml @@ -4,8 +4,9 @@ domain_directory: "{{ zones_directory }}/{{ domain }}" configuration_file: "{{ domain_directory }}/zone.conf" -database_file: "{{ domain_directory }}/{{ zones_environment_database_name }}" -keys_directory: "{{ domain_directory }}/keys" +data_directory: "{{ global_bind_data_directory }}/{{ domain }}" +database_file: "{{ data_directory }}/zone.db" +keys_directory: "{{ data_directory }}/keys" dns_list_file: "{{ global_dns_list_directory }}/{{ domain }}" diff --git a/roles/dns/master/tasks/main.yml b/roles/dns/master/tasks/main.yml index d65c3c1..6b8bbbd 100644 --- a/roles/dns/master/tasks/main.yml +++ b/roles/dns/master/tasks/main.yml @@ -9,41 +9,42 @@ mode: "u=rw,g=r,o=" delegate_to: localhost -- name: Create zone directory writeable for bind +- name: Create zone directory file: path: "{{ domain_directory }}" state: directory - owner: "{{ dns_user }}" + owner: root group: "{{ dns_user }}" mode: u=rwx,g=rx,o= -- name: Create key directory +- name: Create data directory file: - path: "{{ keys_directory }}" + path: "{{ data_directory }}" state: directory owner: "{{ dns_user }}" group: "{{ dns_user }}" mode: u=rwx,g=rx,o= -- name: Create domain environment directory +- name: Create key directory file: - path: "{{ domain_environment_directory }}" + path: "{{ keys_directory }}" state: directory - owner: root - group: root + owner: "{{ dns_user }}" + group: "{{ dns_user }}" mode: u=rwx,g=rx,o= # TODO Copy public ZSK to localhost -- name: Store main database of zone {{ domain }} +- name: Store database of zone {{ domain }} template: src: zone.db - dest: "{{ domain_environment_directory }}/0_main.db" - owner: root - group: root + dest: "{{ database_file }}" + owner: "{{ dns_user }}" + group: "{{ dns_user }}" mode: u=rw,g=r,o= + force: no # Do not override dynamic changes validate: "named-checkzone {{ domain }} %s" - notify: rebuild dns zones + notify: reload bind9 - name: Configure zone {{ domain }} template: @@ -64,3 +65,11 @@ notify: reload bind9 - meta: flush_handlers + +- name: Configure additional records + import_role: + name: dns/entries + vars: + entries_name: "initial:{{ domain }}" + # domain + # entries diff --git a/roles/dns/master/templates/zone.conf b/roles/dns/master/templates/zone.conf index 3f49024..e4fa195 100644 --- a/roles/dns/master/templates/zone.conf +++ b/roles/dns/master/templates/zone.conf @@ -22,6 +22,11 @@ zone "{{ domain }}" { // dnssec inline-signing yes; dnssec-policy "{{ domain }}-policy"; + // dynamic updates + update-policy { + grant local-ddns zonesub any; + grant * selfsub .; + }; // notify & transfer notify yes; allow-transfer { diff --git a/roles/dns/master/templates/zone.db b/roles/dns/master/templates/zone.db index f33046c..dc09241 100644 --- a/roles/dns/master/templates/zone.db +++ b/roles/dns/master/templates/zone.db @@ -7,11 +7,10 @@ $TTL {{ ttl_default }} {{ ttl }} ) -; Certification Authority Authorization -@ IN CAA 0 issue "letsencrypt.org" +@ IN NS {{ main_nameserver_domain }}. +{{ main_nameserver_domain }}. IN A {{ ansible_default_ipv4.address }} +{{ main_nameserver_domain }}. IN AAAA {{ ansible_default_ipv6.address }} {% if dname_subdomain | length > 0 %} {{ dname_subdomain }} IN DNAME @ {% endif %} - -{{ entries }} diff --git a/roles/dns/master/vars/main.yml b/roles/dns/master/vars/main.yml deleted file mode 100644 index 5c10c74..0000000 --- a/roles/dns/master/vars/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -domain_environment_directory: "{{ global_dns_zones_environment_directory }}/{{ domain }}" # Fixed for usage in other roles diff --git a/roles/dns/server_entries/defaults/main.yml b/roles/dns/server_entries/defaults/main.yml index 76437f1..1620710 100644 --- a/roles/dns/server_entries/defaults/main.yml +++ b/roles/dns/server_entries/defaults/main.yml @@ -3,11 +3,14 @@ # domain (of service running) service_system_domain: "{{ inventory_hostname }}" # domain of server running the service -entries: | - {{ ip_entries }} - {{ custom_entries }} -ip_entries: | - {{ domain }}. IN A {{ hostvars[service_system_domain].ansible_default_ipv4.address }} - {{ domain }}. IN AAAA {{ hostvars[service_system_domain].ansible_default_ipv6.address }} - {{ lookup('pipe', global_public_key_directory|quote + '/ssh_dns_fp.py --host ' + service_system_domain|quote + ' --domain ' + domain|quote) }} -custom_entries: "" +entries: "{{ ip_entries + sshfp_entries + custom_entries }}" +ip_entries: + - update delete {{ domain }}. IN SSHFP # delete all SSHFP records for this host before + - domain: "{{ domain }}." + type: "A" + data: "{{ hostvars[service_system_domain].ansible_default_ipv4.address }}" + - domain: "{{ domain }}." + type: "AAAA" + data: "{{ hostvars[service_system_domain].ansible_default_ipv6.address }}" +sshfp_entries: "{{ (lookup('pipe', global_public_key_directory|quote + '/ssh_dns_fp.py --host ' + service_system_domain|quote + ' --domain ' + domain|quote)).split('\n') }}" +custom_entries: []