From 76ec2c13ae93361b34416678fcdf8fde99e53205 Mon Sep 17 00:00:00 2001 From: jkellerer Date: Fri, 11 Jun 2021 09:48:37 +0200 Subject: [PATCH] Maltrail: Integrate fail2ban IP-list with firewall aliases (#2017) --- security/maltrail/Makefile | 2 +- security/maltrail/pkg-descr | 4 + .../Maltrail/Api/ServerController.php | 77 +++++++++++++++++++ .../OPNsense/Maltrail/forms/server.xml | 6 ++ .../app/models/OPNsense/Maltrail/Server.xml | 6 +- .../templates/OPNsense/Maltrail/maltrail.conf | 3 + 6 files changed, 96 insertions(+), 2 deletions(-) diff --git a/security/maltrail/Makefile b/security/maltrail/Makefile index b12529d08..04126919b 100644 --- a/security/maltrail/Makefile +++ b/security/maltrail/Makefile @@ -1,5 +1,5 @@ PLUGIN_NAME= maltrail -PLUGIN_VERSION= 1.7 +PLUGIN_VERSION= 1.8 PLUGIN_COMMENT= Malicious traffic detection system PLUGIN_DEPENDS= maltrail PLUGIN_MAINTAINER= m.muenz@gmail.com diff --git a/security/maltrail/pkg-descr b/security/maltrail/pkg-descr index 9863acea0..0bb1e6287 100644 --- a/security/maltrail/pkg-descr +++ b/security/maltrail/pkg-descr @@ -11,6 +11,10 @@ WWW: https://github.com/stamparm/maltrail Changelog --------- +1.8 + +* Add firewall alias "BlocklistMaltrail" that points to the built-in ip block list + 1.7 * Allow sensor cron restart diff --git a/security/maltrail/src/opnsense/mvc/app/controllers/OPNsense/Maltrail/Api/ServerController.php b/security/maltrail/src/opnsense/mvc/app/controllers/OPNsense/Maltrail/Api/ServerController.php index afc87089f..a42c49510 100644 --- a/security/maltrail/src/opnsense/mvc/app/controllers/OPNsense/Maltrail/Api/ServerController.php +++ b/security/maltrail/src/opnsense/mvc/app/controllers/OPNsense/Maltrail/Api/ServerController.php @@ -29,9 +29,86 @@ namespace OPNsense\Maltrail\Api; use OPNsense\Base\ApiMutableModelControllerBase; +use OPNsense\Firewall\Alias; class ServerController extends ApiMutableModelControllerBase { protected static $internalModelClass = '\OPNsense\Maltrail\Server'; protected static $internalModelName = 'server'; + + protected function setActionHook() + { + $model = $this->getModel(); + + // Handle addition/removal of "BlocklistMaltrail" + if (strval($model->addblocklistalias) == "1") { + $enabled = strval($model->enabled) == "1"; + $address = trim(strval($model->listenaddress)); + + if ($address == "0.0.0.0") { + $address = "127.0.0.1"; + } else if ($address == "::") { + $address = "::1"; + } + + if (strpos($address, ':') !== false) { + $address = "[$address]"; + } + + $address = $address . ':' . strval($model->listenport); + + self::toggleBlocklistAlias(true, $enabled, $address); + } else { + self::toggleBlocklistAlias(false); + } + } + + const BLOCKLIST_ALIAS_NAME = "BlocklistMaltrail"; + const BLOCKLIST_ALIAS_DESCRIPTION = "Autogenerated alias for Maltrail's fail2ban feature"; + const BLOCKLIST_ALIAS_UPDATE_FREQ = (1 / 24 / 60 * 5); // (1) is 24 hours | (1 / 24 / 60 * 5) is every 5 minutes + + private static function toggleBlocklistAlias(bool $add, bool $enabled = false, string $addressAndPort = "") + { + $model = new Alias(); + + // Search for existing alias + $blocklist = null; + $blocklistIndex = null; + foreach ($model->aliases->alias->iterateItems() as $index => $alias) { + if (strval($alias->name) == self::BLOCKLIST_ALIAS_NAME) { + $blocklist = $alias; + $blocklistIndex = $index; + break; + } + } + + // Add, update or remove the alias + if ($add) { + if ($blocklist === null) { + $blocklist = $model->aliases->alias->add(); + $blocklist->name = self::BLOCKLIST_ALIAS_NAME; + $blocklist->description = self::BLOCKLIST_ALIAS_DESCRIPTION; + $blocklist->updatefreq = strval(self::BLOCKLIST_ALIAS_UPDATE_FREQ); + } + + $url = "http://$addressAndPort/fail2ban"; + $enabled = ($enabled ? "1" : "0"); + + $needsUpdate = strval($blocklist->type) != "urltable" + || strval($blocklist->content) != $url + || strval($blocklist->enabled) != $enabled; + + if ($needsUpdate) { + $blocklist->type = "urltable"; + $blocklist->content = $url; + $blocklist->enabled = $enabled; + + $model->serializeToConfig(); + } + } else if ($blocklistIndex !== null) { + if ($model->aliases->alias->del($blocklistIndex)) { + $model->serializeToConfig(); + } + } + } } diff --git a/security/maltrail/src/opnsense/mvc/app/controllers/OPNsense/Maltrail/forms/server.xml b/security/maltrail/src/opnsense/mvc/app/controllers/OPNsense/Maltrail/forms/server.xml index 67d433f29..03ca77c5c 100644 --- a/security/maltrail/src/opnsense/mvc/app/controllers/OPNsense/Maltrail/forms/server.xml +++ b/security/maltrail/src/opnsense/mvc/app/controllers/OPNsense/Maltrail/forms/server.xml @@ -5,6 +5,12 @@ checkbox This will activate the Maltrail server. You can use this service to also collect data from remote Maltrail sensors. + + server.addblocklistalias + + checkbox + Adds firewall alias "BlocklistMaltrail" referencing Maltrail's "/fail2ban" IP list. You can use this alias to block IPs that Maltrail detected as malicious. + server.listenaddress diff --git a/security/maltrail/src/opnsense/mvc/app/models/OPNsense/Maltrail/Server.xml b/security/maltrail/src/opnsense/mvc/app/models/OPNsense/Maltrail/Server.xml index 0c9454835..94df269c2 100644 --- a/security/maltrail/src/opnsense/mvc/app/models/OPNsense/Maltrail/Server.xml +++ b/security/maltrail/src/opnsense/mvc/app/models/OPNsense/Maltrail/Server.xml @@ -1,12 +1,16 @@ //OPNsense/maltrail/server Maltrail server configuration - 0.0.1 + 0.0.2 0 Y + + 0 + Y + 0.0.0.0 Y diff --git a/security/maltrail/src/opnsense/service/templates/OPNsense/Maltrail/maltrail.conf b/security/maltrail/src/opnsense/service/templates/OPNsense/Maltrail/maltrail.conf index 85943100f..5e107c94c 100644 --- a/security/maltrail/src/opnsense/service/templates/OPNsense/Maltrail/maltrail.conf +++ b/security/maltrail/src/opnsense/service/templates/OPNsense/Maltrail/maltrail.conf @@ -7,6 +7,9 @@ HTTP_ADDRESS {{ OPNsense.maltrail.server.listenaddress }} HTTP_PORT {{ OPNsense.maltrail.server.listenport }} USE_SSL false +# Regular expression to be used in external /fail2ban calls for extraction of attacker source IPs +FAIL2BAN_REGEX attacker|reputation|potential[^"]*(web scan|directory traversal|injection|remote code)|spammer|mass scanner + {% if helpers.exists('OPNsense.maltrail.server.loglistenaddress') and OPNsense.maltrail.server.loglistenaddress != '' %} UDP_ADDRESS {{ OPNsense.maltrail.server.loglistenaddress }} {% endif %}