From 961a2f110511518c1e0ec2f96f2c78b9a6df430d Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 17 Aug 2022 19:00:07 +0200 Subject: [PATCH] Add knotd role --- roles/knotd/defaults/main.yml | 23 ++++++ roles/knotd/handlers/main.yml | 11 +++ roles/knotd/tasks/main.yml | 60 ++++++++++++++ roles/knotd/templates/knot.conf.j2 | 127 +++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+) create mode 100644 roles/knotd/defaults/main.yml create mode 100644 roles/knotd/handlers/main.yml create mode 100644 roles/knotd/tasks/main.yml create mode 100644 roles/knotd/templates/knot.conf.j2 diff --git a/roles/knotd/defaults/main.yml b/roles/knotd/defaults/main.yml new file mode 100644 index 0000000..37a901d --- /dev/null +++ b/roles/knotd/defaults/main.yml @@ -0,0 +1,23 @@ +--- +knotd__run_dir: /run/knot +knotd__user: knot +knotd__group: knot +knotd__listen: [] +knotd__port: 53 +knotd__database_dir: /var/lib/knot +knotd__keys: [] +knotd__remotes: [] +knotd__submissions: [] +knotd__policies: [] +knotd__reproducible_signing: true +knotd__nsec3: true +knotd__cds_cdnskey_publish: rollover +knotd__acl: [] +knotd__acl_update_owner: name +knotd__acl_update_owner_match: equal +knotd__zones_dir: "{{ knotd__database_dir }}/zones" +knotd__semantic_checks: true +knotd__serial_policy: increment +knotd__zones: [] +knotd__dnssec_validation: true +... diff --git a/roles/knotd/handlers/main.yml b/roles/knotd/handlers/main.yml new file mode 100644 index 0000000..ebad18e --- /dev/null +++ b/roles/knotd/handlers/main.yml @@ -0,0 +1,11 @@ +--- +- name: Restart knotd + systemd: + name: knot.service + state: restarted + +- name: Reload knotd + systemd: + name: knot.service + state: reloaded +... diff --git a/roles/knotd/tasks/main.yml b/roles/knotd/tasks/main.yml new file mode 100644 index 0000000..ce3da05 --- /dev/null +++ b/roles/knotd/tasks/main.yml @@ -0,0 +1,60 @@ +--- +- name: Install knotd and dnspython + apt: + name: + - knot + - python3-dnspython + +- name: Install config files + template: + src: knot.conf.j2 + dest: /etc/knot/knot.conf + owner: root + group: knot + mode: u=rw,g=r,o= + notify: + - Restart knotd + +- name: Create zones directory + file: + path: "{{ knotd__zones_dir }}" + state: directory + owner: root + group: "{{ knotd__group }}" + mode: u=rwx,g=rx,o= + +- name: Create zone files + dns_zone: + path: "{{ knotd__zones_dir }}/{{ item.key }}.zone" + owner: root + group: "{{ knotd__group }}" + mode: u=rw,g=r,o= + origin: "{{ item.key }}" + soa: "{{ item.value.soa }}" + hosts: "{{ item.value.hosts | default(omit) }}" + ns: "{{ item.value.ns | default(omit) }}" + mx: "{{ item.value.mx | default(omit) }}" + cname: "{{ item.value.cname | default(omit) }}" + txt: "{{ item.value.txt | default(omit) }}" + a: "{{ item.value.a | default(omit) }}" + aaaa: "{{ item.value.aaaa | default(omit) }}" + when: "item.value.master is not defined + and (item.value.enabled | default(true))" + loop: "{{ knotd__zones | dict2items }}" + notify: + - Reload knotd + +- name: Remove disabled zone files + file: + path: "{{ knotd__zones_dir }}/{{ item.key }}.zone" + state: absent + when: "item.value.master is not defined + and not (item.value.enabled | default(true))" + loop: "{{ knotd__zones | dict2items }}" + +- name: Enable and start knotd + systemd: + name: knot.service + enabled: true + state: started +... diff --git a/roles/knotd/templates/knot.conf.j2 b/roles/knotd/templates/knot.conf.j2 new file mode 100644 index 0000000..732b6c8 --- /dev/null +++ b/roles/knotd/templates/knot.conf.j2 @@ -0,0 +1,127 @@ +server: + rundir: "{{ knotd__run_dir }}" + user: {{ knotd__user }}:{{ knotd__group }} +{% for listen in knotd__listen %} + listen: {{ listen.address }}@{{ listen.port | default(knotd__port) }} +{% endfor %} + +log: + - target: syslog + any: info + +database: + storage: "{{ knotd__database_dir }}" + +{% if knotd__keys %} +key: +{% for id, key in knotd__keys.items() %} + - id: {{ id }} + algorithm: {{ key.algorithm }} + secret: {{ key.secret }} +{% endfor %} +{% endif %} + +{% if knotd__remotes %} +remote: +{% for id, remote in knotd__remotes.items() %} + - id: {{ id }} + address: {{ remote.address }} +{% if "key" in remote %} + key: {{ remote.key }} +{% endif %} +{% endfor %} +{% endif %} + +{% if knotd__submissions %} +submission: +{% for id, submission in knotd__submissions.items() %} + - id: {{ id }} + parent: {{ submission.parent }} +{% endfor %} +{% endif %} + +{% if knotd__policies %} +policy: +{% for id, policy in knotd__policies.items() %} + - id: {{ id }} + algorithm: {{ policy.algorithm }} +{% if policy.algorithm.startswith("ECDSA") %} + reproducible-signing: {{ policy.reproducible_signing + | default(knotd__reproducible_signing) + | ternary("on", "off") }} +{% endif %} + ksk-lifetime: {{ policy.ksk_lifetime }} + zsk-lifetime: {{ policy.zsk_lifetime }} + nsec3: {{ policy.nsec3 + | default(knotd__nsec3) + | ternary("on", "off") }} +{% if "ds_push" in policy %} + ds-push: {{ policy.ds_push }} +{% endif %} + cds-cdnskey-publish: {{ policy.cds_cdnskey_publish + | default(knotd__cds_cdnskey_publish) }} +{% if "ksk_submission" in policy %} + ksk-submission: {{ policy.ksk_submission }} +{% endif %} +{% endfor %} +{% endif %} + +{% if knotd__acl %} +acl: +{% for id, acl in knotd__acl.items() %} + - id: {{ id }} +{% if "addresses" in acl %} + address: [ {{ acl.addresses | join(", ") }} ] +{% endif %} + action: {{ acl.action }} +{% if acl.action == "update" %} + update-type: [ {{ acl.update_types | join(", ") }} ] + update-owner: {{ acl.update_owner + | default(knotd__acl_update_owner) }} + update-owner-match: {{ acl.update_owner_match + | default(knotd__acl_update_owner_match) }} + update-owner-name: [ {{ acl.update_owner_name | join(", ") }} ] +{% endif %} +{% if "key" in acl %} + key: {{ acl.key }} +{% endif %} +{% endfor %} +{% endif %} + +template: + - id: default + storage: "{{ knotd__zones_dir }}" + file: "%s.zone" + semantic-checks: {{ knotd__semantic_checks + | ternary("on", "off") }} + zonefile-sync: -1 + zonefile-load: difference-no-serial + journal-content: changes + journal-content: all + serial-policy: {{ knotd__serial_policy }} + +{% if knotd__zones %} +zone: +{% for domain, zone in knotd__zones.items() %} +{% if zone.enabled | default(true) %} + - domain: {{ domain }} +{% if "notify" in zone %} + notify: [ {{ zone.notify | join(", ") }} ] +{% endif %} +{% if "acl" in zone %} + acl: [ {{ zone.acl | join(", ") }} ] +{% endif %} +{% if "master" in zone %} + master: {{ zone.master }} +{% endif %} +{% if "dnssec_policy" in zone %} + dnssec-policy: {{ zone.dnssec_policy }} + dnssec-signing: on +{% else %} + dnssec-validation: {{ zone.dnssec_validation + | default(knotd__dnssec_validation) + | ternary("on", "off") }} +{% endif %} +{% endif %} +{% endfor %} +{% endif %}