petites modifications pour claircir un peu le code

darcs-hash:20051030121324-4ec08-5e87fbd36e222bd2a0d3ff6dd4810cc5ad83ae32.gz
This commit is contained in:
chove 2005-10-30 13:13:24 +01:00
parent 9e86726964
commit 53a82857e2

View file

@ -1,6 +1,18 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: iso-8859-15 -*-
"""
Script de déconnection automatique des machines du crans pour les raisons :
- upload
- p2p
- flood
- virus
Copyright (C) Xavier Pessoles
Licence : ????
"""
########################### ###########################
# Import des commmandes : # # Import des commmandes : #
########################### ###########################
@ -9,13 +21,13 @@ import commands
import sys import sys
from pyPgSQL import PgSQL from pyPgSQL import PgSQL
sys.path.append('/usr/scripts/gestion') sys.path.append('/usr/scripts/gestion')
from config import upload, virus, p2p from config import upload, virus, p2p, NETs
import smtplib import smtplib
from ldap_crans import crans_ldap, crans, invite, base_classes_crans from ldap_crans import crans_ldap, crans, invite, base_classes_crans
from time import * from time import *
# quelques fonctions # Quelques fonctions
#################### ####################
def machine_online(machine) : def machine_online(machine) :
@ -28,11 +40,24 @@ def machine_online(machine) :
# arping pour les fixes # arping pour les fixes
return not commands.getstatusoutput('/usr/sbin/arping -c 3 %s' % machine.mac())[0] return not commands.getstatusoutput('/usr/sbin/arping -c 3 %s' % machine.mac())[0]
# Variables utiles
##################
# création d'une chaine qui ressemble à : (ip_src<<=inet('138.231.136.0/21') or ip_src<<=inet('138.231.148.0/22'))
ip_src_in_crans = '(%s)' % ' or '.join([ "ip_src<<=inet('%s')" % net for net in NETs['all'] ])
# Connections : # Connections :
############### ###############
# pgsql
pgsql = PgSQL.connect(host='/var/run/postgresql', database='filtrage', user='crans') pgsql = PgSQL.connect(host='/var/run/postgresql', database='filtrage', user='crans')
pgsql.autocommit = True pgsql.autocommit = True
curseur = pgsql.cursor()
# smtp
mail = smtplib.SMTP('localhost') mail = smtplib.SMTP('localhost')
# ldap
ldap = crans_ldap() ldap = crans_ldap()
@ -40,21 +65,21 @@ ldap = crans_ldap()
# Vérification de l'upload et du download # # Vérification de l'upload et du download #
########################################### ###########################################
# Déclaration du curseur :
##########################
curseur = pgsql.cursor()
# Table des uploaders : # 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" 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) curseur.execute(requete)
table = curseur.fetchall() uploadeurs= curseur.fetchall()
# Table des avertis # Table des avertis
################### ###################
# Avertis hard
requete = "SELECT ip_crans FROM avertis_upload where hard='1' and date>timestamp 'now' - interval '1 day'" requete = "SELECT ip_crans FROM avertis_upload where hard='1' and date>timestamp 'now' - interval '1 day'"
curseur.execute(requete) curseur.execute(requete)
avertish = curseur.fetchall() avertish = curseur.fetchall()
# Avertis soft
requete = "SELECT ip_crans FROM avertis_upload where soft='1' " requete = "SELECT ip_crans FROM avertis_upload where soft='1' "
curseur.execute(requete) curseur.execute(requete)
avertiss = curseur.fetchall() avertiss = curseur.fetchall()
@ -62,93 +87,97 @@ avertiss = curseur.fetchall()
# Vérification : # Vérification :
################ ################
for i in range(0,len(table)) : for elupload, IP in uploadeurs :
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 : # On regarde si c'est de l'upload hard
###################################### if elupload >= upload.hard :
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)
# L'adhérent a t il été averti ?
################################
if [IP] in avertish:
continue
# Objets LDAP
#############
machine = ldap.search('ipHostNumber=%s' % IP,'w')['machine'][0]
hostname = machine.nom()
proprio = machine.proprietaire()
mid = machine.id()
# Est ce de l'upload soft ? # On évite de blacklister les proprios spéciaux
elif elupload >= upload.soft : ###############################################
# L'adhérent a-t-il déjà été averti ? if proprio.__class__ == crans or proprio.__class__ == invite:
if [IP] not in avertiss: continue
# 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 # On inscrit l'ip dans la table des avertis
corps = upload.avertissement % { 'From': upload.expediteur, ###########################################
'To': upload.expediteur, inscription = "INSERT INTO avertis_upload (ip_crans,date,hard) VALUES ('%s','now','1')" % IP
'upload': elupload, curseur.execute(inscription)
'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) # On sanctionne
###############
debut = localtime(time())
fin = localtime(time()+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 envoie un mail a l'adhérent
################################
proprio = proprio.mail()
if '@' not in proprio :
proprio += '@crans.org'
corps = upload.hardmessage % { '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
################################
if upload.disconnect_mail_hard :
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:
continue
# On récupère les informations de LDAP
######################################
machine = ldap.search('ipHostNumber=%s' % IP )['machine'][0]
hostname = machine.nom()
proprio = machine.proprietaire().mail()
# On envoie un mail à l'adhérent
################################
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
################################
if upload.disconnect_mail_sost:
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 uploads)
requete="UPDATE avertis_upload set hard='f' where hard='t' and date < timestamp ' now' - interval '1 day'" requete="UPDATE avertis_upload set hard='f' where hard='t' and date < timestamp ' now' - interval '1 day'"
curseur.execute(requete) curseur.execute(requete)
requete="UPDATE avertis_upload set soft='f' where soft='t' and date < timestamp 'now' - interval '1 day'" requete="UPDATE avertis_upload set soft='f' where soft='t' and date < timestamp 'now' - interval '1 day'"
curseur.execute(requete) curseur.execute(requete)
############################################### ###############################################
# Détection de l'existence de virus ou de P2P # # Détection de l'existence de virus ou de P2P #
############################################### ###############################################
@ -157,7 +186,7 @@ curseur.execute(requete)
######## ########
# Dans le table virus on sélectionne les ip_src qui appartiennent au reseau # Dans le table virus on sélectionne les ip_src qui appartiennent au reseau
requete = "SELECT ip_src,count(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' group by ip_src" 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) curseur.execute(requete)
veroles = curseur.fetchall() veroles = curseur.fetchall()
@ -166,10 +195,7 @@ requete = "SELECT ip_crans FROM avertis_virus"
curseur.execute(requete) curseur.execute(requete)
infectes = curseur.fetchall() infectes = curseur.fetchall()
for verole in veroles: for ip, nombre in veroles:
ip=verole[0]
nombre=verole[1]
# si le type dépasse le seuil, on le blacklist # si le type dépasse le seuil, on le blacklist
if nombre < virus.virus or [ip] not in infectes : if nombre < virus.virus or [ip] not in infectes :
@ -196,11 +222,12 @@ for verole in veroles:
proprio.blacklist(['now','-','virus',hostname]) proprio.blacklist(['now','-','virus',hostname])
proprio.save() proprio.save()
# Flood # Flood
######## ########
# Dans le table virus on sélectionne les ip_src qui appartiennent au reseau # Dans le table virus on sélectionne les ip_src qui appartiennent au reseau
requete = "SELECT ip_src,count(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' group by ip_src" 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) curseur.execute(requete)
veroles = curseur.fetchall() veroles = curseur.fetchall()
@ -209,10 +236,7 @@ requete = "SELECT ip_crans FROM avertis_virus"
curseur.execute(requete) curseur.execute(requete)
infectes = curseur.fetchall() infectes = curseur.fetchall()
for verole in veroles: for ip, nombre in veroles:
ip=verole[0]
nombre=verole[1]
# si le type dépasse le seuil, on le blacklist # si le type dépasse le seuil, on le blacklist
if nombre < virus.flood or [ip] not in infectes : if nombre < virus.flood or [ip] not in infectes :
@ -239,21 +263,28 @@ for verole in veroles:
proprio.blacklist(['now','-','virus',hostname]) proprio.blacklist(['now','-','virus',hostname])
proprio.save() proprio.save()
# Reconnexion si le virus a disparu
###################################
# 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'" requete = "SELECT ip_crans FROM avertis_virus where date < timestamp 'now' - interval '1 hour'"
curseur.execute(requete) curseur.execute(requete)
infectes = curseur.fetchall() infectes = [ x[0] for x in curseur.fetchall() ]
for i in range(0,len(infectes)):
IP=infectes[i][0] for IP in infectes :
# Nombre de requets de virus
requete1="SELECT COUNT(ip_src) FROM virus where ip_src='%s' and date > timestamp 'now' - interval '1 hour'" % IP requete1="SELECT COUNT(ip_src) FROM virus where ip_src='%s' and date > timestamp 'now' - interval '1 hour'" % IP
curseur.execute(requete1) curseur.execute(requete1)
nb_virus = curseur.fetchall() nb_virus = curseur.fetchall()
# Nombre de requetes de flood
requete2="SELECT COUNT(ip_src) FROM flood where ip_src='%s' and date > timestamp 'now' - interval '1 hour'" % IP requete2="SELECT COUNT(ip_src) FROM flood where ip_src='%s' and date > timestamp 'now' - interval '1 hour'" % IP
curseur.execute(requete2) curseur.execute(requete2)
nb_flood = curseur.fetchall() nb_flood = curseur.fetchall()
# On traite que les IP qui sont descendues en dessoys des seuils
# On 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 : if nb_virus[0][0] < virus.virus and nb_flood[0][0] < virus.flood :
machine = ldap.search('ipHostNumber=%s' % IP,'w' )['machine'][0] machine = ldap.search('ipHostNumber=%s' % IP,'w' )['machine'][0]
# si la machine est pas online, on reconnecte # si la machine est pas online, on reconnecte
@ -280,55 +311,48 @@ for i in range(0,len(infectes)):
# Gestion du P2P : # Gestion du P2P :
################## ##################
# Dans le table virus on sélectionne les ip_src qui appartiennent au reseau # Dans le table p2p 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" requete = "SELECT ip_src,id_p2p,count(ip_src) FROM p2p WHERE %s AND date > timestamp 'now' - interval '1 day' GROUP BY ip_src,id_p2p ORDER BY ip_src" % ip_src_in_crans
curseur.execute(requete) curseur.execute(requete)
pair = curseur.fetchall() fraudeurs = curseur.fetchall()
# Recuperation des infectes pour ne pas les reblacklister # Recuperation des infectes pour ne pas les reblacklister
requete = "SELECT ip_crans FROM avertis_p2p WHERE date > timestamp 'now' - interval '1 day'" requete = "SELECT ip_crans,protocole FROM avertis_p2p WHERE date > timestamp 'now' - interval '1 day'"
curseur.execute(requete) curseur.execute(requete)
avertisp2p = curseur.fetchall() avertisp2p = curseur.fetchall()
N=0
ip1=str('0.0.0.0') for ip, id_p2p, nombre in fraudeurs :
if pair :
ip1=pair[0][0] # On récupére le protocole de p2p :
for i in range(0,len(pair)): requete="SELECT nom FROM protocole_p2p WHERE id_p2p=%d" % id_p2p
ip=pair[i][0] curseur.execute(requete)
if ip != ip1 : protocole = curseur.fetchall()[0][0]
ip1=ip
N=0 # On ne prend pas en compte s'il est sous le seuil admis, ou s'il est averti
else : if nombre <= p2p.tag or [ip, protocole] in avertisp2p :
N=N+1 continue
if N >= p2p.tag and [ip] not in avertisp2p :
# Recuperation des ref de la machine # Recuperation des ref de la machine
machine = ldap.search('ipHostNumber=%s' % ip,'w' )['machine'][0] machine = ldap.search('ipHostNumber=%s' % ip,'w' )['machine'][0]
hostname = machine.nom() hostname = machine.nom()
proprio = machine.proprietaire() # proprio = machine.proprietaire()
#On récupére le protocole de p2p :
protocole=int(pair[i][1]) # Envoie du mail à disconnect
requete="SELECT nom FROM protocole_p2p WHERE id_p2p=%d" % protocole corps = p2p.avertissement % { 'From': upload.expediteur, 'To': upload.expediteur, 'protocole': protocole, 'hostname':hostname}
curseur.execute(requete) corps = corps.encode('iso 8859-15')
protocole = curseur.fetchall() mail.sendmail(upload.expediteur,upload.expediteur,corps)
protocole=protocole[0][0]
corps = p2p.avertissement % { 'From': upload.expediteur, # Inscription dans la base des avertis
'To': upload.expediteur, requete="INSERT INTO avertis_p2p (ip_crans,date,protocole) VALUES ('%s','now','%s')" % (ip, protocole)
'protocole': protocole, curseur.execute(requete)
'hostname':hostname}
corps = corps.encode('iso 8859-15') # Blacklistage
mail.sendmail(upload.expediteur,upload.expediteur,corps) # date = time()
#Inscription dans la base des avertis # debut = localtime(date)
requete="INSERT INTO avertis_p2p (ip_crans,date,protocole) VALUES ('%s','now','%s')" % (ip1,protocole) # 7 jours
curseur.execute(requete) # fin = localtime(date+60*60*24*7)
requete = "SELECT ip_crans FROM avertis_p2p WHERE date > timestamp 'now' - interval '1 day'" # 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])
curseur.execute(requete) # proprio.save()
avertisp2p = curseur.fetchall()
# Blacklistage # fermeture des connections
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() mail.quit()