[surveillance/analyse] Un script tout beau, tout neuf, et adapté

This commit is contained in:
Pierre-Elliott Bécue 2014-06-18 17:19:57 +02:00
parent c4c142686d
commit 7da7390665
3 changed files with 634 additions and 148 deletions

View file

@ -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)