From 1f444bacafa4fc13af582a8a65b86269b21cca1f Mon Sep 17 00:00:00 2001
From: Ada <ada@gnous.eu>
Date: Wed, 17 Apr 2024 14:58:43 +0200
Subject: [PATCH] Add DHCP

---
 ansible/deploy.yml                            |  6 ++
 ansible/group_vars/kea-dhcp/all.yml           | 19 ++++
 ansible/hosts.yml                             |  6 ++
 ansible/roles/kea_dhcp/handlers/main.yml      | 11 +++
 ansible/roles/kea_dhcp/tasks/main.yml         | 40 +++++++++
 .../kea_dhcp/templates/kea-dhcp4.conf.j2      | 88 +++++++++++++++++++
 6 files changed, 170 insertions(+)
 create mode 100644 ansible/group_vars/kea-dhcp/all.yml
 create mode 100644 ansible/roles/kea_dhcp/handlers/main.yml
 create mode 100644 ansible/roles/kea_dhcp/tasks/main.yml
 create mode 100644 ansible/roles/kea_dhcp/templates/kea-dhcp4.conf.j2

diff --git a/ansible/deploy.yml b/ansible/deploy.yml
index ec63e93..7bf1932 100644
--- a/ansible/deploy.yml
+++ b/ansible/deploy.yml
@@ -19,3 +19,9 @@
   become: true
   roles:
     - knot_resolver
+
+- name: DHCP
+  hosts: kea-dhcp
+  become: true
+  roles:
+    - kea_dhcp
diff --git a/ansible/group_vars/kea-dhcp/all.yml b/ansible/group_vars/kea-dhcp/all.yml
new file mode 100644
index 0000000..9852e0c
--- /dev/null
+++ b/ansible/group_vars/kea-dhcp/all.yml
@@ -0,0 +1,19 @@
+---
+domain: r4.pm
+domain_search:
+  - lab.r4.pm
+  - r4.pm
+
+networks:
+  - subnet: 10.15.0.0/24
+    start: 10.15.0.200
+    end: 10.15.0.254
+    routers: 10.15.0.1
+  - subnet: 10.20.0.0/24
+    start: 10.20.0.200
+    end: 10.20.0.254
+    routers: 10.20.0.1
+  - subnet: 10.30.0.0/24
+    start: 10.30.0.200
+    end: 10.30.0.254
+    routers: 10.30.0.1
diff --git a/ansible/hosts.yml b/ansible/hosts.yml
index db621ac..dcc7539 100644
--- a/ansible/hosts.yml
+++ b/ansible/hosts.yml
@@ -1,8 +1,14 @@
+---
 all:
   hosts:
     resolver-1:
       ansible_host: 10.20.0.42
+    dhcp-1:
+      ansible_host: 10.20.0.43
   children:
     resolver:
       hosts:
         resolver-1:
+    kea-dhcp:
+      hosts:
+        dhcp-1:
diff --git a/ansible/roles/kea_dhcp/handlers/main.yml b/ansible/roles/kea_dhcp/handlers/main.yml
new file mode 100644
index 0000000..102a5bc
--- /dev/null
+++ b/ansible/roles/kea_dhcp/handlers/main.yml
@@ -0,0 +1,11 @@
+---
+- name: Restart isc-kea-dhcp4-server
+  become: true
+  ansible.builtin.service:
+    state: restarted
+    name: isc-kea-dhcp4-server
+
+- name: Enable isc-kea-dhcp4-server
+  ansible.builtin.service:
+    enabled: true
+    name: isc-kea-dhcp4-server
diff --git a/ansible/roles/kea_dhcp/tasks/main.yml b/ansible/roles/kea_dhcp/tasks/main.yml
new file mode 100644
index 0000000..e2a1d2c
--- /dev/null
+++ b/ansible/roles/kea_dhcp/tasks/main.yml
@@ -0,0 +1,40 @@
+---
+- name: Add kea dhcp pgp key
+  ansible.builtin.get_url:
+    url: https://dl.cloudsmith.io/public/isc/kea-2-4/gpg.0D9D9A1439E23DB9.key
+    dest: /usr/share/keyrings/kea-archive-keyring.asc
+    mode: "0644"
+    validate_certs: true
+    checksum: sha512:f58db6baa7f7147c3280275b6f7cc11e34836fb904604d587c1883e6b4a8e89377046809203e2f1a1a87a7f28556728a9ecdb740d62e753592d2dbab0d2e87c8
+  changed_when: false
+  no_log: false
+
+- name: Add kea dhcp repository
+  ansible.builtin.apt_repository:
+    repo: "deb [signed-by=/usr/share/keyrings/kea-archive-keyring.asc]
+     https://dl.cloudsmith.io/public/isc/kea-2-4/deb/{{ ansible_distribution|lower }} {{ ansible_distribution_release }} main"
+    state: present
+    filename: isc-kea-dhcp
+
+- name: Install isc-kea-dhcp
+  ansible.builtin.apt:
+    name: isc-kea-dhcp4-server
+  notify:
+    - Enable isc-kea-dhcp4-server
+
+- name: Configure isc-kea-dhcp
+  ansible.builtin.template:
+    src: kea-dhcp4.conf.j2
+    dest: /etc/kea/kea-dhcp4.conf
+    owner: _kea
+    mode: '0640'
+  notify:
+    - Restart isc-kea-dhcp4-server
+
+- name: Open required ports
+  community.general.ufw:
+    rule: allow
+    port: "{{ item }}"
+    proto: udp
+  with_items:
+    - '67'
diff --git a/ansible/roles/kea_dhcp/templates/kea-dhcp4.conf.j2 b/ansible/roles/kea_dhcp/templates/kea-dhcp4.conf.j2
new file mode 100644
index 0000000..e66c536
--- /dev/null
+++ b/ansible/roles/kea_dhcp/templates/kea-dhcp4.conf.j2
@@ -0,0 +1,88 @@
+{
+"Dhcp4": {
+    // Add names of your network interfaces to listen on.
+    "interfaces-config": {
+        "interfaces": [ "eth0" ],
+    },
+
+    "control-socket": {
+        "socket-type": "unix",
+        "socket-name": "/tmp/kea4-ctrl-socket"
+    },
+
+    "lease-database": {
+        // Memfile is the simplest and easiest backend to use. It's an in-memory
+        // C++ database that stores its state in CSV file.
+        "type": "memfile",
+        "lfc-interval": 3600
+    },
+
+    "expired-leases-processing": {
+        "reclaim-timer-wait-time": 10,
+        "flush-reclaimed-timer-wait-time": 25,
+        "hold-reclaimed-time": 3600,
+        "max-reclaim-leases": 100,
+        "max-reclaim-time": 250,
+        "unwarned-reclaim-cycles": 5
+    },
+
+    "renew-timer": 900,
+    "rebind-timer": 1800,
+    "valid-lifetime": 3600,
+
+    "option-data": [
+        {
+            "name": "domain-name-servers",
+            "data": "{{ resolver_ip }}"
+        },
+        {
+            "code": 15,
+            "data": "{{ domain }}"
+        },
+
+        {
+            "name": "domain-search",
+            "data": "{{ domain_search|join(', ') }}"
+        },
+    ],
+
+    // Below an example of a simple IPv4 subnet declaration. Uncomment to enable
+    // it. This is a list, denoted with [ ], of structures, each denoted with
+    // { }. Each structure describes a single subnet and may have several
+    // parameters. One of those parameters is "pools" that is also a list of
+    // structures.
+    "subnet4": [
+        {% for network in networks %}
+        {
+            "subnet": "{{ network.subnet }}",
+
+            "pools": [ { "pool": "{{ network.start }} - {{ network.end }}" } ],
+
+            "option-data": [
+                {
+                    "name": "routers",
+                    "data": "{{ network.routers }}"
+                }
+            ],
+        }{% if not loop.last %},{% endif %}
+        {% endfor %}
+    ],
+
+    "loggers": [
+    {
+        // This section affects kea-dhcp4, which is the base logger for DHCPv4
+        // component. It tells DHCPv4 server to write all log messages (on
+        // severity INFO or more) to a file.
+        "name": "kea-dhcp4",
+        "output_options": [
+            {
+                "output": "stdout",
+            }
+        ],
+        "severity": "INFO",
+
+        "debuglevel": 0
+    }
+  ]
+}
+}