[scripts] Going to utf-8

This commit is contained in:
Pierre-Elliott Bécue 2013-05-04 19:19:36 +02:00
parent c4a19a88ed
commit a1bf0a4547
54 changed files with 676 additions and 573 deletions

View file

@ -1,9 +1,9 @@
#! /usr/bin/env python
# -*- coding: iso-8859-15 -*-
# -*- coding: utf-8 -*-
""" Génération de la configuration pour bind9
""" Génération de la configuration pour bind9
Copyright (C) Frédéric Pauget
Copyright (C) Frédéric Pauget
Licence : GPLv2
"""
import time, sys, re, hashlib, base64, os
@ -56,36 +56,36 @@ def netv6_to_arpa(net):
class dns(gen_config) :
"""
Génération des fichiers de configuration de bind9 :
* fichier DNS_CONF qui contient les définitions de zone conformément
à zone_template. Ce fichier doit être inclus à partir de la config statique
Génération des fichiers de configuration de bind9 :
* fichier DNS_CONF qui contient les définitions de zone conformément
à zone_template. Ce fichier doit être inclus à partir de la config statique
de bind
* les fichiers de zones, ce sont eux qui contiennent les données du
dns, ils ont appellés par le fichier DNS_CONF et sont générés dans DNS_DIR
Leur entète est générée à partir de zone_entete.
* les fichiers de zones, ce sont eux qui contiennent les données du
dns, ils ont appellés par le fichier DNS_CONF et sont générés dans DNS_DIR
Leur entète est générée à partir de zone_entete.
Les fichiers générés placent bind comme autoritaire sur les noms de
zones_direct et les adresses de zones_reverse. Les données proviennent de
Les fichiers générés placent bind comme autoritaire sur les noms de
zones_direct et les adresses de zones_reverse. Les données proviennent de
la base LDAP
"""
######################################PARTIE DE CONFIGURATION
### Fichiers à écrire
# Répertoire d'écriture des fichiers de zone
DNS_DIR = '/etc/bind/generated/' # Avec un / à la fin
DNSSEC_DIR = '/etc/bind/signed/' # Avec un / à la fin
# Fichier de définition des zones pour le maître
### Fichiers à écrire
# Répertoire d'écriture des fichiers de zone
DNS_DIR = '/etc/bind/generated/' # Avec un / à la fin
DNSSEC_DIR = '/etc/bind/signed/' # Avec un / à la fin
# Fichier de définition des zones pour le maître
DNS_CONF = DNS_DIR + 'zones_crans'
# Fichier de définition des zones pour les esclaves géré par BCfg2
# Fichier de définition des zones pour les esclaves géré par BCfg2
DNS_CONF_BCFG2 = "/var/lib/bcfg2/Cfg/etc/bind/generated/zones_crans/zones_crans"
### Sur quelles zones on a autorité ?
## En cas de modification de ces zones penser à regéner le fichier de
### Sur quelles zones on a autorité ?
## En cas de modification de ces zones penser à regéner le fichier de
## zone des esclaves (sur le serveur principal de bcfg2 : python /usr/scripts/gestion/gen_confs/bind.py puis lancer bcfg2 sur les miroirs)
# Résolution directe
# Résolution directe
zones_direct = config.dns.zones_direct
# Zones signée par opendnssec sur le serveur maitre
# Zones signée par opendnssec sur le serveur maitre
zones_dnssec = config.dns.zones_dnssec
# Zones alias pour les enregistrement A AAAA CNAME TXT et SSHFP
zone_alias = config.dns.zone_alias
@ -97,7 +97,7 @@ la base LDAP
'adm.crans.org': 'adm.v6.crans.org',
'ferme.crans.org': 'ferme.v6.crans.org',
}
# Résolution inverse
# Résolution inverse
zones_reverse = config.dns.zones_reverse
zones_v6_to_net = {
'crans.eu': config.prefix["fil"][0],
@ -105,26 +105,26 @@ la base LDAP
'wifi.crans.org': config.prefix["wifi"][0],
'adm.crans.org': config.prefix["adm"][0],
'ferme.crans.org': config.prefix["fil"][0],
# Hack pour générer un fichier de zone vide
# Hack pour générer un fichier de zone vide
'##HACK##': config.prefix["subnet"][0],
}
### Liste DNS
# Le premier doit être le maitre
# Le premier doit être le maitre
DNSs = ['sable.crans.org', 'freebox.crans.org', 'ovh.crans.org']
DNSs_private = []
ip_master_DNS = config.dns.master
zone_multicast = 'tv.crans.org'
### Liste des délégations de zone
# Pour les demandes de ces zones, le DNS dira d'aller voir les serveurs listés ici
### Liste des délégations de zone
# Pour les demandes de ces zones, le DNS dira d'aller voir les serveurs listés ici
# Pour les noms des serveurs on met l'IP sans point ou le nom avec un point
DELEG = {
zone_multicast : [ 'sable.crans.org.' , 'mdr.crans.org.', 'freebox.crans.org.', 'ovh.crans.org.'] ,
}
### Serveurs de mail
# format : [ priorité serveur , .... ]
# format : [ priorité serveur , .... ]
MXs = ['10 redisdead.crans.org', '20 ovh.crans.org', '20 freebox.crans.org']
SRVs = [
'_jabber._tcp.crans.org. 86400 IN SRV 5 0 5269 xmpp.crans.org.',
@ -135,7 +135,7 @@ la base LDAP
'_sips._tcp.crans.org. 86400 IN SRV 5 0 5061 asterisk.crans.org.',
]
# DS à publier dans zone parentes : { parent : [ zone. TTL IN DS key_id algo_id 1 hash ] }
# DS à publier dans zone parentes : { parent : [ zone. TTL IN DS key_id algo_id 1 hash ] }
# ex : { 'crans.eu' : ['wifi.crans.eu. 86400 IN DS 33131 8 1 3B573B0E2712D8A8B1B0C3'] }
# /!\ Il faut faire attention au rollback des keys, il faudrait faire quelque chose d'automatique avec opendnssec
DS = {
@ -161,7 +161,7 @@ la base LDAP
}
### Entète des fichiers de zone
### Entète des fichiers de zone
zone_entete="""
$ORIGIN %(zone)s.
$TTL 3600
@ -174,14 +174,14 @@ $TTL 3600
)
"""
# Syntaxe utilisée dans le fichier DNS_CONF pour définir une zone sur le maître
# Syntaxe utilisée dans le fichier DNS_CONF pour définir une zone sur le maître
zone_template="""
zone "%(NOM_zone)s" {
type master;
file "%(FICHIER_zone)s";
};
"""
# Syntaxe utilisée dans le fichier DNS_CONF_BCFG2 pour définir une zone sur un esclave
# Syntaxe utilisée dans le fichier DNS_CONF_BCFG2 pour définir une zone sur un esclave
zone_template_slave="""
zone "%(NOM_zone)s" {
type slave;
@ -190,10 +190,10 @@ zone "%(NOM_zone)s" {
};
"""
### Verbosité
# Si =2, ralera (chaine warnings) si machines hors zone trouvée
### Verbosité
# Si =2, ralera (chaine warnings) si machines hors zone trouvée
# Si =1, comme ci-dessus, mais ne ralera pas pour freebox
# Si =0, ralera seulement contre les machines ne pouvant être classées
# Si =0, ralera seulement contre les machines ne pouvant être classées
verbose = 1
hostname = short_name(gethostname())
@ -208,8 +208,8 @@ zone "%(NOM_zone)s" {
return "DNS"
def reverse(self, 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
"""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)
@ -228,7 +228,7 @@ zone "%(NOM_zone)s" {
zone_reverse=netv4_to_arpa(config.NETs['multicast'][0])[0]
sap=open('/tmp/chaines_recup_sap.txt').readlines()
DNS='; DNS de la zone par ordre de priorité\n'
DNS='; DNS de la zone par ordre de priorité\n'
for d in self.DELEG[self.zone_multicast] :
DNS += '@\tIN\tNS %s\n' % d
DNS += '\n'
@ -238,9 +238,9 @@ zone "%(NOM_zone)s" {
lignes_d +='@\tIN\tA\t%s\n' % '138.231.136.243'
for line in sap:
[nom,ip]=line.split(':')
nom=re.sub('TNT([0-9]*) ','',nom) # on enlève les TNT## des noms
nom=re.sub(' +([^ ])','-\g<1>',nom) # on remplaces les espaces intérieur par un tiret
nom=re.sub('[ .():,"\'+<>]','',nom) # on enlève tous les caractères illégaux
nom=re.sub('TNT([0-9]*) ','',nom) # on enlève les TNT## des noms
nom=re.sub(' +([^ ])','-\g<1>',nom) # on remplaces les espaces intérieur par un tiret
nom=re.sub('[ .():,"\'+<>]','',nom) # on enlève tous les caractères illégaux
nom=nom.lower()
try:
[ip1,ip2,ip3,ip4]=ip.strip().split('.')
@ -248,7 +248,7 @@ zone "%(NOM_zone)s" {
lignes_d +='%s\tIN\tA\t%s' % (nom,ip)
except:
pass
# Écriture de la zone directe
# Écriture de la zone directe
file = self.DNS_DIR + 'db.' + self.zone_multicast
fd = self._open_conf(file,';')
fd.write(self.zone_entete % \
@ -258,7 +258,7 @@ zone "%(NOM_zone)s" {
fd.write(lignes_d)
fd.close()
# Écriture du reverse
# Écriture du reverse
file = self.DNS_DIR + 'db.' + zone_reverse
fd = self._open_conf(file,';')
fd.write(self.zone_entete % \
@ -270,7 +270,7 @@ zone "%(NOM_zone)s" {
def gen_slave(self) :
""" Génération du fichier de config de zone pour les esclaves """
""" Génération du fichier de config de zone pour les esclaves """
zones = self.zones_direct
zones.extend(self.zones_v4_to_v6.values())
@ -297,13 +297,13 @@ zone "%(NOM_zone)s" {
fd.close()
def _gen(self) :
### Génération du numéro de série
# Le + 1000.... s'explique pas l'idée précédente et peu pratique d'avoir
# le numéro de série du type AAAAMMJJNN (année, mois, jour, incrément par jour)
### Génération du numéro de série
# Le + 1000.... s'explique pas l'idée précédente et peu pratique d'avoir
# le numéro de série du type AAAAMMJJNN (année, mois, jour, incrément par jour)
serial = time.time() + 1000000000
### DNS
DNS='; DNS de la zone par ordre de priorité\n'
DNS='; DNS de la zone par ordre de priorité\n'
for d in self.DNSs :
DNS += '@\tIN\tNS %s.\n' % d
DNS += '\n'
@ -311,7 +311,7 @@ zone "%(NOM_zone)s" {
### Serveurs de mail
MX='; Serveurs de mails\n'
for m in self.MXs :
MX += '%(zone)s.\t' # Sera remplacé par le nom de zone plus tard
MX += '%(zone)s.\t' # Sera remplacé par le nom de zone plus tard
MX += 'IN\tMX\t%s.\n' % m
MX += '\n'
@ -345,12 +345,12 @@ zone "%(NOM_zone)s" {
self.anim.iter=len(self.machines)
for machine in self.machines :
self.anim.cycle()
# Calculs préliminaires
# Calculs préliminaires
try :
nom , zone = machine.nom().split('.',1)
zone = zone.encode('iso-8859-1')
zone = zone.encode('utf-8')
except :
warnings += u'Machine ignorée (mid=%s) : format nom incorrect (%s)\n' % ( machine.id().encode('iso-8859-1'), machine.nom().encode('iso-8859-1') )
warnings += u'Machine ignorée (mid=%s) : format nom incorrect (%s)\n' % ( machine.id().encode('utf-8'), machine.nom().encode('utf-8') )
continue
# Le direct
@ -359,7 +359,7 @@ zone "%(NOM_zone)s" {
# Si la machine est une borne wifi, on ajoute la position
if isinstance(machine,ldap_crans.BorneWifi) and machine.position():
ligne +="%s\tIN\tTXT\t\"LOC %s,%s \"\n" % (nom,machine.position()[0],machine.position()[1])
# Si la machine à des clefs ssh, on ajoute les champs SSFP correspondant
# Si la machine à des clefs ssh, on ajoute les champs SSFP correspondant
for sshkey in machine.sshFingerprint():
try:
[algo_txt,key]=sshkey.split()[:2]
@ -378,7 +378,7 @@ zone "%(NOM_zone)s" {
for alias in self.zone_alias[zone]:
direct[alias] = direct.get(alias, "") + ligne
elif self.verbose and machine.nom() != "ftp.federez.net":
warnings += u'Résolution directe ignorée (mid=%s) : zone non autoritaire (%s)\n' % ( machine.id().encode('iso-8859-1'), zone.encode('iso-8859-1') )
warnings += u'Résolution directe ignorée (mid=%s) : zone non autoritaire (%s)\n' % ( machine.id().encode('utf-8'), zone.encode('utf-8') )
# IPv6
if zone in self.zones_v4_to_v6:
@ -406,23 +406,23 @@ zone "%(NOM_zone)s" {
# Le direct avec alias
for alias in machine.alias() :
alias = alias.encode('iso-8859-1')
alias = alias.encode('utf-8')
# Cas particulier : nom de l'alias = nom de la zone
if alias in self.zones_direct :
ligne = "@\tIN\tA\t%s\n" % machine.ip()
ligne = ligne.encode('iso-8859-1')
ligne = ligne.encode('utf-8')
direct[alias] = direct.get(alias, "") + ligne
if alias in self.zone_alias:
for alias2 in self.zone_alias[alias]: direct[alias2] = direct.get(alias2, "") + ligne
if machine.dnsIpv6():
ligne = "@\tIN\tAAAA\t%s\n" % machine.ipv6()
ligne = ligne.encode('iso-8859-1')
ligne = ligne.encode('utf-8')
direct[alias]= direct.get(alias, "") + ligne
if alias in self.zone_alias:
for alias2 in self.zone_alias[alias]: direct[alias2] = direct.get(alias2, "") + ligne
if alias in self.zones_v4_to_v6:
ligne = "@\tIN\tAAAA\t%s\n" % machine.ipv6()
ligne = ligne.encode('iso-8859-1')
ligne = ligne.encode('utf-8')
zone6 = self.zones_v4_to_v6[alias]
direct[zone6] = direct.get(zone6, '') + ligne
if alias in self.zone_alias:
@ -445,9 +445,9 @@ zone "%(NOM_zone)s" {
ok = 1
break
if not ok:
warnings += u'Alias ignoré (mid=%s) : %s\n' % ( machine.id().encode('iso-8859-1'), alias.encode('iso-8859-1') )
warnings += u'Alias ignoré (mid=%s) : %s\n' % ( machine.id().encode('utf-8'), alias.encode('utf-8') )
continue
zone = zone.encode('iso-8859-1')
zone = zone.encode('utf-8')
ligne = "%s\tIN\tCNAME\t%s.\n" % ( nom, machine.nom() )
direct[zone] = direct.get(zone, '') + ligne
if zone in self.zones_v4_to_v6:
@ -468,40 +468,40 @@ zone "%(NOM_zone)s" {
base_ip = ip.split('.')
base_ip.reverse()
zone, length = self.reverse(net, ip)
zone = zone.encode('iso-8859-1')
zone = zone.encode('utf-8')
ligne = '%s\tIN\tPTR\t%s.\n' % ('.'.join(base_ip[:length]), machine.nom())
try : reverse[zone] += ligne
except : reverse[zone] = ligne
elif self.verbose >= 2 or machine.nom() not in ('freebox.crans.org', 'ovh.crans.org', 'kokarde.crans.org'):
warnings += u'Résolution inverse ignorée (mid=%s) : ip sur zone non autoritaire (%s)\n' % ( machine.id().encode('iso-8859-1'), machine.ip().encode('iso-8859-1') )
warnings += u'Résolution inverse ignorée (mid=%s) : ip sur zone non autoritaire (%s)\n' % ( machine.id().encode('utf-8'), machine.ip().encode('utf-8') )
### Ajouts pour les fichiers de résolution directs
### Ajouts pour les fichiers de résolution directs
for zone in direct.keys() :
# MXs
direct[zone] = MX % { 'zone' : zone } + direct[zone]
### XXX: création de la zone inverse pour le /48 IPv6 complet du Cr@ns
### XXX: création de la zone inverse pour le /48 IPv6 complet du Cr@ns
full_net_v6 = self.zones_v6_to_net["##HACK##"]
zone_rev, length = self.reverse(full_net_v6, netaddr.IPNetwork(full_net_v6).first)
reverse[zone_rev] = reverse.get(zone_rev, "")
### Ajout des délégations de zones
### Ajout des délégations de zones
for deleg in self.DELEG.keys():
nom, zone = deleg.split('.',1)
if not zone in direct.keys():
warnings += u'Délégation ignorée %s : on ne génère pas la zone parent\n' % deleg
warnings += u'Délégation ignorée %s : on ne génère pas la zone parent\n' % deleg
continue
for serv in self.DELEG[deleg]:
direct[zone] = direct[zone] + "%s\tIN\tNS\t%s\n" % ( nom, serv )
### Ajout d'eventuel champs DS pour les délégation dnssec
### Ajout d'eventuel champs DS pour les délégation dnssec
for zone,ds in self.DS.items():
for s in ds:
direct[zone] += s + '\n'
direct[zone] += '\n'
### Ecriture des fichiers de zone et préparation du fichier de définition
### Ecriture des fichiers de zone et préparation du fichier de définition
f = ''
for zone, lignes in direct.items() + reverse.items() :
if zone in self.zones_dnssec:
@ -523,7 +523,7 @@ zone "%(NOM_zone)s" {
else:
f += self.zone_template % { 'NOM_zone' : zone, 'FICHIER_zone' : path }
### Ecriture fichier de définition
### Ecriture fichier de définition
fd = self._open_conf(self.DNS_CONF,'//')
fd.write(f)
fd.close()
@ -535,13 +535,13 @@ if __name__ == '__main__' :
from config import bcfg2_main
hostname = short_name(gethostname())
if hostname == short_name(bcfg2_main):
print "Reconfiguration du fichier de BCfg2 pour configurer le bind d'un serveur en esclave (pensez à lancer bcfg2 sur les esclaves)."
print "Reconfiguration du fichier de BCfg2 pour configurer le bind d'un serveur en esclave (pensez à lancer bcfg2 sur les esclaves)."
c = dns()
c.gen_slave()
if hostname == short_name(dns.DNSs[0]):
print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate."
print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate."
elif hostname == short_name(dns.DELEG['tv.crans.org'][0][0:-1]):
print "Serveur ma�tre pour tv.crans.org, génération de la zone"
print "Serveur maᅵtre pour tv.crans.org, génération de la zone"
c = dns()
c.gen_tv()
import subprocess
@ -551,10 +551,10 @@ if __name__ == '__main__' :
print ret[0].strip()
print ret[1].strip()
if hostname == short_name(dns.DNSs[0]):
print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate."
print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate."
elif hostname == short_name(dns.DNSs[0]):
print "Ce serveur est maître ! Utilisez generate."
print "Ce serveur est maître ! Utilisez generate."
elif hostname in map(lambda fullhostname : short_name(fullhostname),dns.DNSs[1:]+dns.DNSs_private):
print "Ce serveur est esclave! Lancez ce script sur %s, puis lancez bcfg2 ici" % bcfg2_main
else:
print "Ce serveur ne correspond à rien pour la configuration DNS."
print "Ce serveur ne correspond à rien pour la configuration DNS."