From 450be99adaafee71ae7a5289520078890be06505 Mon Sep 17 00:00:00 2001 From: Bombar Maxime Date: Mon, 27 Apr 2020 11:37:10 +0200 Subject: [PATCH] Add reverse zones --- lookup_plugins/re2oapi.py | 47 +++++++++++++++++++ network.yml | 1 + .../templates/bind/named.conf.local.j2 | 34 ++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/lookup_plugins/re2oapi.py b/lookup_plugins/re2oapi.py index b378d559..9e540907 100644 --- a/lookup_plugins/re2oapi.py +++ b/lookup_plugins/re2oapi.py @@ -13,6 +13,7 @@ import requests import stat import json import collections +import netaddr from configparser import ConfigParser from ansible.module_utils._text import to_native @@ -312,6 +313,9 @@ class LookupModule(LookupBase): - dnszones: Queries the re2o API and returns the list of all dns zones nicely formatted to be rendered in a template. + - dnsreverse: Queries the re2o API and returns the list of all reverse + dns zones, formatted to be rendered in a template. + - get_role, role_name: Works in pair. Fails if role_name not provided. Queries the re2o API and returns the list of all machines whose role_type is role_name. @@ -402,6 +406,8 @@ class LookupModule(LookupBase): display.v("\nLookup for {} \n".format(term)) if term == 'dnszones': res.append(self._getzones(api_client)) + elif term == 'dnsreverse': + res.append(self._getreverse(api_client)) elif term == 'get_role': try: role_name = dterms.popleft() @@ -429,6 +435,47 @@ class LookupModule(LookupBase): zones_name = [zone["name"][1:] for zone in zones] return zones_name + def _getreverse(self, api_client): + display.v("Getting dns reverse zones") + display.vvv("Contacting the API, endpoint dns/reverse-zones...") + zones = api_client.list('dns/reverse-zones') + display.vvv("...Done") + res = [] + for zone in zones: + if zone['ptr_records']: + display.vvv('Found PTR records') + subnets = [] + for net in zone['cidrs']: + net = netaddr.IPNetwork(net) + if net.prefixlen > 24: + subnets.extend(net.subnet(32)) + elif net.prefixlen > 16: + subnets.extend(net.subnet(24)) + elif net.prefixlen > 8: + subnets.extend(net.subnet(16)) + else: + subnets.extend(net.subnet(8)) + for subnet in subnets: + _address = netaddr.IPAddress(subnet.first) + rev_dns_a = _address.reverse_dns.split('.')[:-1] + if subnet.prefixlen == 8: + zone_name = '.'.join(rev_dns_a[3:]) + elif subnet.prefixlen == 16: + zone_name = '.'.join(rev_dns_a[2:]) + elif subnet.prefixlen == 24: + zone_name = '.'.join(rev_dns_a[1:]) + res.append(zone_name) + display.vvv("Found reverse zone {}".format(zone_name)) + if zone['ptr_v6_records']: + display.vvv("Found PTR v6 record") + net = netaddr.IPNetwork(zone['prefix_v6']+'/'+str(zone['prefix_v6_length'])) + net_class = max(((net.prefixlen -1) // 4) +1, 1) + zone6_name = ".".join( + netaddr.IPAddress(net.first).reverse_dns.split('.')[32 - net_class:])[:-1] + res.append(zone6_name) + display.vvv("Found reverse zone {}".format(zone6_name)) + return res + def _rawquery(self, api_client, endpoint): display.v("Make a raw query to endpoint {}".format(endpoint)) return api_client.list(endpoint) diff --git a/network.yml b/network.yml index 52e46483..b7d09a19 100755 --- a/network.yml +++ b/network.yml @@ -44,6 +44,7 @@ masters: "{{ lookup('re2oapi', 'get_role', 'dns-authoritary-master')[0] }}" slaves: "{{ lookup('re2oapi', 'get_role', 'dns-authoritary-slave')[0] }}" zones: "{{ lookup('re2oapi', 'dnszones') }}" + reverse: "{{ lookup('re2oapi', 'dnsreverse') }}" roles: - bind-authoritative diff --git a/roles/bind-authoritative/templates/bind/named.conf.local.j2 b/roles/bind-authoritative/templates/bind/named.conf.local.j2 index a7b8d610..41c26b7a 100644 --- a/roles/bind-authoritative/templates/bind/named.conf.local.j2 +++ b/roles/bind-authoritative/templates/bind/named.conf.local.j2 @@ -77,3 +77,37 @@ zone "{{ zone }}" { }; {% endfor %} + +// Crans reverse zones +{% for zone in bind.reverse %} +zone "{{ zone }}" { + {% if is_master -%} + type master; + // Apparmor: Need to ln -s /var/cache/bind/generated /var/local/re2o-services/dns/generated + file "generated/dns.{{ zone }}.zone"; + allow-transfer { + {% for ip in slaves_ipv4 -%} + {{ ip }}; + {% endfor -%} + {% for ip in slaves_ipv6 -%} + {{ ip }}; + {% endfor -%} + }; + notify yes; + {% else -%} + type slave; + file "bak.{{ zone }}"; + masters { + {% for ip in masters_ipv4 -%} + {{ ip }}; + {% endfor -%} + {% for ip in masters_ipv6 -%} + {{ ip }}; + {% endfor -%} + }; + allow-transfer { "none"; }; + notify no; +{% endif -%} +}; + +{% endfor %}