diff --git a/gestion/gen_confs/bind.py b/gestion/gen_confs/bind.py index ebbd4db7..565c21b8 100755 --- a/gestion/gen_confs/bind.py +++ b/gestion/gen_confs/bind.py @@ -33,25 +33,6 @@ disclamer = """//**************************************************************/ def short_name(fullhostname): return fullhostname.split(".")[0] -def reverse(net, ip): - """Renvoie la zone DNS inverse correspondant au réseau et à - l'adresse donnés, ainsi que le nombre d'éléments de l'ip a - mettre dans le fichier de zone.""" - n = netaddr.IPNetwork(net) - a = netaddr.IPAddress(ip) - rev_dns_a = a.reverse_dns.split('.')[:-1] - assert a in n - if n.version == 4: - if n.prefixlen == 8: - return ('.'.join(rev_dns_a[3:]), 3) - elif n.prefixlen == 16: - return ('.'.join(rev_dns_a[2:]), 2) - else: - return ('.'.join(rev_dns_a[1:]), 1) - elif n.version == 6: - return ('.'.join(rev_dns_a[(128-n.prefixlen)/4:]), (128-n.prefixlen)/4) - - class ResourceRecord(object): def __init__(self, type, name, value, ttl=None): self._type=type @@ -260,8 +241,10 @@ class Zone(ZoneBase): class ZoneReverse(Zone): def __init__(self, net, ttl, soa, ns_list): + if len(ZoneReverse.network_to_arpanets(net))!=1: + raise ValueError("%s n'est pas un réseau valide pour une zone de reverse dns" % net) self.net = net - zone_name = reverse(net, net.split('/')[0])[0] + zone_name = ZoneReverse.reverse(net)[0] if '.' in net: ipv6=False ipv4=True @@ -272,6 +255,55 @@ class ZoneReverse(Zone): raise ValueError("net should be an ipv4 ou ipv6 network") super(ZoneReverse, self).__init__(zone_name, ttl, soa, ns_list, ipv6=ipv6, ipv4=ipv4) + @staticmethod + def reverse(net, ip=None): + """Renvoie la zone DNS inverse correspondant au réseau et à + l'adresse donnés, ainsi que le nombre d'éléments de l'ip a + mettre dans le fichier de zone si elle est fournie, n'importe + quoi sinon.""" + n = netaddr.IPNetwork(net) + a = netaddr.IPAddress(ip if ip else n.ip) + rev_dns_a = a.reverse_dns.split('.')[:-1] + assert a in n + if n.version == 4: + if n.prefixlen == 8: + return ('.'.join(rev_dns_a[3:]), 3) + elif n.prefixlen == 16: + return ('.'.join(rev_dns_a[2:]), 2) + elif n.prefixlen == 24: + return ('.'.join(rev_dns_a[1:]), 1) + else: + raise ValueError("Bad network %s" % n) + elif n.version == 6: + return ('.'.join(rev_dns_a[(128-n.prefixlen)/4:]), (128-n.prefixlen)/4) + + + @staticmethod + def network_to_arpanets(nets): + """ + retourne une liste de reseaux ne contenant que + des préfixes de taille 32, 24, 16 ou 8 en ipv4 + et laisse inchangé les réseaux ipv6. + """ + if not isinstance(nets, list): + nets = [nets] + subnets = [] + for net in nets: + if not isinstance(net, netaddr.IPNetwork): + net = netaddr.IPNetwork(net) + if net.version == 4: + 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)) + elif net.version == 6: + subnets.append(net) + return subnets + def add_machine(self, machine): if machine['host']: @@ -283,7 +315,7 @@ class ZoneReverse(Zone): raise ValueError("A reverse zone should be ipv6 or ipv6") for ip in machine[attr]: try: - zone, length = reverse(self.net, str(ip)) + zone, length = ZoneReverse.reverse(self.net, str(ip)) nom = '.'.join(ip.value.reverse_dns.split('.')[:length]) if zone != self.zone_name: continue @@ -402,22 +434,8 @@ class dns(gen_config) : def gen_zones_reverse(self, ttl, ns_list, serial, zones={}, zones_reverse_v4=config.dns.zones_reverse, zones_reverse_v6=config.dns.zones_reverse_v6): - # reverse ipv4 - for net in zones_reverse_v4: - net = netaddr.IPNetwork(net) - if net.prefixlen > 24: - subnets = net.subnet(32) - elif net.prefixlen > 16: - subnets = net.subnet(24) - elif net.prefixlen > 8: - subnets = net.subnet(16) - else: - subnets = net.subnet(8) - for subnet in subnets: - zones[str(subnet)]=ZoneReverse(str(subnet), ttl, self.gen_soa(ns_list, serial, ttl), ns_list) - # reverse ipv6 - for net in zones_reverse_v6: - zones[net]=ZoneReverse(net, ttl, self.gen_soa(ns_list, serial, ttl), ns_list) + for net in ZoneReverse.network_to_arpanets(zones_reverse_v4 + zones_reverse_v6): + zones[str(net)]=ZoneReverse(str(net), ttl, self.gen_soa(ns_list, serial, ttl), ns_list) return zones def gen_zones_clone(self, ttl, ns_list, serial, zones={}):