scripts/surveillance/statistiques.py
Vincent Le Gallic 2ce185720e Éclatement de config.py en plusieurs sous-module de config. L'API reste à peu près la même, il faut juste penser à import config.submodule avant d'utilisr config.submodule (confid.dns, config.upload par exemple)
Tous les autres fichiers modifiés le sont pour compatibilité avec ce changement.

Ce commit implique des commits du même genre dans l'intranet2, lc_ldap et bcfg2.
2013-03-26 16:24:31 +01:00

326 lines
9.6 KiB
Python
Executable file

#! /usr/bin/env python
# -*- encoding: iso-8859-15 -*-
"""
Script d'envoi des statistiques des déconnections
et du trafic de la journée à disconnect@
Copyright (C) Xavier Pessoles - Étienne Chové - Michel Blockelet
Licence : GPLv2
"""
###########################
# Import des commmandes : #
###########################
import commands
import sys, os
import psycopg2
sys.path.append('/usr/scripts/gestion')
sys.path.append('/usr/scripts/surveillance')
import config.virus
import smtplib
import socket
import time, random, hashlib
import netaddr
from analyse import stats
from affich_tools import tableau
from iptools import AddrInNet
from ldap_crans import AssociationCrans, crans_ldap
CL = crans_ldap()
def ipv4or6(addr):
if ':' in addr:
return "IPv6"
else:
return "IPv4"
# Liste des IP des serveurs
ips_serveurs = []
ips_proxys = []
for m in AssociationCrans().machines():
if m.nom() in [u'charybde.crans.org', u'sable.crans.org']:
ips_proxys.extend([m.ip(), str(m.ipv6())])
else:
ips_serveurs.extend([m.ip(), str(m.ipv6())])
##############################
# Ouverture des connexions : #
##############################
pgsql = psycopg2.connect(database="filtrage", user="crans")
curseur = pgsql.cursor()
###########################
# Statistiques d'upload : #
###########################
# Liste des uploads :
#####################
requete = """(SELECT ip_crans, sum(upload) AS somme, sum(download)
FROM upload
WHERE
date > timestamp 'now' - interval '1 day'
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
)
UNION
(SELECT
ip_crans, sum(upload) AS somme, sum(download)
FROM
(
SELECT DISTINCT * FROM
(
SELECT
upload6.date, mac_ip.mac AS ip_crans, upload6.ip_ext, upload6.id, upload6.port_crans, upload6.port_ext, upload6.download, upload6.upload
FROM mac_ip,upload6
WHERE
upload6.ip_crans = mac_ip.ip
AND upload6.date > mac_ip.date
AND upload6.date - interval '1 day' < mac_ip.date
AND upload6.date > timestamp 'now' - interval '1 day'
AND upload6.date < 'now'
AND NOT EXISTS
(
SELECT 1
FROM exemptes
WHERE upload6.ip_crans <<= exemptes.ip_crans
AND upload6.ip_ext <<= exemptes.ip_dest
)
) AS upload
) AS upload
GROUP BY
ip_crans
)
ORDER BY somme DESC"""
curseur.execute(requete)
data_upload = curseur.fetchall()
liste_upload = tableau(data = [ (l[1], l[2], ipv4or6(str(l[0])), socket.getfqdn(str(l[0])))
for l in data_upload
if int(l[1]) > 100*1024*1024
and l[0] not in (ips_serveurs + ips_proxys)],
titre = ['upload', 'download', 'proto', 'machine'],
largeur = [10, 10, 10, 40],
format = ['o', 'o', 's', 's'],
alignement = ['d', 'd', 'c', 'c']).encode('iso-8859-15')
# Trafic exempté :
##################
requete = """(SELECT ip_crans, sum(upload) AS somme, sum(download)
FROM upload
WHERE
date > timestamp 'now' - interval '1 day'
AND EXISTS (
SELECT 1
FROM exemptes
WHERE
upload.ip_crans = exemptes.ip_crans
-- AND upload.ip_ext <<= exemptes.ip_dest
)
GROUP BY ip_crans
)
UNION
(SELECT ip_crans, sum(upload) AS somme, sum(download)
FROM upload6
WHERE
date > timestamp 'now' - interval '1 day'
AND EXISTS (
SELECT 1
FROM exemptes
WHERE
upload6.ip_crans = exemptes.ip_crans
-- AND upload6.ip_ext <<= exemptes.ip_dest
)
GROUP BY ip_crans
)
ORDER BY somme DESC"""
curseur.execute(requete)
liste_exemptes = tableau(data = [[l[1], l[2], ipv4or6(str(l[0])), socket.getfqdn(str(l[0]))]
for l in curseur.fetchall()],
titre = ['upload', 'download', 'proto', 'machine'],
largeur = [10, 10, 10, 30],
format = ['o', 'o', 's', 's'],
alignement = ['d', 'd', 'c', 'c']).encode('iso-8859-15')
# Upload des serveurs :
#######################
liste_serveurs = []
for l in data_upload:
if l[0] in (ips_serveurs + ips_proxys) and l[1] + l[2] > 10*1024*1024:
liste_serveurs.append([l[1], l[2], ipv4or6(str(l[0])), socket.getfqdn(l[0])])
# requete = """SELECT sum(upload), sum(download)
# FROM upload
# WHERE
# ip_crans='%s'
# AND date > timestamp 'now' - interval '1 day' """ % IP
# curseur.execute(requete)
# traffic = curseur.fetchone()
# On ne compte pas le serveur si le trafic est petit
liste_serveurs = tableau(data = liste_serveurs,
titre = ['upload', 'download', 'proto', 'serveur'],
largeur = [10, 10, 10, 30],
format = ['o', 'o', 's', 's'],
alignement = ['d', 'd', 'c', 'c']).encode('iso-8859-15')
# statistiques des gros uploads depuis les serveurs
###################################################
# Liste des IP des serveurs
gros_uploads_des_serveurs = stats(ip_crans=ips_serveurs,
show=['ip_crans', 'ip_ext'], upload_mini=50,
show_limit=100).encode('iso-8859-15')
############################
# Statistiques virus/p2p : #
############################
# IPs envoyant des paquets de protocole Ethernet inconnu :
#########################################################
requete = """(SELECT COUNT(*), ip_ext
FROM upload
WHERE
id=-1
GROUP BY ip_ext)
UNION
(SELECT COUNT(*), ip_ext
FROM upload6
WHERE
id=-1
GROUP BY ip_ext
)"""
curseur.execute(requete)
liste_etherunk = tableau(data = [[l[0], socket.getfqdn(str(l[1]))]
for l in curseur.fetchall()],
titre = ['nombre','ip'],
largeur = [10, 30],
alignement = ['d','c']).encode('iso-8859-15')
# Machines actuellement déconnectées :
######################################
requete = "SELECT DISTINCT ip_crans FROM avertis_virus"
curseur.execute(requete)
infections = [ x[0] for x in curseur.fetchall() ]
liste_virus = []
for IP in infections:
hostname = socket.getfqdn(IP)
liste_virus.append(["%s" % (str(hostname))])
liste_virus = tableau(liste_virus,
titre=['machine'], largeur=[30]).encode('iso-8859-15')
# Machines ayant fait des attaques virus dans la journée :
##########################################################
requete = """SELECT * FROM (SELECT ip_src,count(ip_src) as compteur FROM virus
WHERE date > timestamp 'now' - interval '1 day'
GROUP BY ip_src ORDER BY compteur DESC)
AS tous
WHERE tous.compteur>'%s' LIMIT 30""" % config.virus.virus
curseur.execute(requete)
liste_virus2 = []
for IP, compteur in curseur.fetchall():
hostname = socket.getfqdn(IP)
liste_virus2.append([hostname, compteur])
liste_virus2 = tableau(data = liste_virus2,
titre = ['machine', 'nombre'],
largeur = [30, 12],
alignement = ['c', 'd']).encode('iso-8859-15')
# Machines ayant fait de attaques flood dans la journée :
#########################################################
requete = """SELECT * FROM (SELECT ip_src,count(ip_src) as compteur FROM flood
WHERE date > timestamp 'now' - interval '1 day'
GROUP BY ip_src ORDER BY compteur DESC)
AS tous
WHERE tous.compteur>'%s' LIMIT 30""" % config.virus.flood
curseur.execute(requete)
liste_virus3 = []
for IP, compteur in curseur.fetchall():
hostname = socket.getfqdn(IP)
liste_virus3.append([hostname, compteur])
liste_virus3 = tableau(data = liste_virus3,
titre = ['machine', 'nombre'],
largeur = [30, 12],
alignement = ['c', 'd']).encode('iso-8859-15')
#############
# Message : #
#############
expediteur = "disconnect@crans.org"
destinataire = "disconnect@crans.org"
message = """From: %(From)s
To: %(To)s
Subject: Statistiques des =?iso-8859-1?Q?derni=E8res?= 24h
Message-Id: <%(uuid)s1@crans.org>
Content-Type: text/plain; charset="iso-8859-15"
*Gros uploads des serveurs* (charybde et sable sont exemptés totalement)
%(gros_uploads_des_serveurs)s
*Statistiques de trafic des serveurs*
%(liste_serveurs)s
*IPs envoyant des paquets de protocole Ethernet inconnu*
%(liste_etherunk)s
*Machines actuellement déconnectées pour virus*
%(liste_virus)s
*Machines ayant commis des attaques virales dans la journée*
%(liste_virus2)s
*Machines ayant commis des attaques virales de type flood dans la journée*
%(liste_virus3)s
*Statistiques de trafic des adhérents* (tout le trafic)
%(liste_upload)s
*Statistiques de trafic des adhérents exemptés* (juste le trafic exempté)
%(liste_exemptes)s
--
statistiques.py
"""
uuid = hashlib.md5(str(long(time.time() * 1000)) +
str(long(random.random()*100000000000000000L))).hexdigest()
corps = message % { 'From': expediteur,
'To': destinataire,
'uuid': uuid,
'gros_uploads_des_serveurs': gros_uploads_des_serveurs,
'liste_etherunk': liste_etherunk,
'liste_serveurs': liste_serveurs,
'liste_upload': liste_upload,
'liste_virus': liste_virus,
'liste_virus2': liste_virus2,
'liste_virus3': liste_virus3,
'liste_exemptes': liste_exemptes
}
mail = smtplib.SMTP('localhost')
mailaddr = os.getenv('CRANS_EMAIL', 'disconnect@crans.org')
mail.sendmail(mailaddr, mailaddr, corps)