From 38078c65a2b59b23c0a599e2409c48456987e645 Mon Sep 17 00:00:00 2001 From: Guillaume Destuynder Date: Fri, 23 Jan 2015 01:39:32 +0100 Subject: [PATCH] New alert for https://github.com/mozilla-it/duo_openvpn Alerts when fDuoSecurity contact fails, which is means either authentication was refused, either granted based on a single authentication factor ("fail open"). --- alerts/duo_fail_open.py | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 alerts/duo_fail_open.py diff --git a/alerts/duo_fail_open.py b/alerts/duo_fail_open.py new file mode 100644 index 00000000..a7f68a04 --- /dev/null +++ b/alerts/duo_fail_open.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# Copyright (c) 2014 Mozilla Corporation +# +# Contributors: +# kang@mozilla.com +# +# This script alerts when openvpn's duo security failed to contact the duo server and let the user in. +# This is a very serious warning that must be acted upon as it means MFA failed and only one factor was validated (in +# this case a VPN certificate) + +from lib.alerttask import AlertTask +import pyes + +class AlertDuoFailOpen(AlertTask): + def main(self): + # look for events in last 15 mins + date_timedelta = dict(minutes=15) + # Configure filters using pyes + must = [ + pyes.TermFilter('_type', 'event'), + pyes.TermFilter('_source.tags', 'openvpn,duosecurity'), + pyes.QueryFilter(pyes.MatchQuery('summary','DuoAPI contact failed','phrase')), + pyes.QueryFilter(pyes.MatchQuery('summary','DuoAPI contact failed','phrase')), + ] + self.filtersManual(date_timedelta, must=must) + + # Search aggregations on field 'sourceipaddress', keep 50 samples of events at most + self.searchEventsAggreg('hostname', samplesLimit=1) + # alert when >= X matching events in an aggregation + # in this case, always + self.walkAggregations(threshold=1) + + # Set alert properties + def onAggreg(self, aggreg): + # aggreg['count']: number of items in the aggregation, ex: number of failed login attempts + # aggreg['value']: value of the aggregation field, ex: toto@example.com + # aggreg['events']: list of events in the aggregation + category = 'bypass' + tags = ['openvpn', 'duosecurity'] + severity = 'WARNING' + + summary = ('DuoSecurity OpenVPN contact failed, fail open triggered on {0}'.aggreg['value'])) + + # Create the alert object based on these properties + return self.createAlertDict(summary, category, tags, aggreg['events'], severity)