scripts/gestion/gen_confs/populate_sshFingerprint.py

96 lines
3.2 KiB
Python
Executable file

#! /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(user=u'sshfingerprint')
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()
if len(ret)>2:
key=ret[2]
return key
else:
sys.stderr.write("No key for algo %s used by host %s\n" % (algo, host))
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(u'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=[str(key) 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()