[arpwatch] On marque "à dropper" certains évènements.

Cf 7560f05a1e puis 95234963da.
Si ça marche, on droppera.
This commit is contained in:
Vincent Le Gallic 2013-11-09 03:27:00 +01:00
parent 7ce03ce064
commit 8a79b10b9d

View file

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Ajout d'un whos et d'un tracage aux mails d'arpwatch # Ajout d'un whos et d'un tracage aux mails d'arpwatch
# Auteurs : Stéphane Glondu, Cyril Cohen, Daniel STAN, Valentin Samir # Auteurs : Stéphane Glondu, Cyril Cohen, Daniel STAN, Valentin Samir, Vincent Le Gallic
# Licence : GPLv2 # Licence : GPLv2
from __future__ import print_function from __future__ import print_function
@ -13,7 +13,7 @@ import socket
import common import common
# Keep away from here les modules qui font des connexions ldap sans le dire (!) # Keep away from here les modules qui font des connexions ldap sans le dire (!)
from gestion.config import NETs import gestion.config
from gestion.iptools import AddrInNets from gestion.iptools import AddrInNets
from utils.sendmail import sendmail from utils.sendmail import sendmail
@ -25,7 +25,14 @@ if not recipients:
find_mac = re.compile(r'[0-9A-Fa-f]{1,2}(?::[0-9A-Fa-f]{1,2}){5}') find_mac = re.compile(r'[0-9A-Fa-f]{1,2}(?::[0-9A-Fa-f]{1,2}){5}')
find_ip = re.compile(r'[0-9]{1,3}(?:\.[0-9]{1,3}){3}') find_ip = re.compile(r'[0-9]{1,3}(?:\.[0-9]{1,3}){3}')
arpwatched_net = NETs['all'] + NETs['adm'] + NETs['accueil'] + NETs['isolement'] + NETs['personnel-ens'] + NETs['evenementiel'] #: Regexp pour matcher l'interface.
#: Ne matche pas toutes les interface (si un jour eth1 poppe),
#: Mais de toutes façons on ne drope que des interfaces qu'on a réussi à identifier
find_iface = re.compile(r'eth0(?:\.[0-9]+)?')
arpwatched_nets = sum([gestion.config.NETs[nom] for nom in ['all', 'adm', 'accueil', 'isolement', 'personnel-ens', 'evenementiel']], [])
#: VLANS dont on ignore les "new station"/"new activity" *si elles ont une ip correspondant au vlan*
ignored_vlans = ['accueil', 'wifi']
def get_machine(unformated_mac): def get_machine(unformated_mac):
"""Renvoie les informations sur la machine à partir de sa mac""" """Renvoie les informations sur la machine à partir de sa mac"""
@ -40,6 +47,37 @@ def get_subject(headers_list):
return line[9:].strip() return line[9:].strip()
return None return None
def drop_report(subject, ip):
"""Détermine à partir du ``subject`` du mail
si il n'est pas nécessaire d'envoyer une notification pour cet évènement.
Renvoie ``True`` si il faut le dropper.
"""
# On récupère l'interface et l'ip dans le sujet
ifaces = find_iface.findall(subject)
iface = ifaces[0] if ifaces else None
if not iface is None:
# On détermine le vlan
vlans = re.findall(r"\.([^\.]*)$", iface)
try:
vlan = int(vlans[0]) if vlans else None
except ValueError:
vlan = None
ips = find_ip.findall(subject)
ip = ips[0] if ips else None
#print("%r, %r" % (ip, iface))
#print(arpwatched_nets)
if u"new station" in subject or "new activity" in subject:
if not vlan is None:
vlannames = [k for (k,v) in gestion.config.vlans.iteritems() if v == vlan]
#print("vlannames : %r" % vlannames)
if vlannames and vlannames[0] in ignored_vlans:
#print("%r in %r ?" % (ip, gestion.config.NETs[vlannames[0]]))
if AddrInNets(ip, gestion.config.NETs[vlannames[0]]):
# On ignore les new station dont l'IP est sur le bon vlan
return True
return False
def report(texte, fallback=False): def report(texte, fallback=False):
"""Envoi d'un rapport""" """Envoi d'un rapport"""
textes = texte.splitlines(True) textes = texte.splitlines(True)
@ -60,13 +98,13 @@ def report(texte, fallback=False):
ip = set(find_ip.findall(texte)).pop() ip = set(find_ip.findall(texte)).pop()
except KeyError: except KeyError:
ip = None ip = None
# On complète le message # On complète le message seulement en cas de flip flop
if u'flip flop' in subject and ip is not None and AddrInNets(ip, arpwatched_net): if u'flip flop' in subject and ip is not None and AddrInNets(ip, arpwatched_nets):
try: try:
macs = find_mac.findall(texte) macs = find_mac.findall(texte)
for mac in macs: for mac in macs:
textes.append(get_machine(mac)) textes.append(get_machine(mac))
except: except Exception as exc:
# En cas d'exception, on envoie le traceback # En cas d'exception, on envoie le traceback
import traceback import traceback
textes.append(u'\n') textes.append(u'\n')
@ -77,6 +115,8 @@ def report(texte, fallback=False):
out = ''.join(textes) out = ''.join(textes)
if recipients: if recipients:
if drop_report(subject, ip):
subject += u"(should be dropped)"
sendmail(u"arpwatch@crans.org", recipients, subject, out, sendmail(u"arpwatch@crans.org", recipients, subject, out,
more_headers = { more_headers = {
'X-Mailer': __file__, 'X-Mailer': __file__,