diff --git a/src/opnsense/scripts/filter/kill_states.py b/src/opnsense/scripts/filter/kill_states.py
new file mode 100755
index 000000000..3072cbffe
--- /dev/null
+++ b/src/opnsense/scripts/filter/kill_states.py
@@ -0,0 +1,52 @@
+#!/usr/local/bin/python3
+
+"""
+ Copyright (c) 2021 Ad Schellevis
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+"""
+import argparse
+import ujson
+import subprocess
+from lib.states import query_states
+
+
+if __name__ == '__main__':
+ result = dict()
+ # parse input arguments
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--filter', help='filter results', default='')
+ parser.add_argument('--label', help='label / rule id', default='')
+ inputargs = parser.parse_args()
+
+ # collect all unique state id's
+ commands = dict()
+ for record in query_states(rule_label=inputargs.label, filter_str=inputargs.filter):
+ commands[record['id']] = "/sbin/pfctl -k id -k %s" % record['id']
+
+ # drop list of states in chunks
+ chunk_size = 500
+ commands = list(commands.values())
+ for chunk in [commands[i:i + chunk_size] for i in range(0, len(commands), chunk_size)]:
+ sp = subprocess.run([";\n".join(chunk)], capture_output=True, text=True, shell=True)
+ print(ujson.dumps({'dropped_states': len(commands)}))
diff --git a/src/opnsense/scripts/filter/list_rule_ids.py b/src/opnsense/scripts/filter/list_rule_ids.py
new file mode 100755
index 000000000..4b81e7fd1
--- /dev/null
+++ b/src/opnsense/scripts/filter/list_rule_ids.py
@@ -0,0 +1,44 @@
+#!/usr/local/bin/python3
+
+"""
+ Copyright (c) 2021 Ad Schellevis
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+"""
+import ujson
+from lib.states import fetch_rule_labels
+HEX_DIGITS = set("0123456789abcdef")
+
+result = list()
+unique_ids = set()
+for record in fetch_rule_labels().values():
+ if len(record['rid']) == 32 and set(record['rid']).issubset(HEX_DIGITS):
+ if record['rid'] not in unique_ids:
+ if record['descr'] != "":
+ result.append({'id': record['rid'], 'descr': record['descr']})
+ else:
+ result.append({'id': record['rid'], 'descr': "-- %s" % record['rid']})
+ unique_ids.add(record['rid'])
+
+result = sorted(result, key=lambda k: k['descr'])
+print(ujson.dumps(result))
diff --git a/src/opnsense/scripts/filter/list_states.py b/src/opnsense/scripts/filter/list_states.py
index 09e376e69..5a47ad3f3 100755
--- a/src/opnsense/scripts/filter/list_states.py
+++ b/src/opnsense/scripts/filter/list_states.py
@@ -42,11 +42,11 @@ if __name__ == '__main__':
parser.add_argument('--offset', help='offset results', default='')
inputargs = parser.parse_args()
- # apply offset and limit
result = {
'details': query_states(rule_label=inputargs.label, filter_str=inputargs.filter)
}
result['total_entries'] = len(result['details'])
+ # apply offset and limit
if inputargs.offset.isdigit():
result['details'] = result['details'][int(inputargs.offset):]
if inputargs.limit.isdigit() and len(result['details']) >= int(inputargs.limit):
diff --git a/src/opnsense/service/conf/actions.d/actions_filter.conf b/src/opnsense/service/conf/actions.d/actions_filter.conf
index 729788ddf..ac4adcfea 100644
--- a/src/opnsense/service/conf/actions.d/actions_filter.conf
+++ b/src/opnsense/service/conf/actions.d/actions_filter.conf
@@ -41,6 +41,11 @@ parameters: --filter=%s --limit=%s --offset=%s --label=%s
type:script_output
message:request pf states
+[list.rule_ids]
+command:/usr/local/opnsense/scripts/filter/list_rule_ids.py
+parameters:
+type:script_output
+message:request active rule id's and descriptions
[list.pfsync]
command:/usr/local/opnsense/scripts/filter/list_pfsync.py
@@ -114,6 +119,12 @@ parameters: -k id -k %s/%s 2>&1 && exit 0
type:script_output
message:kill pf state ( %s %s )
+[kill.states]
+command:/usr/local/opnsense/scripts/filter/kill_states.py
+parameters: --filter=%s --label=%s
+type:script_output
+message:kill pf states
+
[find_table_references]
command:/usr/local/opnsense/scripts/filter/find_table_references.py
parameters: %s