From 9ad954a0c35b3a179de82f3aa7a06c5738f0cb4b Mon Sep 17 00:00:00 2001
From: Benjamin Graillot <graillot@crans.org>
Date: Sun, 23 Aug 2020 11:41:39 +0200
Subject: [PATCH] [bind-recursive] Deploy configuration

---
 lookup_plugins/ldap.py                        |  4 +--
 roles/bind-recursive/handlers/main.yml        |  5 +++
 roles/bind-recursive/tasks/main.yml           | 14 ++++++++
 .../bind-recursive/templates/bind/db.infra.j2 | 24 +++++++++++++
 .../templates/bind/named.conf.acl.j2          | 31 +++++++++++++++++
 .../bind/named.conf.default-zones.j2          | 34 +++++++++++++++++++
 .../templates/bind/named.conf.j2              | 14 ++++++++
 .../templates/bind/named.conf.local.j2        | 15 ++++++++
 .../templates/bind/named.conf.options.j2      | 26 ++++++++++++++
 9 files changed, 165 insertions(+), 2 deletions(-)
 create mode 100644 roles/bind-recursive/handlers/main.yml
 create mode 100644 roles/bind-recursive/templates/bind/db.infra.j2
 create mode 100644 roles/bind-recursive/templates/bind/named.conf.acl.j2
 create mode 100644 roles/bind-recursive/templates/bind/named.conf.default-zones.j2
 create mode 100644 roles/bind-recursive/templates/bind/named.conf.j2
 create mode 100644 roles/bind-recursive/templates/bind/named.conf.local.j2
 create mode 100644 roles/bind-recursive/templates/bind/named.conf.options.j2

diff --git a/lookup_plugins/ldap.py b/lookup_plugins/ldap.py
index 05a5493d..3174e79e 100644
--- a/lookup_plugins/ldap.py
+++ b/lookup_plugins/ldap.py
@@ -98,12 +98,12 @@ class LookupModule(LookupBase):
             result = self.base.result(query_id)
             result = result[1][0][1]
             result = [res.decode('utf-8') for res in result[attr]]
-        elif terms[0] == 'networks':
+        elif terms[0] == 'network':
             network = terms[1]
             query_id = self.base.search(f"cn={network},ou=networks,{self.base_dn}", ldap.SCOPE_BASE, "objectClass=ipNetwork")
             result = self.base.result(query_id)
             result = result[1][0][1]
-            return [str(ipaddress.ip_network('{}/{}'.format(result['ipNetworkNumber'][0].decode('utf-8'), result['ipNetmaskNumber'][0].decode('utf-8'))))]
+            return str(ipaddress.ip_network('{}/{}'.format(result['ipNetworkNumber'][0].decode('utf-8'), result['ipNetmaskNumber'][0].decode('utf-8'))))
         elif terms[0] == 'zones':
             query_id = self.base.search(f"ou=networks,{self.base_dn}", ldap.SCOPE_ONELEVEL, "objectClass=ipNetwork")
             result = self.base.result(query_id)
diff --git a/roles/bind-recursive/handlers/main.yml b/roles/bind-recursive/handlers/main.yml
new file mode 100644
index 00000000..c6741672
--- /dev/null
+++ b/roles/bind-recursive/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Reload bind9
+  systemd:
+    name: bind9
+    state: reloaded
diff --git a/roles/bind-recursive/tasks/main.yml b/roles/bind-recursive/tasks/main.yml
index 0c962a8b..e45f12c2 100644
--- a/roles/bind-recursive/tasks/main.yml
+++ b/roles/bind-recursive/tasks/main.yml
@@ -6,3 +6,17 @@
   register: apt_result
   retries: 3
   until: apt_result is succeeded
