scripts/surveillance/arpwatch/report.py
Daniel STAN c068df708d [arpwatch] ajout d'un serveur d'envoi
Celui-ci écoute au travers d'une socket unix. Il permet ainsi de garder
une connexion ldap (et pg et cie) en permanence ouverte. Ce qui accélère
le traitement des rapports de arpwatch.
Pour utiliser ce server, report.py (ancien arpwatch_sendmail.py)
tente de se connecter à cette socket et envoie le mail lui-même en cas
d'échec.
On rajoute également un initscript pour arpwatch_sendmail_server.
Il n'est pas parfait et si vous aimez pas, feel free to edit.
2013-07-21 20:08:53 +02:00

96 lines
3 KiB
Python
Executable file

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Ajout d'un whos et d'un tracage aux mails d'arpwatch
# Auteurs : Stéphane Glondu, Cyril Cohen, Daniel STAN, Valentin Samir
# Licence : GPLv2
from __future__ import print_function
import sys, os, re
import socket
import common
sys.path.append('/usr/scripts')
from gestion.tools.locate_mac import trace_machine, format_mac, info_machine
from gestion.config import NETs
from gestion.iptools import AddrInNets
from utils.sendmail import sendmail
# On récupère les destinataires dans les arguments (très ad hoc)
recipients = [ mail for mail in sys.argv[1:] if '@' in mail ]
if not recipients:
print("Pas de mail fourni: affichage sur stdout.",
file=sys.stderr)
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}')
arpwatched_net = NETs['all'] + NETs['adm'] + NETs['accueil'] + NETs['isolement'] + NETs['personnel-ens'] + NETs['evenementiel']
def get_machine(unformated_mac):
"""Renvoie les informations sur la machine à partir de sa mac"""
mac = format_mac(unformated_mac)
return u"\n" + info_machine(mac) + u"\n" + trace_machine(mac)
def get_subject(headers_list):
for line in headers_list:
if line.lower().startswith('subject:'):
return line[9:].strip()
return None
def report(texte, fallback=False):
"""Envoi d'un rapport"""
textes = texte.splitlines(True)
try:
i = textes.index('\n')
except ValueError:
print("wrong formatted mail", file=sys.stderr)
return
headers = textes[:i]
textes = textes[(i+1):]
# Extrait le sujet
subject = get_subject(headers)
# Cherche les IP dans le corps
try:
ip = set(find_ip.findall(texte)).pop()
except KeyError:
ip = None
# On complète le message
if u'flip flop' in subject and ip is not None and AddrInNets(ip, arpwatched_net):
try:
macs = find_mac.findall(texte)
for mac in macs:
textes.append(get_machine(mac))
except:
# En cas d'exception, on envoie le traceback
import traceback
textes.append(u'\n')
textes.append(u''.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)))
if fallback:
textes.append(u'\nAttention, arpwatch/sendmail_server.py inactif !\n')
textes.append(u'\n-- \narpwatch_sendmail.py\n')
out = ''.join(textes)
if recipients:
sendmail(u"arpwatch@crans.org", recipients, subject, out,
more_headers = {
'X-Mailer': __file__,
})
else:
print(out)
if __name__ == '__main__':
data = sys.stdin.read()
# On essaye d'envoyer le mail à la socket de sendmail_server
# et au pire, on envoie nous-même le mail
try:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(common.SOCKET_FILE)
s.send(data)
s.close()
except socket.error:
report(data, fallback=True)