Skip to content

Instantly share code, notes, and snippets.

@olivierlemoal
Last active August 29, 2015 14:17
Show Gist options
  • Save olivierlemoal/a24f2b6b8dd7ba24c6ae to your computer and use it in GitHub Desktop.
Save olivierlemoal/a24f2b6b8dd7ba24c6ae to your computer and use it in GitHub Desktop.
VPN Mail alert post connect
#! /usr/bin/env python2
# -*- coding: utf8 -*-
import os
import sys
import logging
import traceback
import smtplib
from email.mime.text import MIMEText
from datetime import tzinfo, timedelta, datetime
import socket
import pygeoip
import pickledb
LOG_FILENAME = 'alert_vpn.log'
logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)
def exit_with_0(type, value, traceback_error):
# Logging
traceback_error = traceback.format_tb(traceback_error)
logging.debug("{}: {} {}".format(type.__name__, value, "\n".join(traceback_error)))
# Must exit with 0 whatever happens
exit(0)
# Handle uncaught errors
sys.excepthook = exit_with_0
# Server name
server = u"Grenelle"
# SMTP server
SMTP_SERVER = "localhost"
username = os.environ['username'].decode("utf-8")
ip = os.environ['trusted_ip'].decode("utf-8")
directory = os.path.dirname(os.path.realpath(__file__))
# Country
# Database update:
# http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
gi_country = pygeoip.GeoIP(directory + '/GeoIP.dat')
country = gi_country.country_name_by_addr(ip)
alert_user = True
alert_security = True
if country:
# CC to security if IP not in France
alert_security = country != "France"
# Check if known IP
db = pickledb.load("known_ips.db", True)
ips = db.get(username)
if ips is None:
db.lcreate(username)
db.ladd(username, ip)
elif ip in ips:
alert_user = False
else:
db.ladd(username, ip)
# ASN
# Database update:
# http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz
gi_asn = pygeoip.GeoIP(directory + '/GeoIPASNum.dat')
asn = gi_asn.asn_by_addr(ip)
# Reverse
try:
reverse, _, _ = socket.gethostbyaddr(ip)
except:
reverse = None
# From, To, Cc
from_mail = u"[email protected]"
to_mail = u"%[email protected]" % username
cc_mail = [u"[email protected]"]
# Date / Hour
class GMT1(tzinfo):
def utcoffset(self, dt):
return timedelta(hours=1)
def dst(self, dt):
return timedelta(hours=1)
def tzname(self, dt):
return "Europe/Paris"
date = datetime.now(GMT1()).strftime("%d/%m/%Y")
hour = datetime.now(GMT1()).strftime("%H:%M")
# Logging to file
logging.info("Connexion user=\"{}\", date=\"{} {}\", ip=\"{}\", country=\"{}\", reverse=\"{}\", asn=\"{}\"".format(username, date, hour, ip, country, asn, reverse))
if not alert_user:
# Nothing suspect here
exit(0)
if country:
# Format for mail
country = " (%s)" % country
# Body
body = u"""Bonjour %s,\n
Vous recevez ce message car vous vous êtes connecté sur le VPN %s le %s à %s, depuis l'IP %s%s.
Si vous n'êtes pas à l'origine de cette connexion, veuillez avertir immédiatement l'équipe sécurité à l'adresse suivante :
[email protected]\n
Cordialement,\n
Le serveur VPN""" % (username, server, date, hour, ip, country)
body += u"""
\n=== Infos techniques ===
IP : %s
ASN : %s
Reverse : %s
========================
""" % (ip, asn, reverse)
# Mail encoding, headers
msg = MIMEText(body.encode("utf-8"), 'plain', 'utf-8')
msg['Subject'] = u'[VPN %s] Connexion de %s (%s)%s' % (server, username, ip, country)
msg['From'] = from_mail
msg['To'] = to_mail
if alert_security:
msg['Cc'] = ", ".join(cc_mail)
recipients = [to_mail]
if alert_security:
recipients.extend(cc_mail)
s = smtplib.SMTP(SMTP_SERVER)
s.sendmail(from_mail, recipients, msg.as_string())
s.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment