
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.
93 lines
3.1 KiB
Python
Executable file
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()
|