357 lines
18 KiB
Python
Executable file
357 lines
18 KiB
Python
Executable file
#! /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 *
|
|
|
|
|
|
# quelques fonctions
|
|
####################
|
|
|
|
def machine_online(machine) :
|
|
"""
|
|
Retourne True si la machine est connectée au réseau et False si elle ne l'est pas
|
|
"""
|
|
# les wifi sont toujours online
|
|
if machine.ipsec() :
|
|
return True
|
|
# arping pour les fixes
|
|
return not commands.getstatusoutput('/usr/sbin/arping -c 3 %s' % machine.mac())[0]
|
|
|
|
# Connections :
|
|
###############
|
|
pgsql = PgSQL.connect(host='/var/run/postgresql', database='filtrage', user='crans')
|
|
pgsql.autocommit = True
|
|
mail = smtplib.SMTP('localhost')
|
|
ldap = crans_ldap()
|
|
|
|
|
|
###########################################
|
|
# 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)
|
|
|
|
|
|
|
|
|
|
###############################################
|
|
# 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()
|
|
bl = proprio.blacklist()
|
|
# 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
|
|
for ligne in bl:
|
|
# On réédite si possible les lignes existantes pour ne pas charger la blackliste
|
|
if 'virus,' in ligne :
|
|
liste=ligne.split(',')
|
|
date = time()
|
|
debut = localtime(date)
|
|
argument=['now','-','virus',hostname]
|
|
index = bl.index(ligne)
|
|
proprio.blacklist((index,argument))
|
|
proprio.save()
|
|
break
|
|
else :
|
|
date = time()
|
|
debut = localtime(date)
|
|
proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],debut[3],debut[4]),'-','virus',hostname])
|
|
proprio.save()
|
|
#date = time()
|
|
#debut = localtime(date)
|
|
#proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],debut[3],debut[4]),'-','virus',hostname])
|
|
#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',hostname])
|
|
proprio.save()
|
|
|
|
|
|
|
|
# Reconnexion si le virus a disparu
|
|
###################################
|
|
|
|
requete = "SELECT ip_crans FROM avertis_virus where date < timestamp 'now' - interval '1 hour'"
|
|
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]
|
|
# si la machine n'est pas online, on ne reconnecte pas
|
|
if not machine_online(machine) :
|
|
continue
|
|
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,%s'%hostname 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
|
|
curseur.execute(requete)
|
|
|
|
|
|
# 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 '40 days'"
|
|
curseur.execute(requete)
|
|
requete = "DELETE FROM virus where date< timestamp 'now' - interval '7 days'"
|
|
curseur.execute(requete)
|
|
requete = "DELETE FROM flood where date< timestamp 'now' - interval '7 days'"
|
|
curseur.execute(requete)
|
|
requete = "DELETE FROM p2p where date< timestamp 'now' - interval '7 days'"
|
|
curseur.execute(requete)
|