From 30cd1289c0347860073392545dbc9840cfacdfb5 Mon Sep 17 00:00:00 2001
From: Ada <ada@gnous.eu>
Date: Thu, 18 Apr 2024 20:42:26 +0200
Subject: [PATCH] Add knot authoritative dns

---
 ansible/deploy.yml                            |  6 ++
 ansible/group_vars/dns-authoritative/all.yml  | 11 ++++
 ansible/group_vars/resolver/all.yml           |  5 ++
 ansible/hosts.yml                             |  5 ++
 ansible/roles/knot/files/zones/lab.r4.pm.zone | 12 ++++
 ansible/roles/knot/handlers/main.yml          | 15 +++++
 ansible/roles/knot/tasks/main.yml             | 58 +++++++++++++++++++
 ansible/roles/knot/templates/knot.conf.j2     | 32 ++++++++++
 ansible/roles/knot_resolver/tasks/main.yml    |  4 +-
 .../knot_resolver/templates/kresd.conf.j2     |  6 +-
 10 files changed, 151 insertions(+), 3 deletions(-)
 create mode 100644 ansible/group_vars/dns-authoritative/all.yml
 create mode 100644 ansible/roles/knot/files/zones/lab.r4.pm.zone
 create mode 100644 ansible/roles/knot/handlers/main.yml
 create mode 100644 ansible/roles/knot/tasks/main.yml
 create mode 100644 ansible/roles/knot/templates/knot.conf.j2

diff --git a/ansible/deploy.yml b/ansible/deploy.yml
index 7bf1932..cc09b0b 100644
--- a/ansible/deploy.yml
+++ b/ansible/deploy.yml
@@ -25,3 +25,9 @@
   become: true
   roles:
     - kea_dhcp
+
+- name: Knot
+  hosts: dns-authoritative
+  become: true
+  roles:
+    - knot
diff --git a/ansible/group_vars/dns-authoritative/all.yml b/ansible/group_vars/dns-authoritative/all.yml
new file mode 100644
index 0000000..7e1adfa
--- /dev/null
+++ b/ansible/group_vars/dns-authoritative/all.yml
@@ -0,0 +1,11 @@
+---
+acls:
+  - id: ddns
+    action: update
+    address: 10.20.0.42/32
+
+zones:
+  - domain: lab.r4.pm
+    acl: ddns
+
+listen_ip: 10.20.0.44
diff --git a/ansible/group_vars/resolver/all.yml b/ansible/group_vars/resolver/all.yml
index 7b8e1fa..43e069b 100644
--- a/ansible/group_vars/resolver/all.yml
+++ b/ansible/group_vars/resolver/all.yml
@@ -2,3 +2,8 @@
 kresd_allow:
   - 10.0.0.0/8
   - 172.16.0.0/12
+
+forward:
+  - zone: lab.r4.pm.
+    address: 10.20.0.44
+    ds: "lab.r4.pm. DS 61454 13 4 c510acc4a85ee8cfd93205b0cdc8d65a9e5376cf45517e5bd7db7fc836d076df688b11cf7f3a3b33a9b1011d74d00e74"
diff --git a/ansible/hosts.yml b/ansible/hosts.yml
index dcc7539..ca71b3a 100644
--- a/ansible/hosts.yml
+++ b/ansible/hosts.yml
@@ -5,6 +5,8 @@ all:
       ansible_host: 10.20.0.42
     dhcp-1:
       ansible_host: 10.20.0.43
+    authoritative-1:
+      ansible_host: 10.20.0.44
   children:
     resolver:
       hosts:
@@ -12,3 +14,6 @@ all:
     kea-dhcp:
       hosts:
         dhcp-1:
