#! /usr/bin/env python # -*- coding: iso8859-15 -*- import socket import sys, re from pyPgSQL import PgSQL sys.path.append('/usr/scripts/gestion/') from affich_tools import tableau def stats(ip_crans=[], ip_ext=[], show=['ip_crans','ip_ext','port_crans','port_ext'], upload_mini=0, show_limit=10, begin_time=24, end_time=0): """ Retourne une chaine de caratères formatée avec le tableau de statistiques d'upload de l'ip fourni ip_crans : ips des machine chaine de caratère si il a qu'une machine liste si il y a plusieurs machines view : liste des champs à afficher parmi : ip_crans, ip_ext, port_crans, port_ext upload_mini : n'affiche que les lignes avec plus d'upload que la valeur donnée show_limit : nombre max de lignes à afficher begin : date de départ d'analyse (en heure avant maintenant) end : date de fin d'analyse (en heure avant maintenant) """ if type(ip_crans) == str: ip_crans = [ip_crans] if type(ip_ext) == str: ip_ext = [ip_ext] # variables pour la requete et l'affichage ########################################## select = [] largeur = [] titre = [] format = [] alignement = [] if 'ip_crans' in show and len(ip_crans)!=1: select.append('ip_crans') largeur.append(13) titre.append('machine crans') format.append('s') alignement.append('c') if 'ip_ext' in show : select.append('ip_ext') largeur.append('*') titre.append('machine ext') format.append('s') alignement.append('c') if 'port_ext' in show : select.append('port_ext') largeur.append(10) titre.append('port ext') format.append('s') alignement.append('d') if 'port_crans' in show : select.append('port_crans') largeur.append(10) titre.append('port crans') format.append('s') alignement.append('d') select += ['sum(download) as download','sum(upload) as upload'] largeur += [10,10] titre += ['download','upload'] format += ['o','o'] alignement += ['d','d'] # requete dans la base ###################### ip_crans = ' OR '.join([ "ip_crans='%s'"%x for x in ip_crans ]) if not ip_crans: ip_crans='true' ip_ext = ' OR '.join([ "ip_ext='%s'"%x for x in ip_ext ]) if not ip_ext: ip_ext='true' requete = "SELECT * FROM ( SELECT %s FROM upload WHERE (%s) AND (%s) AND (date > timestamp 'now' - interval '%d hours') AND (date < timestamp 'now' - interval '%d hours') GROUP BY %s) AS resultat_intemediaire WHERE upload>='%d' ORDER BY upload DESC LIMIT %d;" % (','.join(select), ip_crans, ip_ext, begin_time, end_time, ','.join(show), upload_mini*1024*1024, show_limit) pgsql = PgSQL.connect(host='/var/run/postgresql', database='filtrage', user='crans') curseur = pgsql.cursor() curseur.execute(requete) results = curseur.fetchall() # on transforme tout en chaine results = [ [ str(x) for x in line ] for line in results ] # on modifie les ip en noms de machine et les ports en noms def nom_de_machine (ip) : try: return socket.gethostbyaddr(ip)[0] except: return ip port_to_service = {} for service,port in [ re.split('[ \t]+',x.strip().replace('/tcp','').replace('/udp',''))[:2] for x in open('/etc/services').readlines() if x[0] not in ['\n','#'] ] : port_to_service[port]=service for champ in select: if champ == 'ip_ext': col = select.index(champ) results = [ x[:col] + [nom_de_machine(x[col])] + x[col+1:] for x in results ] elif champ == 'ip_crans': col = select.index(champ) results = [ x[:col] + [nom_de_machine(x[col]).split('.')[0]] + x[col+1:] for x in results ] elif 'port' in champ: col = select.index(champ) results = [ x[:col] + [port_to_service.get(x[col],x[col])] + x[col+1:] for x in results ] return tableau(results, titre=titre, largeur=largeur, alignement=alignement, format=format) if __name__ == '__main__' : help = """Statistiques d'upload d'une machine du crans usage: analyse.py [options] Option fait partie des options suivantes : --ip-crans ip de la machine crans --ip-ext ip de la machine extérieure --show champs à afficher (parmi ip_crans, ip_ext, port_crans, port_ext) --upload-mini upload mini des lignes à afficher --show-limit nombre maximum de lignes à afficher --begin-time heure de départ de l'analyse (en heure depuis maintenant) --end-time heure de fin de l'analyse (en heure depuis maintenant) Exemples : sudo /usr/scripts/surveillance/analyse.py bilou.crans.org""" # import des modules import getopt # aide ###### if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv)==1: print help sys.exit(0) # parsage des arguments ####################### try : opts, args = getopt.getopt(sys.argv[1:],'',['ip-crans=','ip-ext=','show=','upload-mini=','begin-time=','end-time=','show-limit=']) except getopt.GetoptError,message : print help sys.exit(4) print "Statistiques d'upload" # recherche de la machine crans ############################### ip_crans = [] ip_crans_nom = [] for key,value in opts : if key == '--ip-crans' : try : ip_crans.append(socket.gethostbyaddr(value)[2][0]) ip_crans_nom.append(socket.gethostbyaddr(value)[0]) except socket.gaierror : print "Hôte %s inconnu" % value sys.exit(5) if len(ip_crans_nom)==1: print ' depuis la machine %s' % ip_crans_nom[0] elif ip_crans_nom: print ' depuis les machines %s' % ', '.join(ip_crans_nom) # recherche de la machine ext ############################# ip_ext = [] ip_ext_nom = [] for key,value in opts : if key == '--ip-ext' : # recherche de l'ip de la machine extérieur try : ip_ext.append(socket.gethostbyaddr(value)[2][0]) except socket.gaierror : print "Hôte %s inconnu" % value sys.exit(5) # recherche du nom d'hote try : ip_ext_nom.append(socket.gethostbyaddr(value)[0]) except socket.gaierror : ip_ext_nom.append(ip_ext[-1]) if len(ip_ext_nom)==1: print ' vers la machine extérieure %s' % ip_ext_nom[0] elif ip_ext_nom: print ' vers les machines extérieures %s' % ', '.join(ip_ext_nom) # limite d'affichage #################### show = [ x[1] for x in opts if x[0] == '--show' and x[1] in ['ip_crans','ip_ext','port_crans','port_ext'] ] if not show : show = ['ip_crans','ip_ext','port_crans','port_ext'] else : print ' affichage de %s' % ', '.join(show) # upload mini à afficher ######################## upload_mini = 0 for key,value in opts : if key == '--upload-mini' : try : upload_mini = int(value) except : print 'L\'upload mini doit être un entier (en MO)' sys.exit(4) break if upload_mini: print ' pour les traffics supérieurs à %d Mo' % upload_mini # nombre limite d'enregristrements ################################## limit = 10 for key,value in opts : if key == '--show-limit' : try : limit = int(value) print ' affichage des %d premiers résultats' % limit except : print 'Le nombre limite n\'est pas un entier' sys.exit(3) break # début de l'analyse #################### begin_time = 24 for key,value in opts : if key == '--begin-time' : try : begin_time = int(value) except : print 'Le nombre d\'heures doit être un entier' sys.exit(4) break # fin de l'analyse ################## end_time = 0 for key,value in opts : if key == '--end-time' : try : end_time = int(value) except : print 'Le nombre d\'heures doit être un entier' sys.exit(4) break if begin_time != 24 or end_time: print ' entre il y a %d heures et il y a %d heures' % (begin_time,end_time) # affichage du résultat ####################### #print stats(ip_crans, group, upload_mini, limit, heures) print stats(ip_crans, ip_ext, show, upload_mini, limit, begin_time, end_time)