diff --git a/gestion/config/mails/upload.py b/gestion/config/mails/upload.py index 511cce81..6ab48ffc 100644 --- a/gestion/config/mails/upload.py +++ b/gestion/config/mails/upload.py @@ -30,6 +30,8 @@ Ses machines ont été aperçues pour la dernière fois à ces endroits : La chambre de l'adhérent est %(chambre)s. +analyse.py devrait bientôt avoir généré un fichier que vous pourrez lui envoyer en cas de demande. Le fichier sera dans le dossier /usr/scripts/var/. + --\u0020 Message créé par deconnexion.py diff --git a/surveillance/analyse2.py b/surveillance/analyse2.py new file mode 100755 index 00000000..12c75587 --- /dev/null +++ b/surveillance/analyse2.py @@ -0,0 +1,480 @@ +#!/bin/bash /usr/scripts/python.sh +# -*- encoding: utf-8 -*- + +import socket +import sys +import re +import psycopg2 +import psycopg2.extras +import gestion.affichage as affichage +import lc_ldap.shortcuts +import argparse +import time +import gestion.config as config +import subprocess + +ldap = lc_ldap.shortcuts.lc_ldap_readonly() +encoding = "UTF-8" + +def get_stats(args): + output = pretty_header(args) + "\n" + output += u"Période considérée : du %s au %s.\n" % (args.begin, args.end) + output += u"Attention, l'upload total et le download total sont calculés sur les %s plus grosses entrées." % (args.limit) + + if not args.fichier: + print output.encode(encoding) + output = u"" + else: + output += u"\n" + pgsql = psycopg2.connect(database='filtrage', user='crans') + pgsql.set_session(autocommit=True) + curseur = pgsql.cursor(cursor_factory=psycopg2.extras.DictCursor) + ip_requete = """ +SELECT + SUM(upload) as tot_upload, + SUM(download) as tot_download, + mac, + ip_crans, + ip_ext, + port_crans, + port_ext +FROM ( + ( + SELECT + sum(bytes) as upload, + '0' as download, + mac_src as mac, + ip_src as ip_crans, + ip_dst as ip_ext, + port_src as port_crans, + port_dst as port_ext + FROM + upload + LEFT JOIN + machines + ON + machines.mac_addr = upload.mac_src + WHERE + ip_src=%(pg_value)s + AND NOT + ip_src <<= inet%(ipv6_local)s + AND NOT + ip_dst <<= inet%(ipv6_local)s + AND NOT + ip_dst <<= inet%(plage_ens)s + AND NOT + ip_dst <<= inet%(appt)s + AND NOT + ip_dst <<= inet%(plage_ipv6)s + AND + stamp_inserted >= %(begin)s + AND + stamp_updated <= %(end)s + GROUP BY + mac, + ip_crans, + ip_ext, + port_crans, + port_ext + ) + UNION + ( + SELECT + '0' as upload, + sum(bytes) as download, + mac_dst as mac, + ip_dst as ip_crans, + ip_src as ip_ext, + port_dst as port_crans, + port_src as port_ext + FROM + upload + LEFT JOIN + machines + ON + machines.mac_addr = upload.mac_dst + WHERE + ip_dst=%(pg_value)s + AND NOT + ip_src <<= inet%(ipv6_local)s + AND NOT + ip_dst <<= inet%(ipv6_local)s + AND NOT + ip_src <<= inet%(plage_ens)s + AND NOT + ip_src <<= inet%(appt)s + AND NOT + ip_src <<= inet%(plage_ipv6)s + AND + stamp_inserted >= %(begin)s + AND + stamp_updated <= %(end)s + GROUP BY + mac, + ip_crans, + ip_ext, + port_crans, + port_ext + ) + ) +AS + famille +GROUP BY + mac, + ip_crans, + ip_ext, + port_crans, + port_ext +""" + mac_requete = """ +SELECT + SUM(upload) as tot_upload, + SUM(download) as tot_download, + mac, + ip_crans, + ip_ext, + port_crans, + port_ext +FROM ( + ( + SELECT + sum(bytes) as upload, + '0' as download, + mac_src as mac, + ip_src as ip_crans, + ip_dst as ip_ext, + port_src as port_crans, + port_dst as port_ext + FROM + upload + LEFT JOIN + machines + ON + machines.mac_addr = upload.mac_src + WHERE + machines.mac_addr=%(pg_value)s + AND NOT + ip_src <<= inet%(ipv6_local)s + AND NOT + ip_dst <<= inet%(ipv6_local)s + AND NOT + ip_dst <<= inet%(plage_ens)s + AND NOT + ip_dst <<= inet%(appt)s + AND NOT + ip_dst <<= inet%(plage_ipv6)s + AND + stamp_inserted >= %(begin)s + AND + stamp_updated <= %(end)s + GROUP BY + mac, + ip_crans, + ip_ext, + port_crans, + port_ext + ) + UNION + ( + SELECT + '0' as upload, + sum(bytes) as download, + mac_dst as mac, + ip_dst as ip_crans, + ip_src as ip_ext, + port_dst as port_crans, + port_src as port_ext + FROM + upload + LEFT JOIN + machines + ON + machines.mac_addr = upload.mac_dst + WHERE + machines.mac_addr=%(pg_value)s + AND NOT + ip_src <<= inet%(ipv6_local)s + AND NOT + ip_dst <<= inet%(ipv6_local)s + AND NOT + ip_src <<= inet%(plage_ens)s + AND NOT + ip_src <<= inet%(appt)s + AND NOT + ip_src <<= inet%(plage_ipv6)s + AND + stamp_inserted >= %(begin)s + AND + stamp_updated <= %(end)s + GROUP BY + mac, + ip_crans, + ip_ext, + port_crans, + port_ext + ) + ) +AS + famille +GROUP BY + mac, + ip_crans, + ip_ext, + port_crans, + port_ext +""" + adh_requete = """ +SELECT + SUM(upload) as tot_upload, + SUM(download) as tot_download, + mac, + ip_crans, + ip_ext, + port_crans, + port_ext +FROM ( + ( + SELECT + sum(bytes) as upload, + '0' as download, + mac_src as mac, + ip_src as ip_crans, + ip_dst as ip_ext, + port_src as port_crans, + port_dst as port_ext + FROM + upload + LEFT JOIN + machines + ON + machines.mac_addr = upload.mac_src + WHERE + machines.type=%(pg_filter)s + AND + machines.id=%(pg_value)s + AND NOT + ip_src <<= inet%(ipv6_local)s + AND NOT + ip_dst <<= inet%(ipv6_local)s + AND NOT + ip_dst <<= inet%(plage_ens)s + AND NOT + ip_dst <<= inet%(appt)s + AND NOT + ip_dst <<= inet%(plage_ipv6)s + AND + stamp_inserted >= %(begin)s + AND + stamp_updated <= %(end)s + GROUP BY + mac, + ip_crans, + ip_ext, + port_crans, + port_ext + ) + UNION + ( + SELECT + '0' as upload, + sum(bytes) as download, + mac_dst as mac, + ip_dst as ip_crans, + ip_src as ip_ext, + port_dst as port_crans, + port_src as port_ext + FROM + upload + LEFT JOIN + machines + ON + machines.mac_addr = upload.mac_dst + WHERE + machines.type=%(pg_filter)s + AND + machines.id=%(pg_value)s + AND NOT + ip_src <<= inet%(ipv6_local)s + AND NOT + ip_dst <<= inet%(ipv6_local)s + AND NOT + ip_src <<= inet%(plage_ens)s + AND NOT + ip_src <<= inet%(appt)s + AND NOT + ip_src <<= inet%(plage_ipv6)s + AND + stamp_inserted >= %(begin)s + AND + stamp_updated <= %(end)s + GROUP BY + mac, + ip_crans, + ip_ext, + port_crans, + port_ext + ) + ) +AS + famille +GROUP BY + mac, + ip_crans, + ip_ext, + port_crans, + port_ext +""" + if args.download: + mac_requete += "ORDER BY tot_download DESC" + ip_requete += "ORDER BY tot_download DESC" + adh_requete += "ORDER BY tot_download DESC" + down_color = "rouge" + up_color = "vert" + else: + mac_requete += "ORDER BY tot_upload DESC" + ip_requete += "ORDER BY tot_upload DESC" + adh_requete += "ORDER BY tot_upload DESC" + down_color = "vert" + up_color = "rouge" + + mac_requete += " LIMIT %s" % (args.limit) + ip_requete += " LIMIT %s" % (args.limit) + adh_requete += " LIMIT %s" % (args.limit) + + fill_in_dict = { + "begin" : args.begin, + "end" : args.end, + "plage_ens" : config.plage_ens, + "ipv6_local" : 'fe80::/8', + "plage_ipv6" : config.prefix['subnet'][0], + "appt" : config.NETs['personnel-ens'][0], + } + + if args.aid: + pg_filter = "adherent" + pg_value = int(args.aid) + fill_in_dict.update({'pg_filter' : pg_filter, 'pg_value' : pg_value}) + curseur.execute(adh_requete, fill_in_dict) + elif args.cid: + pg_filter = "adherent" + pg_value = int(args.cid) + fill_in_dict.update({'pg_filter' : pg_filter, 'pg_value' : pg_value}) + curseur.execute(adh_requete, fill_in_dict) + elif args.ip: + print "Attention, les statistiques par IP sont une mauvaise idée depuis que les extensions de vie privée IPv6 sont actives." + pg_value = args.ip + fill_in_dict.update({'pg_value' : pg_value}) + curseur.execute(ip_requete, fill_in_dict) + elif args.mac: + pg_value = args.mac + fill_in_dict.update({'pg_value' : pg_value}) + curseur.execute(mac_requete, fill_in_dict) + else: + pg_value = ldap.search(u"(host=%s)" % (args.data))[0]['macAddress'][0].value + if pg_value == '': + print "MAC de la machine %s fixée à %s, problème. :o" % (args.data, pg_value) + fill_in_dict.update({'pg_value' : pg_value}) + curseur.execute(mac_requete, fill_in_dict) + stats = curseur.fetchall() + + peuplade_ip = {} + def convert_ip(ip): + host = peuplade_ip.get(ip, []) + if host: + return host + else: + peuplade_ip[ip] = socket.getfqdn(ip) + return peuplade_ip[ip] + + if args.dns: + convert = lambda ip:convert_ip(ip) + else: + convert = lambda ip:ip + + if not args.fichier or args.couleur: + styles = (None, None, None, None, None, down_color, up_color) + else: + styles = None + entete = [u"Mac", u"Ip_crans", u"Ip_ext", u"Port_crans", u"Port_ext", unicode("Download (Mio)"), unicode("Upload (Mio)")] + longueur = [17, '*', '*', 10, 8, 14, 14] + format = ('s', 's', 's', 's', 's', 'o', 'o') + data = [[unicode(ligne['mac']), unicode(convert(ligne['ip_crans'])), unicode(convert(ligne['ip_ext'])), unicode(ligne['port_crans']), unicode(ligne['port_ext']), unicode(ligne["tot_download"]), unicode(ligne["tot_upload"])] for ligne in stats] + final_data = affichage.tableau(data, titre=entete, largeur=longueur, styles=styles, format=format) + + output += u"Upload total : %s Mio, download total : %s Mio\n" % (sum([int(ligne["tot_upload"]) for ligne in stats])/1024/1024, sum([int(ligne["tot_download"]) for ligne in stats])/1024/1024) + output += final_data + + if not args.fichier: + print output.encode(encoding) + else: + with open(args.fichier, 'w') as fichier: + fichier.write(output.encode(encoding)) + +def pretty_header(args): + if args.aid: + adh = ldap.search(u"(aid=%s)" % (args.aid))[0] + prenom = unicode(adh['prenom'][0]) + nom = unicode(adh['nom'][0]) + good_sentence = u"Statistiques d'upload de %s %s" % (prenom, nom) + elif args.cid: + club = ldap.search(u"(cid=%s)" % (args.cid))[0] + prenom = "club" + nom = unicode(club['nom'][0]) + good_sentence = u"Statistiques d'upload du %s %s" % (prenom, nom) + elif args.ip: + machine = ldap.search(u"(|(ipHostNumber=%(val)s)(ip6HostNumber=%(val)s))" % {'val' : args.ip})[0] + nom = unicode(machine['host'][0]) + good_sentence = u"Statistiques d'upload de la machine %s" % (nom) + elif args.mac: + machine = ldap.search(u"(macAddress=%s)" % (args.mac))[0] + nom = unicode(machine['host'][0]) + good_sentence = u"Statistiques d'upload de la machine %s" % (nom) + else: + machine = ldap.search(u"(host=%s)" % (args.data))[0] + nom = unicode(machine['host'][0]) + good_sentence = u"Statistiques d'upload de la machine %s" % (nom) + if not args.fichier or args.couleur: + return affichage.style(good_sentence, 'gras') + return good_sentence + +def self_call(args): + args = ["/usr/scripts/surveillance/analyse2.py"] + args + print args + subprocess.Popen(args, stdout=subprocess.PIPE) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Script d'analyse d'échange de données entre un truc et un autre.", add_help=False) + meg = parser.add_mutually_exclusive_group() + meg.add_argument("-a", "--aid", help="Rechercher tout l'upload d'un adhérent. Il ne faut pas renseigner data si on utilise cette option.", action="store", type=int) + parser.add_argument("-b", "--begin", help="Date de début, dans un format \"AAAA/MM/JJ HH:MM:SS\"", type=str, action="store") + meg.add_argument("-c", "--cid", help="Rechercher tout l'upload d'un club. Il ne faut pas renseigner data si on utilise cette option.", action="store", type=int) + parser.add_argument("-C", "--couleur", help="Force la présence des couleurs et styles, y compris avec -f.", action="store_true") + parser.add_argument("-d", "--download", help="Trier par download décroissant", action="store_true") + parser.add_argument("-e", "--end", help="Date de fin, dans un format \"AAAA/MM/JJTHH:MM:SS\"", type=str, action="store") + parser.add_argument("-f", "--fichier", help="Sauvegarder le résultat de la recherche dans le fichier FILE. Désactive les fonctions de style (couleur...)", type=str, action="store") + parser.add_argument("-h", "--help", help="Affiche cette aide et quitte.", action="store_true") + meg.add_argument("-i", "--ip", help="Filtrer sur l'ip fournie. Format IPv4 ou IPv6. Il ne faut pas renseigner data si on utilise cette option.", action="store", type=str) + parser.add_argument("-l", "--limit", help="Limiter le nombre de résultats.", action="store", type=int) + meg.add_argument("-m", "--mac", help="Filtrer sur la mac fournie. Format \"aa:bb:cc:dd:ee:ff\". Il ne faut pas renseigner data si on utilise cette option.", action="store", type=str) + parser.add_argument("-w", "--dns", help="Forcer la résolution dns des IP lorsque c'est possible. Attention, c'est gourmand en temps.", action="store_true") + meg.add_argument("data", help="La donnée suivant laquelle rechercher. Si pas d'autre option, doit être renseigné à un nom de machine.", type=str, nargs='?') + + args = parser.parse_args() + now = time.time() + + if args.help: + parser.print_help() + sys.exit(0) + if not (args.data or args.aid or args.cid or args.ip or args.mac): + print "Il faut fournir un nom de machine, ou autre." + parser.print_help() + sys.exit(7) + if not args.begin: + args.begin = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(now - 86400)) + if not args.end: + args.end = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(now)) + if not args.download: + args.download = False + if not args.limit: + args.limit = 1000 + get_stats(args) diff --git a/surveillance/deconnexion.py b/surveillance/deconnexion.py index e0893464..17db0b5f 100755 --- a/surveillance/deconnexion.py +++ b/surveillance/deconnexion.py @@ -34,7 +34,7 @@ import lock sys.path.append('/usr/scripts/surveillance/fiche_deconnexion') from generate import generate_ps from affich_tools import tableau -import analyse +import analyse2 as analyse import mail as mail_module @@ -110,7 +110,7 @@ FROM ( WHERE stamp_updated > now() - interval '1 day' AND stamp_updated < now() - AND NOT (ip_dst <<= inet%(plage_ens)s OR ip_dst <<= inet%(plage_ipv6)s OR ip_dst <<= inet%(appt)s) + AND NOT (ip_dst <<= inet%(plage_ens)s OR ip_dst <<= inet%(plage_ipv6)s OR ip_dst <<= inet%(appt)s OR ip_src <<= inet%(ipv6_local)s OR ip_src='0.0.0.0') AND (ip_src <<= inet%(allone)s OR ip_src <<= inet%(alltwo)s OR ip_src <<= inet%(plage_ipv6)s OR ip_src <<= inet%(appt)s) AND NOT EXISTS ( @@ -138,7 +138,7 @@ GROUP BY ORDER BY tot_upload; """ -curseur.execute(requete, {'plage_ens':plage_ens, 'allone':NETs['all'][0], 'alltwo':NETs['all'][1], 'plage_ipv6':prefix['subnet'][0], 'appt':NETs['personnel-ens'][0],}) +curseur.execute(requete, {'plage_ens':plage_ens, 'allone':NETs['all'][0], 'alltwo':NETs['all'][1], 'plage_ipv6':prefix['subnet'][0], 'appt':NETs['personnel-ens'][0], 'ipv6_local':'fe80::/8'}) uploadeurs = curseur.fetchall() @@ -170,8 +170,10 @@ for elupload, eltype, elid in uploadeurs: ########################### if eltype == 'club': proprio = ldap.search('cid=%d'%elid, 'w')['club'] + self_call_type = "cid" elif eltype == 'adherent': proprio = ldap.search('aid=%d'%elid, 'w')['adherent'] + self_call_type = "aid" else: continue @@ -199,13 +201,15 @@ for elupload, eltype, elid in uploadeurs: ############### debut = int(time()) fin = debut + 24*3600 + orig = strftime("%Y/%m/%d %H:%M:%S", localtime(debut - 86400)) + end = strftime("%Y/%m/%d %H:%M:%S", localtime(debut)) try: proprio.blacklist([debut, fin, 'autodisc_upload', "Déconn auto. %s Mo" % elupload]) proprio.save() # On inscrit l'instance dans la table des avertis_hard ###################################################### curseur.execute("INSERT INTO avertis_upload_hard (type,id,date) VALUES ('%s','%d','now')"%(eltype,elid)) - #analyse.stats_fork('-%s' % debut, ip_crans=[m.ip() for m in proprio.machines()], show_limit=1000) + analyse.self_call(["--%s" % (self_call_type), "%s" % (elid), "--begin", "%s" % (orig), "--end", "%s" % (end), "--limit", "1000", "--fichier", "/usr/scripts/var/analyse/%s_%s_%s.txt" % (end.replace("/", "_").replace(":", "_").replace(" ", "_"), self_call_type, elid)]) except Exception as error: sys.stderr.write("Blacklist de id=%s pour %s Mo échoué, %s\n" % (proprio.id(), elupload, error)) continue @@ -287,147 +291,147 @@ curseur.execute("DELETE FROM avertis_upload_hard WHERE date < timestamp 'now' - curseur.execute("DELETE FROM avertis_upload_soft WHERE date < timestamp 'now' - interval '1 day'") ################################################################################ -# Détection de l'existence de virus # -################################################################################ - -# Dans la table virus on sélectionne les ip_src qui appartiennent au réseau -requete = "SELECT ip_src,count(ip_src) FROM virus WHERE %s and date > timestamp 'now' - interval '1 hour' group by ip_src" % ip_src_in_crans -curseur.execute(requete) -infectes = curseur.fetchall() - -# Récupération des infectés pour ne pas les reblacklister -requete = "SELECT ip_crans FROM avertis_virus" -curseur.execute(requete) -infectes_old = curseur.fetchall() - -for ip, nombre in infectes: - - # Si on est en dessous du seuil, on laisse passer - if nombre < virus.virus: - continue - - # Si on est déja avertis, on laisse passer - if (ip) in infectes_old: - continue - - # Lecture des infos de ldap - machine = ldap.search('ipHostNumber=%s' % ip, 'w' )['machine'][0] - hostname = machine.nom() - proprio = machine.proprietaire() - blacklist = proprio.blacklist() - - # Inscription dans la table des infectés - requete = "INSERT INTO avertis_virus (ip_crans,date) VALUES ('%s','now')" % ip - curseur.execute(requete) - - # On récupère les index des lignes de bl où il y a marqué virus - index = [blacklist.index(x) for x in blacklist if 'autodisc_virus' in x ] - if index: - # L'adhérent est déjà blacklisté - proprio.blacklist((index[0], ['now', '-', 'autodisc_virus', hostname])) - proprio.save() - else: - # L'adhérent n'est pas encore blacklisté - proprio.blacklist(['now', '-', 'autodisc_virus', hostname]) - proprio.save() - -################################################################################ -# Détection des virus qui floodent # -################################################################################ - -# Dans la table virus on sélectionne les ip_src qui appartiennent au réseau -requete = "SELECT ip_src,count(ip_src) FROM flood WHERE %s and date > timestamp 'now' - interval '1 hour' GROUP BY ip_src" % ip_src_in_crans -curseur.execute(requete) -infectes = curseur.fetchall() - -# Récupération des infectés pour ne pas les reblacklister -requete = "SELECT ip_crans FROM avertis_virus" -curseur.execute(requete) -infectes_old = curseur.fetchall() - -for ip, nombre in infectes: - - # Si on est en dessous du seuil, ou qu'on est déjà averti, on laisse passer - if nombre < virus.flood or (ip) in infectes_old: - continue - - # Lecture des infos de ldap - try : - machine = ldap.search('ipHostNumber=%s' % ip, 'w' )['machine'][0] - except IndexError : - # Dans le cas où l'ip détectée n'est pas enregistrée - print "La machine avec l'ip %s n'est pas declaree !" % ip - continue - hostname = machine.nom() - proprio = machine.proprietaire() - blacklist = proprio.blacklist() - - # Inscription dans la table des infectés - requete = "INSERT INTO avertis_virus (ip_crans,date) VALUES ('%s','now')" % ip - curseur.execute(requete) - - # On récupère les index des lignes de bl où il y a marqué virus - index = [ blacklist.index(x) for x in blacklist if 'autodisc_virus' in x ] - try: - if index: - # L'adhérent est déjà blacklisté - proprio.blacklist((index[0], ['now', '-', 'autodisc_virus', hostname])) - proprio.save() - else: - # L'adhérent n'est pas encore blacklisté - proprio.blacklist(['now', '-', 'autodisc_virus', hostname]) - proprio.save() - except ValueError: # On a essayé de blacklister un proporiétaire virtuel - pass # Le message d'erreur a déjà été affiché (changer ça ?) - - -# Reconnexion si le virus/flood a disparu -######################################### - -# Dans la table avertis_virus on récupère la liste des infectés -requete = "SELECT ip_crans FROM avertis_virus where date < timestamp 'now' - interval '1 hour'" -curseur.execute(requete) -infectes = [ x[0] for x in curseur.fetchall() ] - -for IP in infectes: - - # Nombre de requêtes de virus - requete1 = "SELECT COUNT(ip_src) FROM virus where ip_src='%s' and date > timestamp 'now' - interval '1 hour'" % IP - curseur.execute(requete1) - nb_virus = curseur.fetchall() - - # Nombre de requêtes de flood - requete2 = "SELECT COUNT(ip_src) FROM flood where ip_src='%s' and date > timestamp 'now' - interval '1 hour'" % IP - curseur.execute(requete2) - nb_flood = curseur.fetchall() - - # On ne traite que les IP qui sont descendues en dessous des seuils - if nb_virus[0][0] < virus.virus and nb_flood[0][0] < virus.flood: - try: - machine = ldap.search('ipHostNumber=%s' % IP, 'w' )['machine'][0] - except IndexError: - print "Suppression de %s des machines infectees (la machine n'existe plus)"%IP - requete = "DELETE FROM avertis_virus where ip_crans='%s'"%IP - curseur.execute(requete) - continue # la machine n'existe plus, on passe à l'infecté suivant - # Si la machine n'est pas online, on reconnecte - #if machine_online(machine): - proprio = machine.proprietaire() - bl = proprio.blacklist() - hostname = machine.nom() - # On stoppe la sanction pour une ligne existante de la blackliste - # En prenant en compte le fait que d'autres lignes de blackliste - # ont pu s'ajouter. - lignes_enlevees = 0 - for ligne in bl: - if '$-$autodisc_virus$%s' % hostname in ligne: - liste = ligne.split('$') - argument = [liste[0], 'now', liste[2], liste[3]] - index = bl.index(ligne) - proprio.blacklist((index, argument)) - proprio.save() - lignes_enlevees += 1 - if lignes_enlevees == 0: - print "Suppression de %s des machines infectees, mais aucune blackliste"%hostname - requete = "DELETE FROM avertis_virus where ip_crans='%s'"%IP - curseur.execute(requete) +## Détection de l'existence de virus # +################################################################################# +# +## Dans la table virus on sélectionne les ip_src qui appartiennent au réseau +#requete = "SELECT ip_src,count(ip_src) FROM virus WHERE %s and date > timestamp 'now' - interval '1 hour' group by ip_src" % ip_src_in_crans +#curseur.execute(requete) +#infectes = curseur.fetchall() +# +## Récupération des infectés pour ne pas les reblacklister +#requete = "SELECT ip_crans FROM avertis_virus" +#curseur.execute(requete) +#infectes_old = curseur.fetchall() +# +#for ip, nombre in infectes: +# +# # Si on est en dessous du seuil, on laisse passer +# if nombre < virus.virus: +# continue +# +# # Si on est déja avertis, on laisse passer +# if (ip) in infectes_old: +# continue +# +# # Lecture des infos de ldap +# machine = ldap.search('ipHostNumber=%s' % ip, 'w' )['machine'][0] +# hostname = machine.nom() +# proprio = machine.proprietaire() +# blacklist = proprio.blacklist() +# +# # Inscription dans la table des infectés +# requete = "INSERT INTO avertis_virus (ip_crans,date) VALUES ('%s','now')" % ip +# curseur.execute(requete) +# +# # On récupère les index des lignes de bl où il y a marqué virus +# index = [blacklist.index(x) for x in blacklist if 'autodisc_virus' in x ] +# if index: +# # L'adhérent est déjà blacklisté +# proprio.blacklist((index[0], ['now', '-', 'autodisc_virus', hostname])) +# proprio.save() +# else: +# # L'adhérent n'est pas encore blacklisté +# proprio.blacklist(['now', '-', 'autodisc_virus', hostname]) +# proprio.save() +# +################################################################################# +## Détection des virus qui floodent # +################################################################################# +# +## Dans la table virus on sélectionne les ip_src qui appartiennent au réseau +#requete = "SELECT ip_src,count(ip_src) FROM flood WHERE %s and date > timestamp 'now' - interval '1 hour' GROUP BY ip_src" % ip_src_in_crans +#curseur.execute(requete) +#infectes = curseur.fetchall() +# +## Récupération des infectés pour ne pas les reblacklister +#requete = "SELECT ip_crans FROM avertis_virus" +#curseur.execute(requete) +#infectes_old = curseur.fetchall() +# +#for ip, nombre in infectes: +# +# # Si on est en dessous du seuil, ou qu'on est déjà averti, on laisse passer +# if nombre < virus.flood or (ip) in infectes_old: +# continue +# +# # Lecture des infos de ldap +# try : +# machine = ldap.search('ipHostNumber=%s' % ip, 'w' )['machine'][0] +# except IndexError : +# # Dans le cas où l'ip détectée n'est pas enregistrée +# print "La machine avec l'ip %s n'est pas declaree !" % ip +# continue +# hostname = machine.nom() +# proprio = machine.proprietaire() +# blacklist = proprio.blacklist() +# +# # Inscription dans la table des infectés +# requete = "INSERT INTO avertis_virus (ip_crans,date) VALUES ('%s','now')" % ip +# curseur.execute(requete) +# +# # On récupère les index des lignes de bl où il y a marqué virus +# index = [ blacklist.index(x) for x in blacklist if 'autodisc_virus' in x ] +# try: +# if index: +# # L'adhérent est déjà blacklisté +# proprio.blacklist((index[0], ['now', '-', 'autodisc_virus', hostname])) +# proprio.save() +# else: +# # L'adhérent n'est pas encore blacklisté +# proprio.blacklist(['now', '-', 'autodisc_virus', hostname]) +# proprio.save() +# except ValueError: # On a essayé de blacklister un proporiétaire virtuel +# pass # Le message d'erreur a déjà été affiché (changer ça ?) +# +# +## Reconnexion si le virus/flood a disparu +########################################## +# +## Dans la table avertis_virus on récupère la liste des infectés +#requete = "SELECT ip_crans FROM avertis_virus where date < timestamp 'now' - interval '1 hour'" +#curseur.execute(requete) +#infectes = [ x[0] for x in curseur.fetchall() ] +# +#for IP in infectes: +# +# # Nombre de requêtes de virus +# requete1 = "SELECT COUNT(ip_src) FROM virus where ip_src='%s' and date > timestamp 'now' - interval '1 hour'" % IP +# curseur.execute(requete1) +# nb_virus = curseur.fetchall() +# +# # Nombre de requêtes de flood +# requete2 = "SELECT COUNT(ip_src) FROM flood where ip_src='%s' and date > timestamp 'now' - interval '1 hour'" % IP +# curseur.execute(requete2) +# nb_flood = curseur.fetchall() +# +# # On ne traite que les IP qui sont descendues en dessous des seuils +# if nb_virus[0][0] < virus.virus and nb_flood[0][0] < virus.flood: +# try: +# machine = ldap.search('ipHostNumber=%s' % IP, 'w' )['machine'][0] +# except IndexError: +# print "Suppression de %s des machines infectees (la machine n'existe plus)"%IP +# requete = "DELETE FROM avertis_virus where ip_crans='%s'"%IP +# curseur.execute(requete) +# continue # la machine n'existe plus, on passe à l'infecté suivant +# # Si la machine n'est pas online, on reconnecte +# #if machine_online(machine): +# proprio = machine.proprietaire() +# bl = proprio.blacklist() +# hostname = machine.nom() +# # On stoppe la sanction pour une ligne existante de la blackliste +# # En prenant en compte le fait que d'autres lignes de blackliste +# # ont pu s'ajouter. +# lignes_enlevees = 0 +# for ligne in bl: +# if '$-$autodisc_virus$%s' % hostname in ligne: +# liste = ligne.split('$') +# argument = [liste[0], 'now', liste[2], liste[3]] +# index = bl.index(ligne) +# proprio.blacklist((index, argument)) +# proprio.save() +# lignes_enlevees += 1 +# if lignes_enlevees == 0: +# print "Suppression de %s des machines infectees, mais aucune blackliste"%hostname +# requete = "DELETE FROM avertis_virus where ip_crans='%s'"%IP +# curseur.execute(requete)