diff --git a/gestion/config.py b/gestion/config.py index 304c3c89..fd93095f 100644 --- a/gestion/config.py +++ b/gestion/config.py @@ -116,6 +116,15 @@ cfengine_main = bcfg2_main ISCSI_MAP_FILE = "/usr/scripts/var/iscsi_names.py" ISCSI_MAP_FILE_TEMPLATE = "/usr/scripts/var/iscsi_names_%s.py" +# format: { algorithm : (IANA_id, ssh_algo) } +# où algorithm est tel qu'il apparait dans les fichiers /etc/ssh/ssh_host_%s_key.pub % algorithm +# IANA_id correspond à l'entier attribué par l'IANA pour l'algorithm dans les champs dns SSHFP +# ssh_algo correspond a la première chaine de charactère donnant le nom de l'algorithme de chiffrement lorsque la clef ssh est dans le format openssh (algo key comment) +sshfp_algo = { + "rsa" : (1,"ssh-rsa"), + "dsa" : (2,"ssh-dss"), + } + ## Impression class impression: """Cette classe contient toutes les variables @@ -499,8 +508,8 @@ NETs = { 'serveurs' : [ '138.231.136.0/28' ], 'fil' : [ '138.231.136.0/21' ], 'wifi': [ '138.231.144.0/21' ], 'gratuit': [ '10.42.0.0/16' ], - 'accueil': ['10.51.0.0/16' ], - 'isolement': ['10.52.0.0/16' ], + 'accueil': ['10.51.0.0/16' ], + 'isolement': ['10.52.0.0/16' ], 'personnel-ens': ['10.2.9.0/24' ], 'ens' : ['138.231.135.0/24'], 'all' : [ '138.231.136.0/21', '138.231.148.0/21' ] diff --git a/gestion/gen_confs/bind.py b/gestion/gen_confs/bind.py index 02c652d1..b633d0c7 100644 --- a/gestion/gen_confs/bind.py +++ b/gestion/gen_confs/bind.py @@ -284,16 +284,20 @@ zone "%(NOM_zone)s" { # Le direct if zone in self.zones_direct : ligne = "%s\tIN\tA\t%s\n" % ( nom, machine.ip() ) - # Si la machine est une borne wifi, on ajoute la position + # 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,key]=sshkey.split()[:2] - if algo == "ssh-rsa": algo=1 - elif algo == "ssh-dss": algo=2 - else: raise ValueError("Invalid Algorithms %s" % algo) + [algo_txt,key]=sshkey.split()[:2] + algo=None + for value in config.sshfp_algo.values(): + if algo_txt == value[1]: + algo=value[0] + break + if not algo: + raise ValueError("Invalid Algorithms %s" % algo_txt) key=hashlib.sha1(base64.b64decode(key)).hexdigest() ligne +="%s\tIN\tSSHFP\t%s\t1\t%s\n" % (nom,algo,key) except(ValueError,TypeError): pass diff --git a/gestion/gen_confs/populate_sshFingerprint.py b/gestion/gen_confs/populate_sshFingerprint.py new file mode 100755 index 00000000..84fc0541 --- /dev/null +++ b/gestion/gen_confs/populate_sshFingerprint.py @@ -0,0 +1,64 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +import subprocess +import sys +import os +from socket import gethostname +from netifaces import interfaces, ifaddresses, AF_INET + +sys.path.append('/usr/scripts/lc_ldap') +sys.path.append('/usr/scripts/gestion') +sys.path.append('/etc/crans/secrets/') + +import lc_ldap +import config + +conn=lc_ldap.lc_ldap_admin() + +ssh_algo = config.sshfp_algo.keys() + +def ip4_addresses(): + ip_list = [] + for interface in interfaces(): + if interface!='lo' and AF_INET in ifaddresses(interface).keys(): + for link in ifaddresses(interface)[AF_INET]: + ip_list.append(link['addr']) + return ip_list + +def ssh_keyscan(host,algo): + p=subprocess.Popen(["/usr/bin/ssh-keyscan", "-t", "%s" % algo,"%s" % host],stdout=subprocess.PIPE,stderr=subprocess.PIPE) + ret=p.communicate()[0].split() + key=ret[2] + return key + + +def get_machines(): + machines=[] + for ip in set(ip4_addresses()): + machines.extend(conn.search('ipHostNumber=%s' %ip,mode='rw')) + return machines + +def get_local_keys(): + keys={} + for algo in ssh_algo: + if os.path.isfile('/etc/ssh/ssh_host_%s_key.pub' % algo): + keys[algo]=open('/etc/ssh/ssh_host_%s_key.pub' % algo).read() + return keys + +def check_keys(keys): + return dict([ (algo,key.split()[1] == ssh_keyscan('localhost',algo)) for algo,key in keys.items() ]) + +def publish_keys(): + keys=get_local_keys() + validation=check_keys(keys) + machines=get_machines() + for machine in machines: + sshkeys_old=[key.value for key in machine.get('sshFingerprint',[])] + sshkeys_new=[key.decode('UTF-8') for algo,key in keys.items() if validation[algo]] + if not set(sshkeys_old)==set(sshkeys_new): + machine['sshFingerprint']=sshkeys_new + machine.save() + + +if __name__ == '__main__' : + publish_keys()