+    dns-authoritative:
+      hosts:
+        authoritative-1:
diff --git a/ansible/roles/knot/files/zones/lab.r4.pm.zone b/ansible/roles/knot/files/zones/lab.r4.pm.zone
new file mode 100644
index 0000000..77bb16b
--- /dev/null
+++ b/ansible/roles/knot/files/zones/lab.r4.pm.zone
@@ -0,0 +1,12 @@
+$ORIGIN lab.r4.pm.
+$TTL 3600
+@   IN  SOA   knot.lab.r4.pm. admin.r4.pm. (
+    2024041800 ; serial number
+    12h        ; refresh
+    15m        ; update retry
+    3w         ; expiry
+    2h         ; minimum
+)
+
+@               86400 IN NS knot.lab.r4.pm.
+knot.lab.r4.pm. 86400 IN A  10.20.0.44
diff --git a/ansible/roles/knot/handlers/main.yml b/ansible/roles/knot/handlers/main.yml
new file mode 100644
index 0000000..1b611d9
--- /dev/null
+++ b/ansible/roles/knot/handlers/main.yml
@@ -0,0 +1,15 @@
+---
+- name: Restart knot
+  ansible.builtin.service:
+    state: restarted
+    name: knot
+
+- name: Reload knot
+  ansible.builtin.service:
+    state: reloaded
+    name: knot
+
+- name: Enable knot
+  ansible.builtin.service:
+    enabled: true
+    name: knot
diff --git a/ansible/roles/knot/tasks/main.yml b/ansible/roles/knot/tasks/main.yml
new file mode 100644
index 0000000..c25af02
--- /dev/null
+++ b/ansible/roles/knot/tasks/main.yml
@@ -0,0 +1,58 @@
+---
+- name: Add knot pgp key
+  ansible.builtin.get_url:
+    url: https://pkg.labs.nic.cz/gpg
+    dest: /usr/share/keyrings/cznic-labs-pkg.gpg
+    mode: "0644"
+    validate_certs: true
+    checksum: sha512:e78a1404feff1040c86f4a199495e4a2cf82684b8ff22ffc318a9bffa0ddf45136e484bc17e4440660c089e1c186af77008c76fb463434611b1f60709b57ee52
+  changed_when: false
+  no_log: false
+
+- name: Add knot repository
+  ansible.builtin.apt_repository:
+    repo: "deb [signed-by=/usr/share/keyrings/cznic-labs-pkg.gpg] https://pkg.labs.nic.cz/knot-dns {{ ansible_distribution_release }} main"
+    state: present
+    filename: knot-dns
+
+
+- name: Install knot
+  ansible.builtin.apt:
+    name: knot
+  notify:
+    - Enable knot
+    - Restart knot
+
+- name: Configure knot
+  ansible.builtin.template:
+    src: knot.conf.j2
+    dest: /etc/knot/knot.conf
+    owner: knot
+    mode: '0640'
+  notify: Restart knot
+
+- name: Allow port 53 (DNS)
+  community.general.ufw:
+    rule: allow
+    port: "{{ item.port }}"
+    proto: "{{ item.proto }}"
+  with_items:
+    - { port: "53", proto: tcp }
+    - { port: "53", proto: udp }
+
+- name: Create knot zones directory
+  ansible.builtin.file:
+    path: /var/lib/knot/zones/
+    state: directory
+    mode: '0750'
+    owner: knot
+
+- name: Copy zone
+  ansible.builtin.copy:
+    src: "{{ item }}"
+    dest: /var/lib/knot/zones/
+    owner: knot
+    mode: '0640'
+  with_fileglob:
+    - zones/*
+  notify: Reload knot
diff --git a/ansible/roles/knot/templates/knot.conf.j2 b/ansible/roles/knot/templates/knot.conf.j2
new file mode 100644
index 0000000..e6d0333
--- /dev/null
+++ b/ansible/roles/knot/templates/knot.conf.j2
@@ -0,0 +1,32 @@
+server:
+    rundir: "/run/knot"
+    user: knot:knot
+    automatic-acl: on
+    listen: [ {{ listen_ip }}@53 ]
+
+log:
+  - target: syslog
+    any: info
+
+database:
+    storage: "/var/lib/knot"
+
+acl:
+{% for acl in acls %}
+  - id: {{ acl.id }}
+    address: {{ acl.address }}
+    action: {{ acl.action }}
+{% endfor %}
+
+template:
+  - id: default
+    storage: "/var/lib/knot/zones"
+    file: "%s.zone"
+    dnssec-signing: on
+    serial-policy: dateserial
+
+zone:
+{% for zone in zones %}
+  - domain: {{ zone.domain }}
+    acl: {{ zone.acl }}
+{% endfor %}
diff --git a/ansible/roles/knot_resolver/tasks/main.yml b/ansible/roles/knot_resolver/tasks/main.yml
index 62d2614..411e2a7 100644
--- a/ansible/roles/knot_resolver/tasks/main.yml
+++ b/ansible/roles/knot_resolver/tasks/main.yml
@@ -26,5 +26,5 @@
     port: "{{ item.port }}"
     proto: "{{ item.proto }}"
   with_items:
-    - { port: "53", proto: "tcp" }
-    - { port: "53", proto: "udp" }
+    - { port: "53", proto: tcp }
+    - { port: "53", proto: udp }
diff --git a/ansible/roles/knot_resolver/templates/kresd.conf.j2 b/ansible/roles/knot_resolver/templates/kresd.conf.j2
index 8754040..bb346f9 100644
--- a/ansible/roles/knot_resolver/templates/kresd.conf.j2
+++ b/ansible/roles/knot_resolver/templates/kresd.conf.j2
@@ -22,5 +22,9 @@ view:addr('{{ prefix }}', policy.all(policy.PASS))
 view:addr('0.0.0.0/0', policy.all(policy.DROP))
 view:addr('::/0', policy.all(policy.DROP))
 
+{% for zones in forward %}
+policy.add(policy.suffix(policy.FORWARD('{{ zones.address }}'), {todname('{{ zones.zone }}')}))
+trust_anchors.add('{{ zones.ds }}')
+{% endfor %}
 log_target('stdout')
-log_level('debug') 
\ No newline at end of file
+log_level('info')