#! /usr/bin/env python # -*- coding: iso-8859-15 -*- ########################### # Import des commmandes : # ########################### import commands import sys from pyPgSQL import PgSQL sys.path.append('/usr/scripts/gestion') from config import upload, virus, p2p import smtplib from ldap_crans import crans_ldap, crans, invite, base_classes_crans from time import * # Connections : ############### pgsql = PgSQL.connect(host='/var/run/postgresql', database='filtrage', user='crans') pgsql.autocommit = True mail = smtplib.SMTP('localhost') ldap = crans_ldap() xabi="pessoles@crans.org" ########################################### # Vérification de l'upload et du download # ########################################### # Déclaration du curseur : ########################## curseur = pgsql.cursor() # Table des uploaders : ####################### requete = "SELECT round(sum(upload)/1024/1024) as total,ip_crans from upload where upload>download and date>timestamp 'now' - interval '1 day' and date<'now' and NOT EXISTS ( select 1 from exemptes where upload.ip_crans<<=exemptes.ip_crans and upload.ip_ext<<=exemptes.ip_dest) group by ip_crans order by total desc" curseur.execute(requete) table = curseur.fetchall() # Table des avertis ################### requete = "SELECT ip_crans FROM avertis_upload where hard='1' and date>timestamp 'now' - interval '1 day'" curseur.execute(requete) avertish = curseur.fetchall() requete = "SELECT ip_crans FROM avertis_upload where soft='1' " curseur.execute(requete) avertiss = curseur.fetchall() # Vérification : ################ for i in range(0,len(table)) : elupload = int(table[i][0]) IP = table[i][1].encode('iso 8859-15') # On regarde si c'est de l'upload hard if elupload >= upload.hard : # L'adhérent a t il été averti ? if [IP] not in avertish: machine = ldap.search('ipHostNumber=%s' % IP,'w')['machine'][0] hostname = machine.nom() proprio = machine.proprietaire() aid = machine.id() if proprio.__class__ != crans and proprio.__class__ != invite: # On inscrit l'ip dans la table des avertis ########################################### inscription = "INSERT INTO avertis_upload (ip_crans,date,hard) VALUES ('%s','now','1')" % IP curseur.execute(inscription) # On sanctionne : ################# date = time() #debut = localtime(date+60*60*24*200)#test debut = localtime(date) #fin = localtime(date+60*60*24*300)#test fin = localtime(date+60*60*24) proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],debut[3],debut[4]),"%d/%d/%d %d:%d" % (fin[2],fin[1],fin[0],fin[3],fin[4]),'autodisc',"Déconn auto. %s Mo" % elupload]) proprio.save() # On récupere l'adresse électronique : ###################################### proprio = proprio.mail() if '@' not in proprio : proprio += '@crans.org' else: proprio = 'roots@crans.org' corps = upload.hardmessage % { 'From': upload.expediteur, 'To': proprio, 'upload': elupload, 'hostname': hostname } corps = corps.encode('iso 8859-15') # On envoie un mail a l'adhérent mail.sendmail(upload.expediteur,proprio,corps) # On envoie un mail à disconnect corps = upload.deconnexion % { 'From': upload.expediteur, 'To': upload.expediteur, 'upload': elupload, 'hostname': hostname } corps = corps.encode('iso 8859-15') mail.sendmail(upload.expediteur,upload.expediteur,corps) # Est ce de l'upload soft ? elif elupload >= upload.soft : # L'adhérent a-t-il déjà été averti ? if [IP] not in avertiss: # On lui envoie un mail et on l'inscrit machine = ldap.search('ipHostNumber=%s' % IP )['machine'][0] hostname = machine.nom() proprio = machine.proprietaire().mail() if '@' not in proprio : proprio += '@crans.org' corps = upload.softmessage % { 'From': upload.expediteur, 'To': proprio, 'upload': elupload, 'hostname':hostname } corps = corps.encode('iso 8859-15') mail.sendmail(upload.expediteur,proprio,corps) # On envoie un mail à disconnect corps = upload.avertissement % { 'From': upload.expediteur, 'To': upload.expediteur, 'upload': elupload, 'hostname': hostname} corps = corps.encode('iso 8859-15') mail.sendmail(upload.expediteur,upload.expediteur,corps) # On inscrit l'ip dans la table des avertis inscription = "INSERT INTO avertis_upload (ip_crans,date,soft) VALUES ('%s','now','1')" % IP curseur.execute(inscription) # Changement de statut des uploders (Ainsi, les gens ne recoivent des mails qu'une fois et on a en memoire les uplaods) requete="UPDATE avertis_upload set hard='f' where hard='t' and date < timestamp ' now' - interval '1 day'" curseur.execute(requete) requete="UPDATE avertis_upload set soft='f' where soft='t' and date < timestamp 'now' - interval '1 day'" curseur.execute(requete) ############################## # Blackliste des uploaders : # ############################## # Sélection des uploaders du dernier mois #requete = "SELECT ip_crans FROM avertis_upload WHERE hard='f' AND date>timestamp 'now' - interval '1 month' ORDER BY ip_crans" #curseur.execute(requete) #sanctions = curseur.fetchall() #for i in range(0,len(sanctions)-2): # Vu que l'on a classé la requete par IP successive, # si il y a 3 IP identiques à la suite, on sanctionne # if sanctions[i][0]==sanctions[i+1][1]==sanctions[i+2][0]: # Récupération de l'aid # IP=sanction[i][0] # machine = ldap.search('ipHostNumber=%s' % IP,'w')['machine'][0] # proprio=machine.proprietaire() # aid=machine.id() # On cherche des occurences dans la base des sanctions : # requete="SELECT penalite FROM sanctions WHERE aid='%s'" % aid # curseur.execute(requete) # resultat=curseur.fetchall() # Les uploaders sont rangés dans la colonne sanction et sont sortis de la colonne hard # requete = "UPDATE avertis_upload SET hard='0' and sanctions='1' WHERE ip_crans='%s'"%IP # C'est la premiere fois qu'il uploade 3 fois dans le mois : ############################################################ # if resultat[0][0]==[]: # # Inscription dans la base psql # requete="INSER INTO sanctions (date,aid,penalite) VALUES ('now','%s',1)" # curseur.execute(requete) # Sanction sur la base ldap # date = time() # debut = localtime(date) # fin = localtime(date+60*60*24*15) # proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],debut[3],debut[4]),"%d/%d/%d %d:%d" % (fin[2],fin[1],fin[0],fin[3],fin[4]),'upload',"TESTS : upload de %s Mo" % elupload]) # proprio.save() #MAILS ###### # else : # penalite=int(resultat[0][0]) # if penalite == 1: # Inscription dans la base psql # requete="UPDATE sanctions set penalite=2 WHERE aid='%s'" %aid # curseur.execute(requete) # Sanction sur la base ldap # date = time() # debut = localtime(date) # fin = localtime(date+60*60*24*15) # proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],debut[3],debut[4]),"%d/%d/%d %d:%d" % (fin[2],fin[1],fin[0],fin[3],fin[4]),'upload',"TESTS : upload de %s Mo" % elupload]) # proprio.save() # MAILS ######## # elif penalite == 2: # # Inscription dans la base psql # requete="UPDATE sanctions set penalite=3 WHERE aid='%s'" %aid # curseur.execute(requete) # # Sanction sur la base ldap # date = time() # debut = localtime(date) # fin = localtime(date+60*60*24*30) # # proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],debut[3],debut[4]),"%d/%d/%d %d:%d" % (fin[2],fin[1],fin[0],fin[3],fin[4]),'upload'," TESTS upload de %s Mo" % elupload]) # # proprio.save() # # MAILS # ######## ############################################### # Détection de l'existence de virus ou de P2P # ############################################### # VIRUS ######## # Dans le table virus on sélectionne les ip_src qui appartiennent au reseau requete = "SELECT ip_src FROM virus WHERE (ip_src<<=inet('138.231.136.0/21') or ip_src<<=inet('138.231.148.0/22')) and date > timestamp 'now' - interval '1 hour' order by ip_src" curseur.execute(requete) veroles = curseur.fetchall() # Recuperation des infectes pour ne pas les reblacklister requete = "SELECT ip_crans FROM avertis_virus" curseur.execute(requete) infectes = curseur.fetchall() ip1=str('0.0.0.0') N=0 if veroles: ip1=veroles[0][0] for i in range(0,len(veroles)): ip=veroles[i][0] if ip != ip1 : ip1=ip N=0 else : N=N+1 if N >= virus.virus and [ip] not in infectes: # Recuperation des infectes pour ne pas les reblacklister machine = ldap.search('ipHostNumber=%s' % ip,'w' )['machine'][0] hostname = machine.nom() proprio = machine.proprietaire() # Inscription dans la table des infectes requete="INSERT INTO avertis_virus (ip_crans,date) VALUES ('%s','now')" % ip1 curseur.execute(requete) requete = "SELECT ip_crans FROM avertis_virus" curseur.execute(requete) infectes = curseur.fetchall() # Blacklistage date = time() debut = localtime(date) proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],debut[3],debut[4]),'-','virus',"Virus (auto)"]) proprio.save() # Flood ######## # Dans le table virus on sélectionne les ip_src qui appartiennent au reseau requete = "SELECT ip_src FROM flood WHERE (ip_src<<=inet('138.231.136.0/21') or ip_src<<=inet('138.231.148.0/22')) and date > timestamp 'now' - interval '1 hour' order by ip_src" curseur.execute(requete) veroles = curseur.fetchall() # Recuperation des infectes pour ne pas les reblacklister requete = "SELECT ip_crans FROM avertis_virus " curseur.execute(requete) infectes = curseur.fetchall() ip1=str('0.0.0.0') N=0 if veroles: ip1=veroles[0][0] for i in range(0,len(veroles)): ip=veroles[i][0] if ip != ip1 : ip1=ip N=0 else : N=N+1 if N >= virus.flood and [ip] not in infectes: machine = ldap.search('ipHostNumber=%s' % ip,'w' )['machine'][0] hostname = machine.nom() proprio = machine.proprietaire() # Inscription dans la table des infectes requete="INSERT INTO avertis_virus (ip_crans,date) VALUES ('%s','now')" % ip1 curseur.execute(requete) requete = "SELECT ip_crans FROM avertis_virus" curseur.execute(requete) infectes = curseur.fetchall() # Blacklistage date = time() debut = localtime(date) proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],debut[3],debut[4]),'-','virus',"Virus_flood (auto)"]) proprio.save() # Reconnexion si le virus a disparu ################################### requete = "SELECT ip_crans FROM avertis_virus" curseur.execute(requete) infectes = curseur.fetchall() for i in range(1,len(infectes)): IP=infectes[i][0] 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() 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 traite que les IP qui sont descendues en dessoys des seuils if nb_virus[0][0] < virus.virus and nb_flood[0][0] < virus.flood: machine = ldap.search('ipHostNumber=%s' % IP,'w' )['machine'][0] 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. for ligne in bl: if ',-,virus,' in ligne: liste=ligne.split(',') argument=[liste[0],'now',liste[2],liste[3]] print argument,IP index = bl.index(ligne) proprio.blacklist((index,argument)) proprio.save() requete="DELETE FROM avertis_virus where ip_crans='%s'"%IP # Gestion du P2P : ################## # Dans le table virus on sélectionne les ip_src qui appartiennent au reseau requete = "SELECT ip_src,id_p2p FROM p2p WHERE (ip_src<<=inet('138.231.136.0/21') or ip_src<<=inet('138.231.148.0/22')) and date > timestamp 'now' - interval '1 day' order by ip_src" curseur.execute(requete) pair = curseur.fetchall() # Recuperation des infectes pour ne pas les reblacklister requete = "SELECT ip_crans FROM avertis_p2p WHERE date > timestamp 'now' - interval '1 day'" curseur.execute(requete) avertisp2p = curseur.fetchall() ip1=str('0.0.0.0') if pair : ip1=pair[0][0] for i in range(0,len(pair)): ip=pair[i][0] if ip != ip1 : ip1=ip N=0 else : N=N+1 if N >= p2p.tag and [ip] not in avertisp2p : # Recuperation des ref de la machine machine = ldap.search('ipHostNumber=%s' % ip,'w' )['machine'][0] hostname = machine.nom() proprio = machine.proprietaire() #On récupére le protocole de p2p : protocole=int(pair[i][1]) requete="SELECT nom FROM protocole_p2p WHERE id_p2p=%d" % protocole curseur.execute(requete) protocole = curseur.fetchall() protocole=protocole[0][0] corps = p2p.avertissement % { 'From': upload.expediteur, 'To': upload.expediteur, 'protocole': protocole, 'hostname':hostname} corps = corps.encode('iso 8859-15') mail.sendmail(upload.expediteur,upload.expediteur,corps) #Inscription dans la base des avertis requete="INSERT INTO avertis_p2p (ip_crans,date,protocole) VALUES ('%s','now','%s')" % (ip1,protocole) curseur.execute(requete) requete = "SELECT ip_crans FROM avertis_p2p WHERE date > timestamp 'now' - interval '1 day'" curseur.execute(requete) avertisp2p = curseur.fetchall() # Blacklistage date = time() debut = localtime(date) # 7 jours fin = localtime(date+60*60*24*7) # proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],debut[3],debut[4]),"%d/%d/%d %d:%d" % (fin[2],fin[1],fin[0],fin[3],fin[4]),'p2p',"P2P (auto)" % protocole]) # proprio.save() mail.quit() ########################################## # Destruction des logs de plus de 2 mois # ########################################## requete = "DELETE FROM upload where date< timestamp 'now' - interval '2 month'" curseur.execute(requete) requete = "DELETE FROM virus where date< timestamp 'now' - interval '2 month'" curseur.execute(requete) requete = "DELETE FROM flood where date< timestamp 'now' - interval '2 month'" curseur.execute(requete) requete = "DELETE FROM p2p where date< timestamp 'now' - interval '2 month'" curseur.execute(requete)