diff --git a/surveillance/deconnexion.py b/surveillance/deconnexion.py new file mode 100755 index 00000000..810b1e73 --- /dev/null +++ b/surveillance/deconnexion.py @@ -0,0 +1,298 @@ +#! /usr/bin/env python +# -*- encoding: 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)#debut = localtime(date) + fin = localtime(date+60*60*24*300) #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',"upload de %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,xabi,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,xabi,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],dabut[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 # +############################################### + +# 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 '2 hours' 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 WHERE date > timestamp 'now' - interval '2 hour'" +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: + # 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 WHERE date > timestamp 'now' - interval '2 hour'" + curseur.execute(requete) + infectes = curseur.fetchall() + # Blacklistage + date = time() + debut = localtime(date) + fin = localtime(date+60*2) + # proprio.blacklist(["%d/%d/%d %d:%d" % (debut[2],debut[1],debut[0],dabut[3],debut[4]),"%d/%d/%d %d:%d" % (fin[2],fin[1],fin[0],fin[3],fin[4]),'virus'," TESTS Virus" ]) + + + + +# 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') +N=0 +if pair : + ip1=pair[0][0] + for i in range(0,len(veroles)): + 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,xabi,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],dabut[3],debut[4]),"%d/%d/%d %d:%d" % (fin[2],fin[1],fin[0],fin[3],fin[4]),'p2p'," TESTS p2p" % protocole]) +mail.quit() diff --git a/surveillance/filtrage.sql b/surveillance/filtrage.sql new file mode 100644 index 00000000..f080efff --- /dev/null +++ b/surveillance/filtrage.sql @@ -0,0 +1,192 @@ +-- Fichier permttant de reconstituer la base de données de filtrage des logs +-- de net-acct et du firewall +-- Pour regénérer la base : +-- Dropper la bose en tant qu'utilisateur postgres : dropdb filtrage +-- Créer la base avec l'utilisateur crans (par exemple) : +-- createdb -O crans filtrage +-- exécuter en tant qu'utilisateur : +-- psql filtrage -U crans < filtrage.sql + + +BEGIN; +-- Création de la table de protocole de type udp .. : index(1,16,17) | nom (,tcp,udp) +CREATE TABLE protocole ( + id integer NOT NULL, + nom text NOT NULL, + CONSTRAINT id_protocole PRIMARY KEY (id)); + + +-- Création de la table de protocole p2p : (1,2,3,...)|(eMule,SoulSeak, ...) +CREATE TABLE protocole_p2p ( + id_p2p serial NOT NULL, + nom text NOT NULL, + CONSTRAINT id_p2p_protocole PRIMARY KEY (id_p2p)); + + +-- Table Virus : date | source | destinataire | protocole | port source | port dest +CREATE TABLE virus ( + date timestamp NOT NULL, + ip_src inet NOT NULL, + ip_dest inet NOT NULL, + id integer NOT NULL, + port_src integer NOT NULL, + port_dest integer NOT NULL, + CONSTRAINT virus_protocole FOREIGN KEY (id) REFERENCES protocole (id)); + + +-- Table upload : date | source | destinataire | protocole | port source | port dest | download | upload + CREATE TABLE upload ( + date timestamp NOT NULL, + ip_crans inet NOT NULL, + ip_ext inet NOT NULL, + id integer NOT NULL, + port_crans integer NOT NULL, + port_ext integer NOT NULL, + download bigint NOT NULL, + upload bigint NOT NULL, + CONSTRAINT upload_protocole FOREIGN KEY (id) REFERENCES protocole (id)); + +-- Table p2p : date | source | destinataire | protocole p2p | port source | port dest + CREATE TABLE p2p ( + date timestamp NOT NULL, + ip_src inet NOT NULL, + ip_dest inet NOT NULL, + id_p2p integer NOT NULL, + id integer NOT NULL, + port_src integer NOT NULL, + port_dest integer NOT NULL, + CONSTRAINT p2p_id_protocole FOREIGN KEY (id) REFERENCES protocole (id), + CONSTRAINT p2p_id_p2p_protocole FOREIGN KEY (id_p2p) REFERENCES protocole_p2p (id_p2p)); + +-- Table des avertis pour upload + CREATE TABLE avertis_upload ( + date timestamp NOT NULL, + ip_crans inet NOT NULL, + soft boolean, + hard boolean, + sanctions boolean); + +-- Table des infectes + CREATE TABLE avertis_virus ( + date timestamp NOT NULL, + ip_crans inet NOT NULL); + +-- Table des infectes + CREATE TABLE avertis_p2p ( + date timestamp NOT NULL, + ip_crans inet NOT NULL, + protocole text NOT NULL); + +-- Table des sanctionnés pour upload : + CREATE TABLE sanctions ( + date timestamp NOT NULL, + aid integer NOT NULL, + penalite integer NOT NULL); + +-- Table des exemptés : + CREATE TABLE exemptes ( + ip_crans inet NOT NULL, + ip_dest inet NOT NULL); + + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.136.0/28','0.0.0.0/0'); -- crans vers le reste + -- du monde + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.136.0/21','138.231.0.0/16'); -- crans vers ens + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.148.0/22','138.231.0.0/16'); -- wifi crans vers ens + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.149.10','129.104.17.0/24'); -- rivendell vers jussieux + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.141.187','129.104.17.0/24'); -- barad-dur vers jussieux + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.149.10','134.157.96.216'); -- rivendell vers polytechnique + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.141.187','134.157.96.216'); -- barad-dur vers polytechnique + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.137.230','129.175.100.221'); -- helene vers orsay + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.139.106','138.195.74.0/24'); -- schuss vers centrale + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.139.106','138.195.75.0/24'); -- schuss vers centrale + INSERT INTO exemptes (ip_crans,ip_dest) VALUES + ('138.231.137.25','157.99.164.27'); -- sayan vers + -- chile.sysbio.pasteur.fr + + + +-- Protocole udp ... + INSERT INTO protocole VALUES (1,'ICMP'); + INSERT INTO protocole VALUES (2,'IGMP'); + INSERT INTO protocole VALUES (3,'GGP'); + INSERT INTO protocole VALUES (4,'IPENCAP'); + INSERT INTO protocole VALUES (5,'ST'); + INSERT INTO protocole VALUES (6,'TCP'); + INSERT INTO protocole VALUES (8,'EGP'); + INSERT INTO protocole VALUES (9,'IGP'); + INSERT INTO protocole VALUES (12,'PUP'); + INSERT INTO protocole VALUES (17,'UDP'); + INSERT INTO protocole VALUES (20,'HMP'); + INSERT INTO protocole VALUES (22,'XNS-IDP'); + INSERT INTO protocole VALUES (27,'RDP'); + INSERT INTO protocole VALUES (29,'ISO-TP4'); + INSERT INTO protocole VALUES (36,'XTP'); + INSERT INTO protocole VALUES (37,'DDP'); + INSERT INTO protocole VALUES (38,'IDPR-CMTP'); + INSERT INTO protocole VALUES (41,'IPV6'); + INSERT INTO protocole VALUES (43,'IPV6-ROUTE'); + INSERT INTO protocole VALUES (44,'IPV6-FRAG'); + INSERT INTO protocole VALUES (45,'IDRP'); + INSERT INTO protocole VALUES (46,'RSVP'); + INSERT INTO protocole VALUES (47,'GRE'); + INSERT INTO protocole VALUES (50,'IPSEC-ESP'); + INSERT INTO protocole VALUES (51,'IPSEC-AH'); + INSERT INTO protocole VALUES (57,'SKIP'); + INSERT INTO protocole VALUES (58,'IPV6-ICMP'); + INSERT INTO protocole VALUES (59,'IPV6-NONXT'); + INSERT INTO protocole VALUES (60,'IPV6-OPTS'); + INSERT INTO protocole VALUES (73,'RSPF'); + INSERT INTO protocole VALUES (81,'VWTP'); + INSERT INTO protocole VALUES (88,'EIGRP'); + INSERT INTO protocole VALUES (89,'OSPFIGP'); + INSERT INTO protocole VALUES (93,'AX-25'); + INSERT INTO protocole VALUES (94,'IPIP'); + INSERT INTO protocole VALUES (97,'ETHERIP'); + INSERT INTO protocole VALUES (98,'ENCAP'); + INSERT INTO protocole VALUES (103,'PIM'); + INSERT INTO protocole VALUES (108,'IPCOMP'); + INSERT INTO protocole VALUES (112,'VRRP'); + INSERT INTO protocole VALUES (115,'LSTP'); + INSERT INTO protocole VALUES (124,'ISIS'); + INSERT INTO protocole VALUES (132,'SCTP'); + INSERT INTO protocole VALUES (133,'FC'); + +-- Protocoles p2p + INSERT INTO protocole_p2p (nom) VALUES ('Bittorrent'); + INSERT INTO protocole_p2p (nom) VALUES ('AppleJuice'); + INSERT INTO protocole_p2p (nom) VALUES ('SoulSeek'); + INSERT INTO protocole_p2p (nom) VALUES ('WinMX'); + INSERT INTO protocole_p2p (nom) VALUES ('eDonkey'); + INSERT INTO protocole_p2p (nom) VALUES ('DirectConnect'); + INSERT INTO protocole_p2p (nom) VALUES ('KaZaa'); + INSERT INTO protocole_p2p (nom) VALUES ('Ares'); + INSERT INTO protocole_p2p (nom) VALUES ('GNUtella'); + + +-- Création des index + CREATE INDEX date_virus_idx ON virus (date); + CREATE INDEX ip_src_virux_idx ON virus (ip_src); + CREATE INDEX id_virus_idx ON virus (id); + + CREATE INDEX date_upload_idx ON upload (date); + CREATE INDEX id_upload_idx ON upload (id); + CREATE INDEX ip_crans_upload_idx ON upload (ip_crans); + + CREATE INDEX date_p2p_idx ON p2p (date); + CREATE INDEX ip_src_p2p_idx ON p2p (ip_src); + CREATE INDEX id_p2p_idx ON p2p (id); + CREATE INDEX id_p2p_p2p_idx ON p2p (id_p2p); + + + +COMMIT; diff --git a/surveillance/filtrage_firewall.py b/surveillance/filtrage_firewall.py new file mode 100755 index 00000000..83a61ae7 --- /dev/null +++ b/surveillance/filtrage_firewall.py @@ -0,0 +1,120 @@ +#! /usr/bin/env python +# -*- encoding: iso-8859-15 -*- + + +########################### +# Import des commmandes : # +########################### + +import commands +import os +# import pg # Import des commandes de postgres +import sys +sys.path.append('/usr/scripts/gestion') +import iptools +from pyPgSQL import PgSQL +import re +from time import gmtime,strftime +sys.path.append('/home/bernat') +import strptime + +# Définition de constantes : +############################ + +reseau = ["138.231.136.0/21", "138.231.148.0/22"] + +# Ouverture de la base de données : +################################### +pgsql = PgSQL.connect(host='/var/run/postgresql', database='filtrage', user='crans') +pgsql.autocommit = True + + + +########################################### +# Récupération des tables de protocoles : # +########################################### + + +curseur = pgsql.cursor() +requete = "SELECT nom,id_p2p from protocole_p2p" +curseur.execute(requete) +curseur.fetchall +tableau = curseur.fetchall() +protocole_p2p = {} +for cellule in tableau: + protocole_p2p[cellule[0]]=cellule[1] + +curseur = pgsql.cursor() +requete = "SELECT nom,id from protocole" +curseur.execute(requete) +curseur.fetchall +tableau = curseur.fetchall() +protocole = {} +for cellule in tableau: + protocole[cellule[0]]=cellule[1] + + + +############################################################## +# Parser ler log du firewall: /var/log/firewall/filtre.log : # +############################################################## + +# Définition des motifs des comparaisons : +########################################## +motif_p2p = re.compile("^(.*) komaz .* IPP2P=([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*") + +motif_virus = re.compile("^(.*) komaz .* Virus:([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*") + +motif_flood = re.compile("^(.*) komaz .* Flood:([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*") + + +# On récupère en continu les log du firewall: +############################################# +filtre = os.popen("tail -F /var/log/firewall/filtre.log 2> /dev/null") + + +# On matche les log du firewall avec les motifs : +################################################# +for log in filtre : + resultat_p2p = motif_p2p.match(log) + resultat_virus = motif_virus.match(log) + resultat_flood = motif_flood.match(log) + if resultat_p2p : + date = resultat_p2p.group(1) + id_p2p = int(protocole_p2p[resultat_p2p.group(2)]) + ip_src = resultat_p2p.group(3) + ip_dest = resultat_p2p.group(4) + proto = int(protocole[resultat_p2p.group(5)]) #C'est à dire id pour la base + port_src = int(resultat_p2p.group(6)) + port_dest = int(resultat_p2p.group(7)) + date=strptime.syslog2pgsql(date) + + # On remplit la base : + ###################### + curseur = pgsql.cursor() + requete = "INSERT INTO p2p (date,ip_src,ip_dest,id_p2p,id,port_src,port_dest) VALUES ('%s','%s','%s',%d,%d,%d,%d)" % (date,ip_src,ip_dest,id_p2p,proto,port_src,port_dest) + curseur.execute(requete) + + # On teste si le log contient des virus + ######################################## + elif resultat_virus : + date = resultat_virus.group(1) + ip_src = resultat_virus.group(3) + ip_dest = resultat_virus.group(4) + proto = int(protocole[resultat_virus.group(5)]) #C'est à dire id pour la base + port_src = int(resultat_virus.group(6)) + port_dest = int(resultat_virus.group(7)) + elif resultat_flood : + date = resultat_flood.group(1) + ip_src = resultat_flood.group(3) + ip_dest = resultat_flood.group(4) + proto = int(protocole[resultat_flood.group(5)]) #C'est à dire id pour la base + port_src = int(resultat_flood.group(6)) + port_dest = int(resultat_flood.group(7)) + + # On remplit la base : + ###################### + date=strptime.syslog2pgsql(date) + curseur = pgsql.cursor() + requete = "INSERT INTO virus (date,ip_src,ip_dest,id,port_src,port_dest) VALUES ('%s','%s','%s',%d,%d,%d)" % (date,ip_src,ip_dest,proto,port_src,port_dest) + curseur.execute(requete) diff --git a/surveillance/filtrage_netacct.py b/surveillance/filtrage_netacct.py new file mode 100755 index 00000000..fbfda6a4 --- /dev/null +++ b/surveillance/filtrage_netacct.py @@ -0,0 +1,107 @@ +#! /usr/bin/env python +# -*- encoding: iso-8859-15 -*- + + +########################### +# Import des commmandes : # +########################### + +import commands +import os +#import pg # Import des commandes de postgres +import sys +sys.path.append('/usr/scripts/gestion') +import iptools +from pyPgSQL import PgSQL +from time import gmtime,strftime +sys.path.append('/home/bernat') +import strptime + +# Définition de constantes : +############################ + +reseau = ["138.231.136.0/21", "138.231.148.0/22"] + +# Ouverture de la base de données : +################################### +pgsql = PgSQL.connect(host='/var/run/postgresql', database='filtrage', user='crans') +pgsql.autocommit = True + +################################################################# +# Parser ler log de net-acct : /var/log/net-acct/net-acct.log : # +################################################################# + +#On récupère en continu les log de net-account +# Les logs sont sous la forme : date | id(protocole) | ip_src | port_src | ip_dest | port_dest | octet transf + +#netacct = os.popen("sh -c 'tail -F /var/log/ulog-acctd/account.log 2> /dev/null'") +netacct = os.popen("sh -c 'tail -F /var/log/net-acct/net-acct.log 2> /dev/null'") + +# Sélectionner le couple de ligne qui va bien (port_src_i=port_dest_i+1 et ip_src_i=ip_dest_i+1 +# Création d'un dictionnaire pour matcher les conversations + +precedent = {"ip_src":"0","ip_dest":"0","port_src":"0","port_dest":"0","donnees":0} + +for log in netacct : + # Découpage du log + date,proto,ip_src,port_src,ip_dest,port_dest,donnees = log.split("\t")[0:-2] + # ip_src,ip_dest,port_src,port_dest + proto = int(proto) + # Création d'un dictionnaire pour matcher les conversations + actuel = {} + actuel["ip_src"]=ip_src + actuel["port_src"]=port_src + actuel["ip_dest"]=ip_dest + actuel["port_dest"]=port_dest + actuel["donnees"]=donnees + # Test + if actuel["ip_src"]==precedent["ip_dest"] \ + and actuel["ip_dest"]==precedent["ip_src"] \ + and actuel["port_src"]==precedent["port_dest"] \ + and actuel["port_dest"]==precedent["port_src"] : + + + # Remplissage de la base de données : + #################################### + + # Vérification de l'IP: + verif = iptools.AddrInNets (actuel["ip_src"],reseau) + if verif: + crans = "src" + ext = "dest" + upload = int(actuel["donnees"]) + download = int(precedent["donnees"]) + port_src=int(actuel['port_src']) + port_dest=int(actuel['port_dest']) + else : + crans = "dest" + ext = "src" + upload = int(precedent["donnees"]) + download = int(actuel["donnees"]) + port_src=int(actuel['port_dest']) + port_dest=int(actuel['port_src']) + + ip_crans = actuel["ip_%s" % crans] + ip_ext = actuel["ip_%s" % ext] + port_crans = int(actuel["port_%s" % crans]) + port_ext = int(actuel["port_%s" % ext]) + #print actuel["ip_%s" % crans] + #print ip_crans, ip_ext,port_crans, port_ext + + # Traitement dans la base SQL ### Modifier le traitement de l'heure ! + date = strptime.syslog2pgsql(strftime("%b %d %H:%M:%S",gmtime(int(date)))) + curseur = pgsql.cursor() + requete = "INSERT INTO upload (ip_crans,ip_ext,port_crans,port_ext,download,upload,date,id) VALUES ('%s','%s',%d,%d,%d,%d,'%s',%d)" % (ip_crans, + ip_ext, + port_crans, + port_ext, + download, + upload, + date, + proto) + curseur.execute(requete) + + + precedent=actuel + + diff --git a/surveillance/statistiques.py b/surveillance/statistiques.py new file mode 100755 index 00000000..6eedb0f8 --- /dev/null +++ b/surveillance/statistiques.py @@ -0,0 +1,180 @@ +#! /usr/bin/env python +# -*- encoding: iso-8859-15 -*- + +########################### +# Import des commmandes : # +########################### + +import commands +import sys +from pyPgSQL import PgSQL +sys.path.append('/usr/scripts/gestion') +from ldap_crans import crans_ldap +import smtplib + +############################### +# Ouverture des connections : # +############################### + +pgsql = PgSQL.connect(host='/var/run/postgresql', database='filtrage', user='crans') +pgsql.autocommit = True +curseur = pgsql.cursor() +mail = smtplib.SMTP('localhost') +ldap=crans_ldap() + + +########################### +# Statistiques d'upload : # +########################### + +# Adhérents avertis : +##################### +requete = "SELECT ip_crans,sum(upload)/1024/1024 as somme,sum(download)/1024/1024 FROM upload WHERE ip_crans IN (SELECT ip_crans FROM avertis_upload where hard='1' or soft='1') and date > timestamp 'now' - interval '1 day' GROUP BY ip_crans order by somme" +curseur.execute(requete) +hard = curseur.fetchall() + +for i in range(0,len(hard)): + IP=hard[i][0] + machine = ldap.search('ipHostNumber=%s' % IP)['machine'][0] + hostname = machine.nom() + upload = round((hard[i][1]),2) + download=round((hard[i][2]),2) + if i==0 : + liste_upload="%10s%10s\t%s\n"%(str(upload),str(download),str(hostname)) + else : + liste_upload=liste_upload+"%10s%10s\t%s\n"%(str(upload),str(download),str(hostname)) + + + +# Upload exemptés : +################### + +requete = "SELECT ip_crans,sum(upload)/1024/1024 AS somme , sum(download)/1024/1024 FROM upload WHERE ip_crans IN ( SELECT ip_crans from exemptes) and date > timestamp 'now' - interval '1 day' GROUP BY ip_crans order by somme" +curseur.execute(requete) +exemptes = curseur.fetchall() + +for i in range(0,len(exemptes)): + IP=exemptes[i][0] + machine = ldap.search('ipHostNumber=%s' % IP)['machine'][0] + hostname = machine.nom() + upload=round(exemptes[i][1],2) + download=round(exemptes[i][2],2) + if i==0 : + liste_exemptes="%10s%10s\t%s\n"%(str(upload),str(download),str(hostname)) + else : + liste_exemptes=liste_exemptes+"%10s%10s\t%s\n"%(str(upload),str(download),str(hostname)) + + +# Upload des serveurs : +####################### +for i in (10,1,3,4,5,7,8,9,11): + IP='138.231.136.'+str(i) + machine = ldap.search('ipHostNumber=%s' % IP)['machine'][0] + hostname = machine.nom() + requete = "SELECT sum(upload)/1024/1024,sum(download)/1024/1024 FROM upload WHERE ip_crans='%s' AND date > timestamp 'now' - interval '1 day' "%IP + curseur.execute(requete) + traffic=curseur.fetchall() + try : + round(traffic[0][0],2) + except TypeError: + print "Pas d'upload ou download" + else : + upload=round(traffic[0][0],2) + download=round(traffic[0][1],2) + if i==10 : + liste_serveurs="%10s%10s\t%s\n"%(str(upload),str(download),str(hostname)) + else : + liste_serveurs=liste_serveurs+"%10s%10s\t%s\n"%(str(upload),str(download),str(hostname)) + + +# Machines infectées : +###################### +requete = "SELECT ip_crans FROM avertis_virus WHERE date>timestamp 'now' - interval '1 day'" +curseur.execute(requete) +infections = curseur.fetchall() +for i in range(1,len(infections)): + IP=infections[i][0] + machine = ldap.search('ipHostNumber=%s' % IP)['machine'][0] + hostname = machine.nom() + try : + print len(liste_virus) + except NameError: + liste_virus="%s%s\n"%('--','--') + else : + if i==0 : + liste_virus="%s\n"%(str(hostname)) + else : + liste_virus=liste_virus+"%s\n"%(str(hostname)) + + +# Machines utilisant des protocoles P2P : +######################################### +requete = "SELECT ip_crans,protocole FROM avertis_p2p WHERE date>timestamp 'now' - interval '1 day'" +curseur.execute(requete) +p2p = curseur.fetchall() +for i in range(0,len(p2p)): + IP=p2p[i][0] + protocole = p2p[i][1] + machine = ldap.search('ipHostNumber=%s' % IP)['machine'][0] + hostname = machine.nom() + try : + print len(liste_p2p) + except NameError: + liste_p2p="%s%20s\n"%('--','--') + else : + if i==0 : + liste_p2p="%9s\t%s\n"%(str(protocole),str(hostname)) + else : + liste_p2p=liste_p2p+"%9s\t%s\n"%(str(protocole),str(hostname)) + + +############# +# Message : # +############# +expediteur = "pessoles@crans.org" +destinataire = "disconnect@crans.org" +message="""From: %(From)s +To: %(To)s +Subject: MESSAGE DE TEST : Statistiques des dernières 24h + +Bilan des déconnexions : +======================== + + +Machines infectées pour virus : +----------------------------- +%(liste_virus)s + + +Machines utilisant des protocoles de pair à pair : +------------------------------------------------ +%(liste_p2p)s + + +Statistiques d'upload -- download : +--------------------------------- +%(liste_upload)s + + +Statistiques d'upload -- download des machines exemptées : +---------------------------------------------------------- +%(liste_exemptes)s + +Statistiques d'upload -- download des serveurs : +------------------------------------------------ +%(liste_serveurs)s + +-- +statistiques.py +""" +corps = message %{'From':expediteur, + 'To':destinataire, + 'liste_upload':liste_upload, + 'liste_p2p':liste_p2p, + 'liste_virus':liste_virus, + 'liste_exemptes':liste_exemptes, + 'liste_serveurs':liste_serveurs} + +#corps = corps.encode('iso 8859-15') +mail.sendmail('pessoles@crans.org','disconnect@crans.org',corps) +#print corps