luci-app-banip: sync with banIP 1.5
authorDirk Brenken <dev@brenken.org>
Thu, 16 Jan 2025 19:17:38 +0000 (20:17 +0100)
committerDirk Brenken <dev@brenken.org>
Thu, 16 Jan 2025 19:18:38 +0000 (20:18 +0100)
Signed-off-by: Dirk Brenken <dev@brenken.org>
applications/luci-app-banip/Makefile
applications/luci-app-banip/htdocs/luci-static/resources/view/banip/feeds.js
applications/luci-app-banip/htdocs/luci-static/resources/view/banip/overview.js
applications/luci-app-banip/htdocs/luci-static/resources/view/banip/setreport.js
applications/luci-app-banip/root/usr/share/rpcd/acl.d/luci-app-banip.json

index 5f5dbefdbfb2a37b8456194f966442cea608ef8e..6b00a4cc02a33f7ce715e339207412d25df5e923 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2018-2023 Dirk Brenken (dev@brenken.org)
+# Copyright 2018-2025 Dirk Brenken (dev@brenken.org)
 # This is free software, licensed under the Apache License, Version 2.0
 
 include $(TOPDIR)/rules.mk
index 731ef9beb69585d5164d39f0fddc6a5d6548bebf..b14e6273503a60bc1d3cbf762baf5ebb5bb3c2ea 100644 (file)
@@ -143,6 +143,9 @@ function handleEdit(ev) {
                                case 'rule_6':
                                        subElements.rule_6 = value;
                                        break;
+                               case 'chain':
+                                       subElements.chain = value;
+                                       break;
                                case 'descr':
                                        subElements.descr = value;
                                        break;
@@ -169,7 +172,7 @@ return view.extend({
        },
 
        render: function (data) {
-               let m, s, o, feed, url_4, url_6, rule_4, rule_6, descr, flag;
+               let m, s, o, feed, url_4, url_6, rule_4, rule_6, chain, descr, flag;
 
                m = new form.JSONMap(data, _('Custom Feed Editor'), _('With this editor you can upload your local custom feed file or fill up an initial one (a 1:1 copy of the version shipped with the package). \
                        The file is located at \'/etc/banip/banip.custom.feeds\'. \
@@ -180,6 +183,7 @@ return view.extend({
                        rule_4 = m.data.data[feed].rule_4;
                        url_6 = m.data.data[feed].url_6;
                        rule_6 = m.data.data[feed].rule_6;
+                       chain = m.data.data[feed].chain;
                        descr = m.data.data[feed].descr;
                        flag = m.data.data[feed].flag;
 
@@ -211,7 +215,19 @@ return view.extend({
                                return true;
                        }
 
-                       o = s.option(form.Value, 'rule_4', _('Rulev4'));
+                       o = s.option(form.ListValue, 'rule_4', _('Rulev4'));
+                       o.value('/^127\\./{next}/^(([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)[[:space:]]/{printf \"%s,\\n\",$1}', _('<IPv4><SPACE>'));
+                       o.value('/^127\\./{next}/^(([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)$/{printf \"%s,\\n\",$1}', _('<IPv4><END>'));
+                       o.value('/^127\\./{next}/^(([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)[[:space:]]/{printf \"%s/%s,\\n\",$1,$3}', _('<IPv4><SPACE>, concatinated'));
+                       o.value('/^127\\./{next}/^(([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)$/{if(!seen[$1]++)printf \"%s,\\n\",$1}', _('<IPv4><END>, nodups'));
+                       o.value('/^127\\./{next}/^(([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)[-[:space:]]?/{printf \"%s,\\n\",$1}', _('<IPv4>[<SPACE>|<HYPHEN>]'));
+                       o.value('/127\\./{next}/(([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)[[:space:]]/{printf \"%s,\\n\",$2}', _('<DATE><IPv4><SPACE>'));
+                       o.value('BEGIN{FS=\",\"}/^127\\./{next}/^(([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)/{printf \"%s,\\n\",$1}', _('<IPv4>, csv'));
+                       o.value('BEGIN{IGNORECASE=1}/^127\\./{next}/^(([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)([[:space:]]NET)/{printf \"%s,\\n\",$1}', _('<IPv4><SPACE>NET'));
+                       o.value('BEGIN{IGNORECASE=1}/^127\\./{next}/^(([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\\/(1?[0-9]|2?[0-9]|3?[0-2]))?)([[:space:]]YOUR)/{printf \"%s,\\n\",$1}', _('<IPv4><SPACE>YOUR'));
+                       o.value('BEGIN{FS=\";\"}/content:\"127\\./{next}/(content:\"([1-9][0-9]{0,2}\\.){1}([0-9]{1,3}\\.){2}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\")/{printf \"%s,\\n\",substr($10,11,length($10)-11)}', _('<IPv4>, substring'));
+                       o.optional = true;
+                       o.rmempty = true;
 
                        o = s.option(form.Value, 'url_6', _('URLv6'));
                        o.validate = function (section_id, value) {
@@ -224,10 +240,20 @@ return view.extend({
                                return true;
                        }
 
-                       o = s.option(form.Value, 'rule_6', _('Rulev6'));
+                       o = s.option(form.ListValue, 'rule_6', _('Rulev6'));
+                       o.value('/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\\/(1?[0-2][0-8]|[0-9][0-9]))?)[[:space:]]/{printf \"%s,\\n\",$1}', _('<IPv6><SPACE>'));
+                       o.value('/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\\/(1?[0-2][0-8]|[0-9][0-9]))?)$/{printf \"%s,\\n\",$1}', _('<IPv6><END>'));
+                       o.optional = true;
+                       o.rmempty = true;
+
+                       o = s.option(form.ListValue, 'chain', _('Chain'));
+                       o.value('in', _('Inbound'));
+                       o.value('out', _('Outbound'));
+                       o.value('inout', _('Inbound & Outbound'));
+                       o.default = 'in';
 
                        o = s.option(form.Value, 'descr', _('Description'));
-                       o.datatype = 'and(minlength(3),maxlength(30))';
+                       o.datatype = 'and(minlength(5),maxlength(30))';
                        o.validate = function (section_id, value) {
                                if (!value) {
                                        return _('Empty field not allowed');
index b1dbbe0d7e3ce24858646c8592a90fcd4bf8adc0..8381da05471ec835a0baf9262d1149fdc9827802 100644 (file)
@@ -135,10 +135,6 @@ return view.extend({
                                                        if (last_run) {
                                                                last_run.textContent = rtRes.lastRun || '-';
                                                        }
-                                                       infSystem = document.getElementById('system');
-                                                       if (infSystem) {
-                                                               infSystem.textContent = rtRes.systemInfo || '-';
-                                                       }
                                                }
                                        } else {
                                                infStat = document.getElementById('status');
@@ -162,48 +158,44 @@ return view.extend({
                        return E('div', { 'class': 'cbi-section' }, [
                                E('h3', _('Information')),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('Status')),
-                                       E('div', { 'class': 'cbi-value-field spinning', 'id': 'status', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '\xa0')
-                               ]),
-                               E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('Version')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'version', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Status')),
+                                       E('div', { 'class': 'cbi-value-field spinning', 'id': 'status', 'style': 'margin-bottom:-5px;color:#37c;' }, '\xa0')
                                ]),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('Element Count')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'elements', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Version')),
+                                       E('div', { 'class': 'cbi-value-field', 'id': 'version', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
                                ]),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('Active Feeds')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'feeds', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Element Count')),
+                                       E('div', { 'class': 'cbi-value-field', 'id': 'elements', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
                                ]),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('Active Devices')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'devices', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Active Feeds')),
+                                       E('div', { 'class': 'cbi-value-field', 'id': 'feeds', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
                                ]),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('Active Uplink')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'uplink', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Active Devices')),
+                                       E('div', { 'class': 'cbi-value-field', 'id': 'devices', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
                                ]),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('NFT Information')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'nft', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Active Uplink')),
+                                       E('div', { 'class': 'cbi-value-field', 'id': 'uplink', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
                                ]),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('Run Information')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'run', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('NFT Information')),
+                                       E('div', { 'class': 'cbi-value-field', 'id': 'nft', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
                                ]),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('Run Flags')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'flags', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Run Information')),
+                                       E('div', { 'class': 'cbi-value-field', 'id': 'run', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
                                ]),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('Last Run')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'last', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Run Flags')),
+                                       E('div', { 'class': 'cbi-value-field', 'id': 'flags', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
                                ]),
                                E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;font-weight:bold;padding-top:0rem;' }, _('System Information')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'system', 'style': 'margin-bottom:-5px;color:#37c;font-weight:bold;' }, '-')
+                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Last Run')),
+                                       E('div', { 'class': 'cbi-value-field', 'id': 'last', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
                                ]),
                                E('div', { class: 'right' }, [
                                        E('button', {
@@ -258,7 +250,7 @@ return view.extend({
                o = s.taboption('general', form.DummyValue, '_sub');
                o.rawhtml = true;
                o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs a banIP service restart to take effect.') + '</em>'
-                                       + '<hr style="width: 200px; height: 1px;" />';
+                       + '<hr style="width: 200px; height: 1px;" />';
 
                o = s.taboption('general', form.Flag, 'ban_enabled', _('Enabled'), _('Enable the banIP service.'));
                o.rmempty = false;
@@ -345,7 +337,7 @@ return view.extend({
                o = s.taboption('advanced', form.DummyValue, '_sub');
                o.rawhtml = true;
                o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs a banIP service restart to take effect.') + '</em>'
-                                       + '<hr style="width: 200px; height: 1px;" />';
+                       + '<hr style="width: 200px; height: 1px;" />';
 
                o = s.taboption('advanced', form.ListValue, 'ban_nicelimit', _('Nice Level'), _('The selected priority will be used for banIP background processing.'));
                o.value('-20', _('Highest Priority'));
@@ -401,28 +393,27 @@ return view.extend({
                o.placeholder = '/tmp/banIP-report';
                o.rmempty = true;
 
+               o = s.taboption('advanced', form.Value, 'ban_errordir', _('Error Directory'), _('Target directory for banIP-related error files.'));
+               o.placeholder = '/tmp/banIP-error';
+               o.rmempty = true;
+
                o = s.taboption('advanced', form.Flag, 'ban_deduplicate', _('Deduplicate IPs'), _('Deduplicate IP addresses across all active Sets and tidy up the local blocklist.'));
                o.default = 1
                o.rmempty = false;
 
-               o = s.taboption('advanced', form.Flag, 'ban_reportelements', _('Report Elements'), _('List Set elements in the status and report, disable this to reduce the CPU load.'));
-               o.default = 1
-               o.optional = true;
-
                /*
                        advanced chain settings tab
                */
                o = s.taboption('adv_chain', form.DummyValue, '_sub');
                o.rawhtml = true;
                o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs a banIP service restart to take effect.') + '</em>'
-                                       + '<hr style="width: 200px; height: 1px;" />';
+                       + '<hr style="width: 200px; height: 1px;" />';
 
                o = s.taboption('adv_chain', form.ListValue, 'ban_nftpriority', _('Chain Priority'), _('Set the nft chain priority within the banIP table, lower values means higher priority.'));
                o.value('10');
                o.value('0');
                o.value('-100');
                o.value('-150');
-               o.value('-200');
                o.default = '-100';
                o.placeholder = _('-- default --');
                o.create = true;
@@ -493,7 +484,7 @@ return view.extend({
                o = s.taboption('adv_set', form.DummyValue, '_sub');
                o.rawhtml = true;
                o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs a banIP service restart to take effect.') + '</em>'
-                                       + '<hr style="width: 200px; height: 1px;" />';
+                       + '<hr style="width: 200px; height: 1px;" />';
 
                o = s.taboption('adv_set', form.ListValue, 'ban_nftpolicy', _('Set Policy'), _('Set the nft policy for banIP-related Sets.'));
                o.value('memory', _('memory'));
@@ -504,23 +495,30 @@ return view.extend({
                o.optional = true;
                o.rmempty = true;
 
-               o = s.taboption('adv_set', form.ListValue, 'ban_blocktype', _('Block Type'), _('Drop packets silently or actively reject the traffic on WAN-Input and WAN-Forward chains.'));
-               o.value('drop', _('drop'));
-               o.value('reject', _('reject'));
-               o.default = 'drop';
+               o = s.taboption('adv_set', form.ListValue, 'ban_nftretry', _('Set Load Retries'), _('Number of Set load attempts in case of an error.'));
+               o.value('1');
+               o.value('3');
+               o.value('5');
+               o.value('10');
+               o.default = '5';
                o.placeholder = _('-- default --');
                o.create = true;
                o.optional = true;
                o.rmempty = true;
 
-               o = s.taboption('adv_set', form.ListValue, 'ban_blockpolicy', _('Default Block Policy'), _('By default each feed is active in all supported chains. Limit the default block policy to a certain chain.'));
-               o.value('input', _('WAN-Input Chain'));
-               o.value('forwardwan', _('WAN-Forward Chain'));
-               o.value('forwardlan', _('LAN-Forward Chain'));
+               o = s.taboption('adv_set', form.Flag, 'ban_nftcount', _('Set Element Counter'), _('Enable nft counter for every Set element.'));
+               o.rmempty = true;
+
+               o = s.taboption('adv_set', form.ListValue, 'ban_blockpolicy', _('Inbound Block Policy'), _('Drop packets silently or actively reject Inbound traffic.'));
+               o.value('drop', _('drop'));
+               o.value('reject', _('reject'));
+               o.default = 'drop';
+               o.placeholder = _('-- default --');
+               o.create = true;
                o.optional = true;
                o.rmempty = true;
 
-               let feed, feeds, descr;
+               let feed, feeds, chain, descr;
                if (result && Object.keys(result).length) {
                        if (result[0]) {
                                try {
@@ -538,7 +536,7 @@ return view.extend({
                        }
                }
                if (feeds && Object.keys(feeds).length) {
-                       o = s.taboption('adv_set', form.MultiValue, 'ban_blockinput', _('WAN-Input Chain'), _('Limit certain feeds to the WAN-Input chain.'));
+                       o = s.taboption('adv_set', form.MultiValue, 'ban_feedin', _('Inbound Feed'), _('Override the default feed configuration and apply the feed to the inbound chain only.'));
                        o.value('allowlist', _('local allowlist'));
                        o.value('blocklist', _('local blocklist'));
                        for (let i = 0; i < Object.keys(feeds).length; i++) {
@@ -548,7 +546,7 @@ return view.extend({
                        o.optional = true;
                        o.rmempty = true;
 
-                       o = s.taboption('adv_set', form.MultiValue, 'ban_blockforwardwan', _('WAN-Forward Chain'), _('Limit certain feeds to the WAN-Forward chain.'));
+                       o = s.taboption('adv_set', form.MultiValue, 'ban_feedout', _('Outbound Feed'), _('Override the default feed configuration and apply the feed to the outbound chain only.'));
                        o.value('allowlist', _('local allowlist'));
                        o.value('blocklist', _('local blocklist'));
                        for (let i = 0; i < Object.keys(feeds).length; i++) {
@@ -558,7 +556,27 @@ return view.extend({
                        o.optional = true;
                        o.rmempty = true;
 
-                       o = s.taboption('adv_set', form.MultiValue, 'ban_blockforwardlan', _('LAN-Forward Chain'), _('Limit certain feeds to the LAN-Forward chain.'));
+                       o = s.taboption('adv_set', form.MultiValue, 'ban_feedinout', _('Inbound & Outbound Feed'), _('Override the default feed configuration and apply the feed to the inbound and outbound chain.'));
+                       o.value('allowlist', _('local allowlist'));
+                       o.value('blocklist', _('local blocklist'));
+                       for (let i = 0; i < Object.keys(feeds).length; i++) {
+                               feed = Object.keys(feeds)[i].trim();
+                               o.value(feed);
+                       }
+                       o.optional = true;
+                       o.rmempty = true;
+
+                       o = s.taboption('adv_set', form.MultiValue, 'ban_feedfreset', _('Feed Flag Reset'), _('Override the default feed configuration and remove existing port/protocol limitations.'));
+                       o.value('allowlist', _('local allowlist'));
+                       o.value('blocklist', _('local blocklist'));
+                       for (let i = 0; i < Object.keys(feeds).length; i++) {
+                               feed = Object.keys(feeds)[i].trim();
+                               o.value(feed);
+                       }
+                       o.optional = true;
+                       o.rmempty = true;
+
+                       o = s.taboption('adv_set', form.MultiValue, 'ban_feedcomplete', _('Feed Complete'), _('Opt out the feed from the deduplication process.'));
                        o.value('allowlist', _('local allowlist'));
                        o.value('blocklist', _('local blocklist'));
                        for (let i = 0; i < Object.keys(feeds).length; i++) {
@@ -575,7 +593,7 @@ return view.extend({
                o = s.taboption('adv_log', form.DummyValue, '_sub');
                o.rawhtml = true;
                o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs a banIP service restart to take effect.') + '</em>'
-                                       + '<hr style="width: 200px; height: 1px;" />';
+                       + '<hr style="width: 200px; height: 1px;" />';
 
                o = s.taboption('adv_log', form.ListValue, 'ban_nftloglevel', _('NFT Log Level'), _('Set the syslog level for NFT logging.'));
                o.value('emerg', _('emerg'));
@@ -592,16 +610,13 @@ return view.extend({
                o.optional = true;
                o.rmempty = true;
 
-               o = s.taboption('adv_log', form.Flag, 'ban_logprerouting', _('Log Prerouting'), _('Log suspicious Prerouting packets.'));
-               o.rmempty = false;
-
-               o = s.taboption('adv_log', form.Flag, 'ban_loginput', _('Log WAN-Input'), _('Log suspicious incoming WAN packets.'));
+               o = s.taboption('adv_log', form.Flag, 'ban_logprerouting', _('Log Prerouting'), _('Log suspicious packets in the Prerouting chain.'));
                o.rmempty = false;
 
-               o = s.taboption('adv_log', form.Flag, 'ban_logforwardwan', _('Log WAN-Forward'), _('Log suspicious forwarded WAN packets.'));
+               o = s.taboption('adv_log', form.Flag, 'ban_loginbound', _('Log Inbound'), _('Log suspicious packets in the WAN-Input and WAN-Forward chain.'));
                o.rmempty = false;
 
-               o = s.taboption('adv_log', form.Flag, 'ban_logforwardlan', _('Log LAN-Forward'), _('Log suspicious forwarded LAN packets.'));
+               o = s.taboption('adv_log', form.Flag, 'ban_logoutbound', _('Log Outbound'), _('Log suspicious packets in the LAN-Forward chain.'));
                o.rmempty = false;
 
                o = s.taboption('adv_log', form.Value, 'ban_logreadfile', _('Logfile Location'), _('Location for parsing the log file, e.g. via syslog-ng, to deactivate the standard parsing via logread.'));
@@ -626,7 +641,15 @@ return view.extend({
                o.datatype = 'range(1,10)';
                o.rmempty = true;
 
-               o = s.taboption('adv_log', form.DynamicList, 'ban_logterm', _('Log Terms'), _('The default regular expressions are filtering suspicious ssh, LuCI, nginx and asterisk traffic.'));
+               o = s.taboption('adv_log', form.DynamicList, 'ban_logterm', _('Log Terms'), _('Regular expressions to detect suspicious IPs in the system log.'));
+               o.value('Exit before auth from', _('dropbear failed login'));
+               o.value('luci: failed login', _('LuCI failed login'));
+               o.value('error: maximum authentication attempts exceeded', _('sshd failed login'));
+               o.value('sshd.*Connection closed by.*\[preauth\]', _('sshd closed connection'));
+               o.value('SecurityEvent=\"InvalidAccountID\".*RemoteAddress=', _('asterisk invalid account'));
+               o.value('received a suspicious remote IP \'.*\'', _('nginx suspicious IP'));
+               o.value('TLS Error: could not determine wrapping from \[AF_INET\]', _('openvpn TLS error'));
+               o.value('AdGuardHome.*\[error\].*/control/login: from ip', _('AdGuardHome login error'));
                o.optional = true;
                o.rmempty = true;
 
@@ -656,7 +679,7 @@ return view.extend({
                o = s.taboption('adv_email', form.DummyValue, '_sub');
                o.rawhtml = true;
                o.default = '<em style="color:#37c;font-weight:bold;">' + _('To enable email notifications, set up the \'msmtp\' package and specify a vaild E-Mail receiver address.') + '</em>'
-                                       + '<hr style="width: 200px; height: 1px;" />';
+                       + '<hr style="width: 200px; height: 1px;" />';
 
                o = s.taboption('adv_email', form.Flag, 'ban_mailnotification', _('E-Mail Notification'), _('Receive E-Mail notifications with every banIP run.'));
                o.rmempty = true;
@@ -684,20 +707,25 @@ return view.extend({
                o = s.taboption('feeds', form.DummyValue, '_sub');
                o.rawhtml = true;
                o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs a banIP service reload to take effect.') + '</em>'
-                                       + '<hr style="width: 200px; height: 1px;" />'
-                                       + '<em style="color:#37c;font-weight:bold;">' + _('External Blocklist Feeds') + '</em>';
+                       + '<hr style="width: 200px; height: 1px;" />'
+                       + '<em style="color:#37c;font-weight:bold;">' + _('External Blocklist Feeds') + '</em>';
 
                if (feeds && Object.keys(feeds).length) {
                        o = s.taboption('feeds', form.MultiValue, 'ban_feed', _('Blocklist Feed'));
                        for (let i = 0; i < Object.keys(feeds).length; i++) {
                                feed = Object.keys(feeds)[i].trim();
+                               chain = feeds[feed].chain.trim() || 'in';
                                descr = feeds[feed].descr.trim() || '-';
-                               o.value(feed, feed + ' (' + descr + ')');
+                               o.value(feed, feed + ' (' + chain + ', ' + descr + ')');
                        }
                        o.optional = true;
                        o.rmempty = true;
                }
 
+               o = s.taboption('feeds', form.DummyValue, '_feeds');
+               o.rawhtml = true;
+               o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('Country Selection') + '</em>';
+
                let err, ccode, rir, country, countries = [];
                if (result && Object.keys(result[2]).length) {
                        countries = result[2].trim().split('\n');
@@ -731,11 +759,21 @@ return view.extend({
                o.optional = true;
                o.rmempty = true;
 
+               o = s.taboption('feeds', form.Flag, 'ban_countrysplit', _('Split Country Set'), _('The selected Countries are stored in separate Sets.'));
+               o.rmempty = true;
+
+               o = s.taboption('feeds', form.DummyValue, '_feeds');
+               o.rawhtml = true;
+               o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('ASN Selection') + '</em>';
+
                o = s.taboption('feeds', form.DynamicList, 'ban_asn', _('ASNs'));
                o.datatype = 'uinteger';
                o.optional = true;
                o.rmempty = true;
 
+               o = s.taboption('feeds', form.Flag, 'ban_asnsplit', _('Split ASN Set'), _('The selected ASNs are stored in separate Sets.'));
+               o.rmempty = true;
+
                o = s.taboption('feeds', form.DummyValue, '_feeds');
                o.rawhtml = true;
                o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('External Allowlist Feeds') + '</em>';
index 845e081e880d07534fe57d9e50b72905401c3bc3..94c16157e3737577d6f46986d576f15d40487b09 100644 (file)
@@ -137,7 +137,7 @@ return view.extend({
        load: function () {
                return Promise.all([
                        L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['report', 'json']), ''),
-                       L.resolveDefault(fs.exec_direct('/usr/sbin/nft', ['-tj', 'list', 'ruleset']), '')
+                       L.resolveDefault(fs.exec_direct('/usr/sbin/nft', ['-tj', 'list', 'table', 'inet', 'banIP']), '')
                ]);
        },
 
@@ -158,35 +158,35 @@ return view.extend({
                tblSets = E('table', { 'class': 'table', 'id': 'sets' }, [
                        E('tr', { 'class': 'tr table-titles' }, [
                                E('th', { 'class': 'th' }, _('Set')),
-                               E('th', { 'class': 'th right', 'style': 'padding-right: 20px' }, _('Elements')),
-                               E('th', { 'class': 'th' }, _('WAN-Input (packets)')),
-                               E('th', { 'class': 'th' }, _('WAN-Forward (packets)')),
-                               E('th', { 'class': 'th' }, _('LAN-Forward (packets)')),
-                               E('th', { 'class': 'th' }, _('Port/Protocol Limit'))
+                               E('th', { 'class': 'th right', 'style': 'padding-right: 20px' }, _('Count')),
+                               E('th', { 'class': 'th' }, _('Inbound&#160;(packets)')),
+                               E('th', { 'class': 'th' }, _('Outbound&#160;(packets)')),
+                               E('th', { 'class': 'th' }, _('Port&#160;/&#160;Protocol')),
+                               E('th', { 'class': 'th' }, _('Elements'))
                        ])
                ]);
 
                if (content.sets) {
-                       let cnt1, cnt2, cnt3;
+                       let cnt1, cnt2;
                        Object.keys(content.sets).forEach(function (key) {
-                               cnt1 = content.sets[key].cnt_input ? ': (' + content.sets[key].cnt_input + ')' : '';
-                               cnt2 = content.sets[key].cnt_forwardwan ? ': (' + content.sets[key].cnt_forwardwan + ')' : '';
-                               cnt3 = content.sets[key].cnt_forwardlan ? ': (' + content.sets[key].cnt_forwardlan + ')' : '';
+                               cnt1 = content.sets[key].cnt_inbound ? ': (' + content.sets[key].cnt_inbound + ')' : '';
+                               cnt2 = content.sets[key].cnt_outbound ? ': (' + content.sets[key].cnt_outbound + ')' : '';
                                rowSets.push([
                                        E('em', key),
                                        E('em', { 'style': 'padding-right: 20px' }, content.sets[key].cnt_elements),
-                                       E('em', content.sets[key].input + cnt1),
-                                       E('em', content.sets[key].wan_forward + cnt2),
-                                       E('em', content.sets[key].lan_forward + cnt3),
-                                       E('em', content.sets[key].port)
+                                       E('em', content.sets[key].inbound + cnt1),
+                                       E('em', content.sets[key].outbound + cnt2),
+                                       E('em', content.sets[key].port),
+                                       E('em', content.sets[key].set_elements)
                                ]);
                        });
                        rowSets.push([
                                E('em', { 'style': 'font-weight: bold' }, content.sum_sets),
-                               E('em', { 'style': 'font-weight: bold; padding-right: 20px' }, content.sum_setelements),
-                               E('em', { 'style': 'font-weight: bold' }, content.sum_setinput + ' (' + content.sum_cntinput + ')'),
-                               E('em', { 'style': 'font-weight: bold' }, content.sum_setforwardwan + ' (' + content.sum_cntforwardwan + ')'),
-                               E('em', { 'style': 'font-weight: bold' }, content.sum_setforwardlan + ' (' + content.sum_cntforwardlan + ')')
+                               E('em', { 'style': 'font-weight: bold; padding-right: 20px' }, content.sum_cntelements),
+                               E('em', { 'style': 'font-weight: bold' }, content.sum_setinbound + ' (' + content.sum_cntinbound + ')'),
+                               E('em', { 'style': 'font-weight: bold' }, content.sum_setoutbound + ' (' + content.sum_cntoutbound + ')'),
+                               E('em', { 'style': 'font-weight: bold' }, content.sum_setports),
+                               E('em', { 'style': 'font-weight: bold' }, content.sum_setelements)
                        ]);
                }
                cbi_update_table(tblSets, rowSets);
index 41b4b6650b630afd830658d8a385e67236043acf..4abe405f822a3e6e4da2f138d26ca5aeccb4050a 100644 (file)
@@ -42,7 +42,7 @@
                                "/usr/sbin/logread -e  banIP/": [
                                        "exec"
                                ],
-                               "/usr/sbin/nft -tj list ruleset": [
+                               "/usr/sbin/nft -tj list table inet banIP": [
                                        "exec"
                                ],
                                "/etc/init.d/banip stop": [