+
+- name: Deploy Bind9 configuration
+  template:
+    src: bind/{{ item }}.j2
+    dest: /etc/bind/{{ item }}
+    mode: 0644
+  loop:
+    - named.conf
+    - named.conf.acl
+    # - named.conf.options
+    - named.conf.local
+    - named.conf.default-zones
+    - db.infra
+  notify: Reload bind9
diff --git a/roles/bind-recursive/templates/bind/db.infra.j2 b/roles/bind-recursive/templates/bind/db.infra.j2
new file mode 100644
index 00000000..2e926ac6
--- /dev/null
+++ b/roles/bind-recursive/templates/bind/db.infra.j2
@@ -0,0 +1,24 @@
+{{ ansible_header | comment(decoration='; ') }}
+
+$TTL 0
+
+@ IN SOA silice.crans.org root.crans.org (
+	0 ; serial
+	3600 ; refresh (1hr)
+	1800 ; retry (30mn)
+	604800 ; expire (7dy)
+	0 ; TTL (0s)
+	)
+
+@ IN NS passerelle.infra.crans.org
+passerelle.infra.crans.org IN A {{ (query('ldap', 'ip', 'passerelle', 'infra') | ipv4)[0] }}
+
+* IN CNAME crans.org
+*.org IN CNAME crans.org
+*.fr IN CNAME crans.org
+*.com IN CNAME crans.org
+
+intranet.crans.org IN A 172.16.32.156 ; (query('ldap', 'ip', 'intranet', 'infra') | ipv4)[0]
+intranet.infra.crans.org IN A 172.16.32.156
+
+unifi.infra.crans.org IN A {{ (query('ldap', 'ip', 'unifi', 'infra') | ipv4)[0] }}
diff --git a/roles/bind-recursive/templates/bind/named.conf.acl.j2 b/roles/bind-recursive/templates/bind/named.conf.acl.j2
new file mode 100644
index 00000000..25f1ec43
--- /dev/null
+++ b/roles/bind-recursive/templates/bind/named.conf.acl.j2
@@ -0,0 +1,31 @@
+{{ ansible_header | comment(decoration='// ') }}
+
+acl "srv" {
+	{{ query('ldap', 'network', 'srv') }};
+	2a0c:700:{{ query('ldap', 'vlanid', 'srv') }}::/48;
+};
+
+acl "srv-nat" {
+	{{ query('ldap', 'network', 'srv-nat') }};
+	2a0c:700:{{ query('ldap', 'vlanid', 'srv-nat') }}::/48;
+};
+
+acl "adm" {
+	{{ query('ldap', 'network', 'adm') }};
+	fd00:0:0:{{ query('ldap', 'vlanid', 'adm') }}::/64;
+};
+
+acl "infra" {
+	{{ query('ldap', 'network', 'infra') }};
+	fd00:0:0:{{ query('ldap', 'vlanid', 'infra') }}::/64;
+};
+
+acl "adh" {
+	{{ query('ldap', 'network', 'adh') }};
+	2a0c:700:{{ query('ldap', 'vlanid', 'adh') }}::/48;
+};
+
+acl "adh-nat" {
+	{{ query('ldap', 'network', 'adh-nat') }};
+	2a0c:700:{{ query('ldap', 'vlanid', 'adh-nat') }}::/48;
+};
diff --git a/roles/bind-recursive/templates/bind/named.conf.default-zones.j2 b/roles/bind-recursive/templates/bind/named.conf.default-zones.j2
new file mode 100644
index 00000000..6a919236
--- /dev/null
+++ b/roles/bind-recursive/templates/bind/named.conf.default-zones.j2
@@ -0,0 +1,34 @@
+{{ ansible_header | comment(decoration='// ') }}
+
+view "default" {
+	match-clients { any; };
+
+	// prime the server with knowledge of the root servers
+	zone "." {
+		type hint;
+		file "/usr/share/dns/root.hints";
+	};
+
+	// be authoritative for the localhost forward and reverse zones, and for
+	// broadcast zones as per RFC 1912
+
+	zone "localhost" {
+		type master;
+		file "/etc/bind/db.local";
+	};
+
+	zone "127.in-addr.arpa" {
+		type master;
+		file "/etc/bind/db.127";
+	};
+
+	zone "0.in-addr.arpa" {
+		type master;
+		file "/etc/bind/db.0";
+	};
+
+	zone "255.in-addr.arpa" {
+		type master;
+		file "/etc/bind/db.255";
+	};
+};
diff --git a/roles/bind-recursive/templates/bind/named.conf.j2 b/roles/bind-recursive/templates/bind/named.conf.j2
new file mode 100644
index 00000000..5edbf974
--- /dev/null
+++ b/roles/bind-recursive/templates/bind/named.conf.j2
@@ -0,0 +1,14 @@
+{{ ansible_header | comment(decoration='// ') }}
+
+// This is the primary configuration file for the BIND DNS server named.
+//
+// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
+// structure of BIND configuration files in Debian, *BEFORE* you customize
+// this configuration file.
+//
+// If you are just adding zones, please do that in /etc/bind/named.conf.local
+
+include "/etc/bind/named.conf.acl";
+include "/etc/bind/named.conf.options";
+include "/etc/bind/named.conf.local";
+include "/etc/bind/named.conf.default-zones";
diff --git a/roles/bind-recursive/templates/bind/named.conf.local.j2 b/roles/bind-recursive/templates/bind/named.conf.local.j2
new file mode 100644
index 00000000..101fade7
--- /dev/null
+++ b/roles/bind-recursive/templates/bind/named.conf.local.j2
@@ -0,0 +1,15 @@
+{{ ansible_header | comment(decoration='// ') }}
+
+// Consider adding the 1918 zones here, if they are not used in your
+// organization
+//include "/etc/bind/zones.rfc1918";
+
+view "infra" {
+	match-clients { infra; };
+	recursion no;
+
+	zone "." {
+		type master;
+		file "/etc/bind/db.infra";
+	};
+};
diff --git a/roles/bind-recursive/templates/bind/named.conf.options.j2 b/roles/bind-recursive/templates/bind/named.conf.options.j2
new file mode 100644
index 00000000..93497100
--- /dev/null
+++ b/roles/bind-recursive/templates/bind/named.conf.options.j2
@@ -0,0 +1,26 @@
+{{ ansible_header | comment(decoration='// ') }}
+
+options {
+	directory "/var/cache/bind";
+
+	// If there is a firewall between you and nameservers you want
+	// to talk to, you may need to fix the firewall to allow multiple
+	// ports to talk.  See http://www.kb.cert.org/vuls/id/800113
+
+	// If your ISP provided one or more IP addresses for stable
+	// nameservers, you probably want to use them as forwarders.
+	// Uncomment the following block, and insert the addresses replacing
+	// the all-0's placeholder.
+
+	// forwarders {
+	// 	0.0.0.0;
+	// };
+
+	//========================================================================
+	// If BIND logs error messages about the root key being expired,
+	// you will need to update your keys.  See https://www.isc.org/bind-keys
+	//========================================================================
+	dnssec-validation auto;
+
+	listen-on-v6 { any; };
+};
-- 
GitLab