From a754a9243aa16077eb62fe151addbcb1e0312cff Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Thu, 3 Jul 2025 18:36:29 +0200 Subject: [PATCH] Firewall: Aliases - add Expire option to external aliases to automatically cleanup tables via cron, closes https://github.com/opnsense/core/issues/8831 As expiretable was already used for predefined sshlockout and virusprot tables, we moved the option to the model and made sure the internal ones have their settings in the model as well. For simplicity, we flush the tables that need to be expired to cron, using either a 15 minute or 1 minute interval, depending on timing. pfctl offers the same functionality as expiretable now, so lets drop the latter for simplicity. --- Makefile | 1 - src/etc/inc/plugins.inc.d/core.inc | 12 +++++++++-- .../OPNsense/Firewall/Api/AliasController.php | 8 ++------ .../app/models/OPNsense/Firewall/Alias.xml | 4 ++++ .../Firewall/static_aliases/core.json | 4 ++++ .../app/views/OPNsense/Firewall/alias.volt | 20 +++++++++++++++++++ 6 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index e950ac69c6..a21d0d4544 100644 --- a/Makefile +++ b/Makefile @@ -140,7 +140,6 @@ CORE_DEPENDS?= ca_root_nss \ dhcrelay \ dnsmasq \ dpinger \ - expiretable \ filterlog \ flock \ flowd \ diff --git a/src/etc/inc/plugins.inc.d/core.inc b/src/etc/inc/plugins.inc.d/core.inc index 4374ca5a73..99de24b308 100644 --- a/src/etc/inc/plugins.inc.d/core.inc +++ b/src/etc/inc/plugins.inc.d/core.inc @@ -264,11 +264,19 @@ function core_cron() $jobs = array(); $jobs[]['autocron'] = array('/usr/local/sbin/configctl -d syslog archive', '1'); - $jobs[]['autocron'] = array('/usr/local/sbin/expiretable -v -t 3600 sshlockout', '2'); - $jobs[]['autocron'] = array('/usr/local/sbin/expiretable -v -t 3600 virusprot', '3'); $jobs[]['autocron'] = array('/usr/local/sbin/ping_hosts.sh', '*/4'); $jobs[]['autocron'] = array('/usr/local/sbin/configctl -d firmware changelog cron', '0', '22'); + foreach ((new \OPNsense\Firewall\Alias(true))->aliases->alias->iterateItems() as $alias) { + if ($alias->type->isEqual('external') && !$alias->expire->isEmpty()) { + $cmd = [exec_safe("/sbin/pfctl -t %s -T expire %s", [$alias->name, $alias->expire])]; + if ($alias->expire->asFloat() >= 3600) { + $cmd[] = '0,15,30,45'; /* every 15 minute cleanup */ + } + $jobs[]['autocron'] = $cmd; + } + } + /** * rrd graph collector, only schedule execution when enabled */ diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Firewall/Api/AliasController.php b/src/opnsense/mvc/app/controllers/OPNsense/Firewall/Api/AliasController.php index c2b60fbbbf..97345e1472 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Firewall/Api/AliasController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Firewall/Api/AliasController.php @@ -58,12 +58,7 @@ class AliasController extends ApiMutableModelControllerBase return $match_type && $match_cat; }; - $result = $this->searchBase( - "aliases.alias", - ['enabled', 'name', 'description', 'type', 'content', 'current_items', 'last_updated'], - "name", - $filter_funct - ); + $result = $this->searchBase("aliases.alias", null, "name", $filter_funct); /** * remap some source data from the model as searchBase() is not able to distinct this. @@ -338,6 +333,7 @@ class AliasController extends ApiMutableModelControllerBase if (!empty($bckresult['messages'])) { throw new UserException(implode("\n", $bckresult['messages']), gettext("Alias")); } + $backend->configdRun("cron restart", true); return array("status" => "ok"); } else { return array("status" => "failed"); diff --git a/src/opnsense/mvc/app/models/OPNsense/Firewall/Alias.xml b/src/opnsense/mvc/app/models/OPNsense/Firewall/Alias.xml index 1a89b04474..248f51d657 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Firewall/Alias.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Firewall/Alias.xml @@ -77,6 +77,10 @@ Bearer + + 60 + 999999999 + diff --git a/src/opnsense/mvc/app/models/OPNsense/Firewall/static_aliases/core.json b/src/opnsense/mvc/app/models/OPNsense/Firewall/static_aliases/core.json index d5e66d9fe3..5d4a651b65 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Firewall/static_aliases/core.json +++ b/src/opnsense/mvc/app/models/OPNsense/Firewall/static_aliases/core.json @@ -4,6 +4,7 @@ "name": "bogons", "type": "external", "description": "bogon networks (internal)", + "expire": "", "content": "" }, "bogonsv6": { @@ -11,6 +12,7 @@ "name": "bogonsv6", "type": "external", "description": "bogon networks IPv6 (internal)", + "expire": "", "content": "" }, "virusprot": { @@ -18,6 +20,7 @@ "name": "virusprot", "type": "external", "description": "overload table for rate limiting (internal)", + "expire": "3600", "content": "" }, "sshlockout": { @@ -25,6 +28,7 @@ "name": "sshlockout", "type": "external", "description": "abuse lockout table (internal)", + "expire": "3600", "content": "" } } diff --git a/src/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt b/src/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt index 4a0852db25..1ffe410120 100644 --- a/src/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt +++ b/src/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt @@ -454,6 +454,7 @@ $("#row_alias\\.authtype").hide(); $("#row_alias\\.interface").hide(); $("#row_alias\\.path_expression").hide(); + $("#row_alias\\.expire").hide(); switch ($(this).val()) { case 'authgroup': $("#alias_type_authgroup").show(); @@ -470,6 +471,7 @@ $("#alias\\.proto").selectpicker('show'); break; case 'external': + $("#row_alias\\.expire").show(); break; case 'networkgroup': $("#alias_type_networkgroup").show(); @@ -679,6 +681,7 @@ {{ lang._('Type') }} {{ lang._('Description') }} {{ lang._('Content') }} + {{ lang._('Expire') }} {{ lang._('Loaded#') }} {{ lang._('Last updated') }} {{ lang._('Commands') }} @@ -988,6 +991,23 @@ + + +
+ + {{lang._('Expire')}} +
+ + + + + + + + +