scripts/gestion/gen_confs/populate_sshFingerprint.py
Vincent Le Gallic 6946ee5627 [firewall4,populate_sshFingerprint] Plutôt que de s'annoncer en 'root', on précise un user qui permet de savoir quel script accès à la base.
Pour firewall, en fait on s'en fout parce qu'il fait pas d'écriture, mais on laisse le
binding en admin parce que les transactions sont plus rapides et qu'il en fait mâss.
2013-05-16 18:51:49 +02:00

93 lines
3.1 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()
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()