#! /usr/bin/env python # -*- coding: utf-8 -*- import subprocess import sys import os import time import base64 import hashlib from socket import gethostname from netifaces import interfaces, ifaddresses, AF_INET sys.path.append('/usr/scripts/') sys.path.append('/usr/scripts/gestion') sys.path.append('/etc/crans/secrets/') import lc_ldap.shortcuts import config conn = lc_ldap.shortcuts.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 ssh_md5_hash(path): key=base64.b64decode(open(path).read().split()[1]) fpr=hashlib.md5(key).hexdigest() return ':'.join(a+b for a,b in zip(fpr[::2], fpr[1::2])) def ssh_keygen(algo,size): new_path='/etc/ssh/new/' if not os.path.isdir(new_path): os.mkdir(new_path) key_path=new_path + 'ssh_host_%s_key' % algo if not os.path.exists(key_path): args=["/usr/bin/ssh-keygen", "-f", "%s" % key_path, "-b", "%s" % size, "-t", "%s" % algo, "-N", ""] p=subprocess.Popen(args,stdout=subprocess.PIPE,stderr=subprocess.PIPE) p.communicate() fpr="Nouvelle clef ssh %s : %s\n" % (algo.upper(),ssh_md5_hash(key_path + '.pub')) open('/etc/motd','a+').write(fpr) print("Nouvelle clef %s générée" % key_path) def get_machines(): machines=[] for ip in set(ip4_addresses()): machines.extend(conn.search('ipHostNumber=%s' %ip,mode='rw')) return machines def check_keys_age(key_path,algo): age=time.time()-os.path.getmtime(key_path) if age > config.sshkey_max_age: print("La clef ssh %s sur %s a plus de %s ans, il faudrait peut être penser à la changer." % (key_path,gethostname(),round(age/(365.25*24*3600),2))) ssh_keygen(algo,config.sshkey_size[algo]) def get_local_keys(): keys={} for algo in ssh_algo: key_path='/etc/ssh/ssh_host_%s_key.pub' % algo if os.path.isfile(key_path): check_keys_age(key_path,algo) keys[algo]=open(key_path).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()