Skip to content

Commit 2eb0501

Browse files
committed
luci-app-banip: sync with banIP-1.8.0-1
Signed-off-by: Dirk Brenken <dev@brenken.org>
1 parent 9e4d870 commit 2eb0501

File tree

8 files changed

+86
-103
lines changed

8 files changed

+86
-103
lines changed

applications/luci-app-banip/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# Copyright 2018-2025 Dirk Brenken (dev@brenken.org)
1+
# Copyright 2018-2026 Dirk Brenken (dev@brenken.org)
22
# This is free software, licensed under the Apache License, Version 2.0
33

44
include $(TOPDIR)/rules.mk
55

66
LUCI_TITLE:=LuCI support for banIP
77
LUCI_DEPENDS:=+luci-base +banip
88

9-
PKG_VERSION:=1.6.0
9+
PKG_VERSION:=1.8.0
1010
PKG_RELEASE:=1
1111
PKG_LICENSE:=Apache-2.0
1212
PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>

applications/luci-app-banip/htdocs/luci-static/resources/view/banip/allowlist.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const resetScroll = () => {
1313
return view.extend({
1414
load: function () {
1515
return L.resolveDefault(fs.stat(localFile), "")
16-
.then(function (stat) {
16+
.then(function (stat) {
1717
if (!stat) {
1818
return fs.write(localFile, "");
1919
}
@@ -24,7 +24,7 @@ return view.extend({
2424
});
2525
},
2626
render: function (allowlist) {
27-
if (allowlist[0].size >= 100000) {
27+
if (allowlist[0] && allowlist[0].size >= 100000) {
2828
resetScroll();
2929
ui.addNotification(null, E('p', _('The allowlist is too big, unable to save modifications.')), 'error');
3030
}

applications/luci-app-banip/htdocs/luci-static/resources/view/banip/blocklist.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const resetScroll = () => {
1313
return view.extend({
1414
load: function () {
1515
return L.resolveDefault(fs.stat(localFile), "")
16-
.then(function (stat) {
16+
.then(function (stat) {
1717
if (!stat) {
1818
return fs.write(localFile, "");
1919
}
@@ -24,19 +24,19 @@ return view.extend({
2424
});
2525
},
2626
render: function (blocklist) {
27-
if (blocklist[0].size >= 100000) {
27+
if (blocklist[0] && blocklist[0].size >= 100000) {
2828
resetScroll();
2929
ui.addNotification(null, E('p', _('The blocklist is too big, unable to save modifications.')), 'error');
3030
}
3131
return E('div', { 'class': 'cbi-section cbi-section-descr' }, [
3232
E('p', _('This is the local banIP blocklist that will prevent certain MAC-, IP-addresses or domain names.<br /> \
3333
<em><b>Please note:</b></em> add only exactly one MAC/IPv4/IPv6 address or domain name per line. Ranges in CIDR notation and MAC/IP-bindings are allowed.')),
34-
E('textarea', {
35-
'style': 'width: 100% !important; padding: 5px; font-family: monospace; margin-top: .4em',
36-
'spellcheck': 'false',
37-
'wrap': 'off',
38-
'rows': 25
39-
}, [blocklist[1] != null ? blocklist[1] : ''])
34+
E('textarea', {
35+
'style': 'width: 100% !important; padding: 5px; font-family: monospace; margin-top: .4em',
36+
'spellcheck': 'false',
37+
'wrap': 'off',
38+
'rows': 25
39+
}, [blocklist[1] != null ? blocklist[1] : ''])
4040
]);
4141
},
4242
handleSave: function (ev) {

applications/luci-app-banip/htdocs/luci-static/resources/view/banip/feeds.js

Lines changed: 45 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -119,59 +119,50 @@ function handleEdit(ev) {
119119
return ui.addNotification(null, E('p', _('Invalid input values, unable to save modifications.')), 'error');
120120
}
121121
}
122-
let sumSubElements = [], exportJson;
122+
/*
123+
gather all input data
124+
*/
125+
let sumSubElements = [];
123126
const nodeKeys = document.querySelectorAll('[id^="widget.cbid.json"][id$="name"]');
124-
for (let i = 0; i < nodeKeys.length; i++) {
125-
let subElements = {};
126-
const elements = document.querySelectorAll('[id^="widget.cbid.json.' + nodeKeys[i].id.split('.')[3] + '\."], \
127-
[id^="cbid.json.' + nodeKeys[i].id.split('.')[3] + '\.rule_4"], \
128-
[id^="cbid.json.' + nodeKeys[i].id.split('.')[3] + '\.rule_6"]');
129-
for (const element of elements) {
130-
let key;
131-
const value = element.value || "";
132-
const parts = element.id.split('.');
133-
if (parts.length === 5) {
134-
key = element.id.split('.')[4];
135-
} else if (parts.length === 4) {
136-
key = element.id.split('.')[3];
137-
}
138-
if (!key || value === "") {
139-
continue;
140-
}
141-
switch (key) {
142-
case 'url_4':
143-
subElements.url_4 = value;
144-
break;
145-
case 'rule_4':
146-
subElements.rule_4 = value;
147-
break;
148-
case 'url_6':
149-
subElements.url_6 = value;
150-
break;
151-
case 'rule_6':
152-
subElements.rule_6 = value;
153-
break;
154-
case 'chain':
155-
subElements.chain = value;
156-
break;
157-
case 'descr':
158-
subElements.descr = value;
159-
break;
160-
case 'flag':
161-
subElements.flag = value;
162-
break;
127+
for (const keyNode of nodeKeys) {
128+
const keyValue = keyNode.value?.trim();
129+
if (!keyValue) continue;
130+
const idParts = keyNode.id.split(".");
131+
const ruleId = idParts[3];
132+
if (!ruleId) continue;
133+
const selector =
134+
`[id^="widget.cbid.json.${ruleId}."], ` +
135+
`[id^="cbid.json.${ruleId}.rule"]`;
136+
const elements = document.querySelectorAll(selector);
137+
const sub = {};
138+
for (const el of elements) {
139+
const parts = el.id.split(".");
140+
const key = parts[parts.length - 1];
141+
const value = el.value?.trim();
142+
if (!value) continue;
143+
if (["url_4", "url_6", "rule", "chain", "descr", "flag"].includes(key)) {
144+
sub[key] = value;
163145
}
164146
}
165-
if (nodeKeys[i].value !== "" && subElements.descr !== "") {
166-
sumSubElements.push(nodeKeys[i].value, subElements);
147+
if (sub.descr) {
148+
sumSubElements.push(keyValue, sub);
167149
}
168150
}
169-
if (sumSubElements.length > 0) {
170-
exportJson = JSON.stringify(sumSubElements).replace(/^\[/, '{\n').replace(/\}]$/, '\n\t}\n}\n').replace(/,{"/g, ':{\n\t"').replace(/"},"/g, '"\n\t},\n"').replace(/","/g, '",\n\t"');
151+
/*
152+
construct json object
153+
*/
154+
let exportObj = {};
155+
for (let i = 0; i < sumSubElements.length; i += 2) {
156+
const key = sumSubElements[i];
157+
const value = sumSubElements[i + 1];
158+
exportObj[key] = value;
171159
}
172-
return fs.write('/etc/banip/banip.custom.feeds', exportJson).then(function () {
173-
location.reload();
174-
});
160+
const exportJson = JSON.stringify(exportObj, null, 4);
161+
/*
162+
save to file and reload
163+
*/
164+
return fs.write('/etc/banip/banip.custom.feeds', exportJson)
165+
.then(() => location.reload());
175166
}
176167

177168
return view.extend({
@@ -186,17 +177,16 @@ return view.extend({
186177
},
187178

188179
render: function (data) {
189-
let m, s, o, feed, url_4, url_6, rule_4, rule_6, chain, descr, flag;
180+
let m, s, o, feed, url_4, url_6, rule, chain, descr, flag;
190181

191182
m = new form.JSONMap(data, null, _('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). \
192183
The file is located at \'/etc/banip/banip.custom.feeds\'. \
193184
Then you can edit this file, delete entries, add new ones or make a local backup. To go back to the maintainers version just clear the custom feed file.'));
194185
for (let i = 0; i < Object.keys(m.data.data).length; i++) {
195186
feed = Object.keys(m.data.data)[i];
196187
url_4 = m.data.data[feed].url_4;
197-
rule_4 = m.data.data[feed].rule_4;
198188
url_6 = m.data.data[feed].url_6;
199-
rule_6 = m.data.data[feed].rule_6;
189+
rule = m.data.data[feed].rule;
200190
chain = m.data.data[feed].chain;
201191
descr = m.data.data[feed].descr;
202192
flag = m.data.data[feed].flag;
@@ -229,20 +219,6 @@ return view.extend({
229219
return true;
230220
}
231221

232-
o = s.option(form.Value, 'rule_4', _('Rulev4'));
233-
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>'));
234-
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>'));
235-
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'));
236-
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'));
237-
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>]'));
238-
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>'));
239-
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'));
240-
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'));
241-
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'));
242-
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'));
243-
o.optional = true;
244-
o.rmempty = true;
245-
246222
o = s.option(form.Value, 'url_6', _('URLv6'));
247223
o.validate = function (section_id, value) {
248224
if (!value) {
@@ -254,10 +230,11 @@ return view.extend({
254230
return true;
255231
}
256232

257-
o = s.option(form.Value, 'rule_6', _('Rulev6'));
258-
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>'));
259-
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>'));
260-
o.value('BEGIN{FS=\",\"}/^(([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>, csv'));
233+
o = s.option(form.Value, 'rule', _('Rule'));
234+
o.value('feed 1', _('<IP-Address>'));
235+
o.value('feed 1 ,', _('<IP-Address><CSV-Seperator>'));
236+
o.value('feed 13', _('<IP-Address> <Netmask>'));
237+
o.value('suricata 1', _('<Suricata Syntax>'));
261238
o.optional = true;
262239
o.rmempty = true;
263240

applications/luci-app-banip/htdocs/luci-static/resources/view/banip/logtemplate.js

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,24 @@ function Logview(logtag, name) {
1818
const logEl = document.getElementById('logfile');
1919
if (!logEl) return;
2020

21-
const entries = res?.log ?? [];
22-
if (entries.length > 0) {
23-
const filtered = entries
24-
.filter(entry => !logtag || entry.msg.includes(logtag))
25-
.map(entry => {
26-
const d = new Date(entry.time);
27-
const date = d.toLocaleDateString([], {
28-
year: 'numeric',
29-
month: '2-digit',
30-
day: '2-digit'
31-
});
32-
const time = d.toLocaleTimeString([], {
33-
hour: '2-digit',
34-
minute: '2-digit',
35-
second: '2-digit',
36-
hour12: false
37-
});
38-
return `[${date}-${time}] ${entry.msg}`;
39-
});
21+
const filtered = (res?.log ?? [])
22+
.filter(entry => !logtag || entry.msg.includes(logtag))
23+
.map(entry => {
24+
const d = new Date(entry.time);
25+
const date = d.toLocaleDateString([], {
26+
year: 'numeric',
27+
month: '2-digit',
28+
day: '2-digit'
29+
});
30+
const time = d.toLocaleTimeString([], {
31+
hour: '2-digit',
32+
minute: '2-digit',
33+
second: '2-digit',
34+
hour12: false
35+
});
36+
return `[${date}-${time}] ${entry.msg}`;
37+
});
38+
if (filtered.length > 0) {
4039
logEl.value = filtered.join('\n');
4140
} else {
4241
logEl.value = _('No %s related logs yet!').format(name);

applications/luci-app-banip/htdocs/luci-static/resources/view/banip/overview.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ return view.extend({
372372
o.optional = true;
373373
o.rmempty = true;
374374

375+
o = s.taboption('adv_chain', form.Flag, 'ban_bcp38', _('Enable BCP38'), _('Block packets with spoofed source IP addresses in all supported chains.'));
376+
o.optional = true;
377+
o.rmempty = true;
378+
375379
o = s.taboption('adv_chain', form.ListValue, 'ban_icmplimit', _('ICMP-Threshold'), _('ICMP-Threshold in packets per second to prevent WAN-DoS attacks. To disable this safeguard set it to \'0\'.'));
376380
o.value('0');
377381
o.value('25');
@@ -435,8 +439,7 @@ return view.extend({
435439
o.value('1');
436440
o.value('3');
437441
o.value('5');
438-
o.value('10');
439-
o.default = '5';
442+
o.default = '3';
440443
o.placeholder = _('-- default --');
441444
o.create = true;
442445
o.optional = true;

applications/luci-app-banip/htdocs/luci-static/resources/view/banip/setreport.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ return view.extend({
272272
E('div', { 'class': 'cbi-value-title', 'style': 'margin-top:-5px;width:230px;font-weight:bold;' }, _('blocked invalid tcp packets')),
273273
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'margin-top:-5px;color:#37c;font-weight:bold;' }, content?.[0]?.sum_tcpinvalid || '-')
274274
]),
275+
E('div', { 'class': 'cbi-value' }, [
276+
E('div', { 'class': 'cbi-value-title', 'style': 'margin-top:-5px;width:230px;font-weight:bold;' }, _('blocked bcp38 packets')),
277+
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'margin-top:-5px;color:#37c;font-weight:bold;' }, content?.[0]?.sum_bcp38 || '-')
278+
]),
275279
E('hr'),
276280
E('div', { 'class': 'cbi-value' }, [
277281
E('div', { 'class': 'cbi-value-title', 'style': 'margin-top:-5px;width:230px;font-weight:bold;' }, _('auto-added IPs to allowlist')),

applications/luci-app-banip/root/usr/share/rpcd/acl.d/luci-app-banip.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
"luci-app-banip": {
33
"description": "Grant access to LuCI app banIP",
44
"write": {
5+
"uci": [ "banip" ],
56
"file": {
67
"/etc/banip/*": [ "read", "write" ],
78
"/etc/banip/banip.allowlist": [ "write" ],
89
"/etc/banip/banip.blocklist": [ "write" ],
910
"/etc/banip/banip.custom.feeds": [ "read", "write" ]
10-
},
11-
"uci": [ "banip" ]
11+
}
1212
},
1313
"read": {
1414
"cgi-io": [ "exec" ],

0 commit comments

Comments
 (0)