luci-app-banip: re-launch the banIP LuCI frontend

* rewrite the LuCI frontend to support the latest banIP backend release in master (based on nft)  -  (backend >= 0.8.1-3 required)
* sync translations

Signed-off-by: Dirk Brenken <dev@brenken.org>
This commit is contained in:
Dirk Brenken 2023-03-06 15:29:08 +01:00
parent 79f7120b9f
commit dcc94119ce
No known key found for this signature in database
GPG key ID: 9D71CD547BFAE684
48 changed files with 22011 additions and 22024 deletions

View file

@ -1,10 +1,10 @@
# Copyright 2018-2021 Dirk Brenken (dev@brenken.org)
# Copyright 2018-2023 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the Apache License, Version 2.0
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for banIP
LUCI_DEPENDS:=+banip +luci-lib-jsonc @BROKEN
LUCI_DEPENDS:=+banip +luci-lib-jsonc
LUCI_PKGARCH:=all
PKG_LICENSE:=Apache-2.0

View file

@ -0,0 +1,37 @@
'use strict';
'require view';
'require fs';
'require ui';
return view.extend({
load: function () {
return L.resolveDefault(fs.read_direct('/etc/banip/banip.allowlist'), '');
},
handleSave: function (ev) {
var value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n')) + '\n';
return fs.write('/etc/banip/banip.allowlist', value)
.then(function (rc) {
document.querySelector('textarea').value = value;
ui.addNotification(null, E('p', _('Allowlist modifications have been saved, restart banIP that changes take effect.')), 'info');
}).catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save modifications: %s').format(e.message)));
});
},
render: function (allowlist) {
return E([
E('p', {},
_('This is the local banIP allowlist that will permit certain MAC/IP/CIDR addresses.<br /> \
<em><b>Please note:</b></em> add only exactly one MAC/IPv4/IPv6 address or domain name per line.')),
E('p', {},
E('textarea', {
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
'spellcheck': 'false',
'wrap': 'off',
'rows': 25
}, [allowlist != null ? allowlist : ''])
)
]);
},
handleSaveApply: null,
handleReset: null
});

View file

@ -0,0 +1,41 @@
'use strict';
'require view';
'require poll';
'require fs';
return view.extend({
load: function () {
return Promise.all([
L.resolveDefault(fs.stat('/sbin/logread'), null),
L.resolveDefault(fs.stat('/usr/sbin/logread'), null)
]);
},
render: function (stat) {
var logger = stat[0] ? stat[0].path : stat[1] ? stat[1].path : null;
poll.add(function () {
return L.resolveDefault(fs.exec_direct(logger, ['-e', ' banIP/'])).then(function (res) {
var log = document.getElementById("logfile");
if (res) {
log.value = res.trim();
} else {
log.value = _('No banIP related firewall logs yet!');
}
log.scrollTop = log.scrollHeight;
});
});
return E('div', { class: 'cbi-map' },
E('div', { class: 'cbi-section' }, [
E('div', { class: 'cbi-section-descr' }, _('The syslog output, prefiltered for banIP-related firewall log entries only.')),
E('textarea', {
'id': 'logfile',
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
'readonly': 'readonly',
'wrap': 'off',
'rows': 25
})
]));
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});

View file

@ -1,244 +0,0 @@
'use strict';
'require view';
'require fs';
'require ui';
/*
button handling
*/
function handleAction(ev) {
if (ev.target && ev.target.getAttribute('name') === 'whitelist') {
L.ui.showModal(_('Whitelist IP/CIDR'), [
E('p', _('Add this IP/CIDR to your local whitelist.')),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
E('input', { 'class': 'cbi-input-text', 'style': 'width:300px', 'spellcheck': 'false', 'id': 'whitelist', 'value': ev.target.getAttribute('value') }, [])
])
]),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn cbi-button',
'click': L.hideModal
}, _('Cancel')),
' ',
E('button', {
'class': 'btn cbi-button-action',
'click': ui.createHandlerFn(this, function(ev) {
L.resolveDefault(fs.read_direct('/etc/banip/banip.whitelist'), '')
.then(function(res) {
var ip = document.getElementById('whitelist').value.trim().toLowerCase();
if (ip) {
var whitelist = res + ip + '\n';
fs.write('/etc/banip/banip.whitelist', whitelist);
ui.addNotification(null, E('p', _('Whitelist changes have been saved. Refresh your banIP lists that changes take effect.')), 'info');
}
L.hideModal();
});
})
}, _('Save'))
])
]);
document.getElementById('whitelist').focus();
}
if (ev === 'query') {
L.ui.showModal(_('IPSet Query'), [
E('p', _('Search the active banIP-related IPSets for a specific IP, CIDR or MAC address.')),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
E('label', { 'style': 'padding-top:.5em', 'id': 'run' }, [
E('input', {
'class': 'cbi-input-text',
'placeholder': '192.168.0.1',
'style': 'width:300px',
'spellcheck': 'false',
'id': 'search'
})
])
]),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
'\xa0',
E('h5', _('Result')),
E('textarea', {
'id': 'result',
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
'readonly': 'readonly',
'wrap': 'off',
'rows': 20
})
]),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn cbi-button',
'click': L.hideModal
}, _('Cancel')),
' ',
E('button', {
'class': 'btn cbi-button-action',
'click': ui.createHandlerFn(this, function(ev) {
var ip = document.getElementById('search').value.trim().toLowerCase();
if (ip) {
document.getElementById('run').classList.add("spinning");
document.getElementById('search').value = ip;
document.getElementById('result').textContent = 'The query is running, please wait...';
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['query', ip])).then(function(res) {
var result = document.getElementById('result');
if (res) {
result.textContent = res.trim();
} else {
result.textContent = _('No Query results!');
}
document.getElementById('run').classList.remove("spinning");
document.getElementById('search').value = '';
})
}
document.getElementById('search').focus();
})
}, _('Query'))
])
]);
document.getElementById('search').focus();
}
}
return view.extend({
load: function() {
return L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['report', 'json']),'');
},
render: function(ipsetreport) {
if (!ipsetreport) {
ipsetreport = '{}';
};
var content;
content = JSON.parse(ipsetreport);
var rows_ipsets = [];
var tbl_ipsets = E('table', { 'class': 'table', 'id': 'ipsets' }, [
E('tr', { 'class': 'tr table-titles' }, [
E('th', { 'class': 'th' }, _('Name')),
E('th', { 'class': 'th' }, _('Type')),
E('th', { 'class': 'th' }, _('Count SUM')),
E('th', { 'class': 'th' }, _('Count IP')),
E('th', { 'class': 'th' }, _('Count CIDR')),
E('th', { 'class': 'th' }, _('Count MAC')),
E('th', { 'class': 'th' }, _('Count ACC')),
E('th', { 'class': 'th' }, _('Entry Details')),
E('th', { 'class': 'th' }, '\xa0'),
E('th', { 'class': 'th' }, _('Action'))
])
]);
if (content.ipsets) {
var button, member, urlprefix;
Object.keys(content.ipsets).forEach(function(key) {
rows_ipsets.push([
E('em', key),
E('em', content.ipsets[key].type),
E('em', content.ipsets[key].count),
E('em', content.ipsets[key].count_ip),
E('em', content.ipsets[key].count_cidr),
E('em', content.ipsets[key].count_mac),
E('em', content.ipsets[key].count_acc)
]);
for (var i = 0; i < content.ipsets[key].member_acc.length; i++) {
if (key != 'maclist' && key.substr(0,9) != 'whitelist') {
member = '<a href="https://ipwhois.app/json/' + encodeURIComponent(content.ipsets[key].member_acc[i].member) + '" target="_blank" rel="noreferrer noopener" title="IP/CIDR Lookup" >' + content.ipsets[key].member_acc[i].member + '</a>';
button = E('button', {
'class': 'btn cbi-button cbi-button-apply',
'style': 'word-break: inherit',
'name': 'whitelist',
'value': content.ipsets[key].member_acc[i].member,
'click': handleAction
}, [ _('Whitelist...')]);
} else {
member = content.ipsets[key].member_acc[i].member;
button = '';
}
rows_ipsets.push([
'',
'',
'',
'',
'',
'',
'',
member,
content.ipsets[key].member_acc[i].packets,
button
]);
}
});
}
cbi_update_table(tbl_ipsets, rows_ipsets);
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
E('div', { 'class': 'cbi-section' }, [
E('p', _('This tab shows the last generated IPSet Report, press the \'Refresh\' button to get a current one.')),
E('p', '\xa0'),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Timestamp')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.timestamp || '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of all IPSets')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_set_sum || '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of all entries')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_sum || '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of IP entries')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_ip_sum || '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of CIDR entries')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_cidr_sum || '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of MAC entries')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_mac_sum || '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of accessed entries')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_acc_sum || '-')
]),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn cbi-button cbi-button-apply',
'click': ui.createHandlerFn(this, function() {
return handleAction('query');
})
}, [ _('IPSet Query...') ]),
'\xa0\xa0\xa0',
E('button', {
'class': 'btn cbi-button cbi-button-positive',
'click': ui.createHandlerFn(this, async function() {
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['report', 'gen']),'');
var running = 1;
while (running === 1) {
await new Promise(r => setTimeout(r, 1000));
L.resolveDefault(fs.read_direct('/var/run/banip.pid')).then(function(res) {
if (!res) {
running = 0;
}
})
}
location.reload();
})
}, [ _('Refresh') ])
]),
]),
E('br'),
E('div', { 'class': 'cbi-section' }, [
E('div', { 'class': 'left' }, [
E('h3', _('IPSet details')),
tbl_ipsets
])
])
]);
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});

View file

@ -1,37 +0,0 @@
'use strict';
'require view';
'require fs';
'require ui';
return view.extend({
load: function() {
return L.resolveDefault(fs.read_direct('/etc/banip/banip.maclist'), '');
},
handleSave: function(ev) {
var value = ((document.querySelector('textarea').value || '').trim().toUpperCase().replace(/\r\n/g, '\n')) + '\n';
return fs.write('/etc/banip/banip.maclist', value)
.then(function(rc) {
document.querySelector('textarea').value = value;
ui.addNotification(null, E('p', _('Maclist changes have been saved. Refresh your banIP lists that changes take effect.')), 'info');
}).catch(function(e) {
ui.addNotification(null, E('p', _('Unable to save changes: %s').format(e.message)));
});
},
render: function(blacklist) {
return E([
E('p', {},
_('This is the local banIP maclist to always-allow certain MAC addresses.<br /> \
<em><b>Please note:</b></em> add only one MAC address per line. Comments introduced with \'#\' are allowed - domains, wildcards and regex are not.')),
E('p', {},
E('textarea', {
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
'spellcheck': 'false',
'wrap': 'off',
'rows': 25
}, [ blacklist != null ? blacklist : '' ])
)
]);
},
handleSaveApply: null,
handleReset: null
});

View file

@ -11,123 +11,13 @@
button handling
*/
function handleAction(ev) {
if (ev === 'timer') {
L.ui.showModal(_('Refresh Timer'), [
E('p', _('To keep your banIP lists up-to-date, you should set up an automatic update job for these lists.')),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
E('h5', _('Existing job(s)')),
E('textarea', {
'id': 'cronView',
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
'readonly': 'readonly',
'wrap': 'off',
'rows': 5
})
]),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
E('label', { 'class': 'cbi-input-select', 'style': 'padding-top:.5em' }, [
E('h5', _('Set a new banIP job')),
E('select', { 'class': 'cbi-input-select', 'id': 'timerA' }, [
E('option', { 'value': 'start' }, 'Start'),
E('option', { 'value': 'reload' }, 'Reload'),
E('option', { 'value': 'restart' }, 'Restart'),
E('option', { 'value': 'refresh' }, 'Refresh'),
E('option', { 'value': 'suspend' }, 'Suspend'),
E('option', { 'value': 'resume' }, 'Resume'),
E('option', { 'value': 'report gen' }, 'Report'),
E('option', { 'value': 'report mail' }, 'Report &amp; Mail')
]),
'\xa0\xa0\xa0',
_('banIP action')
]),
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
E('input', { 'class': 'cbi-input-text', 'id': 'timerH', 'maxlength': '2' }, [
]),
'\xa0\xa0\xa0',
_('The hours portition (req., range: 0-23)')
]),
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
E('input', { 'class': 'cbi-input-text', 'id': 'timerM', 'maxlength': '2' }),
'\xa0\xa0\xa0',
_('The minutes portion (opt., range: 0-59)')
]),
E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
E('input', { 'class': 'cbi-input-text', 'id': 'timerD', 'maxlength': '13' }),
'\xa0\xa0\xa0',
_('The day of the week (opt., values: 1-7 possibly sep. by , or -)')
])
]),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
E('label', { 'class': 'cbi-input-select', 'style': 'padding-top:.5em' }, [
E('h5', _('Remove an existing job')),
E('input', { 'class': 'cbi-input-text', 'id': 'lineno', 'maxlength': '2' }, [
]),
'\xa0\xa0\xa0',
_('Line number to remove')
])
]),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn cbi-button',
'click': L.hideModal
}, _('Cancel')),
' ',
E('button', {
'class': 'btn cbi-button-action',
'click': ui.createHandlerFn(this, function(ev) {
var lineno = document.getElementById('lineno').value;
var action = document.getElementById('timerA').value;
var hours = document.getElementById('timerH').value;
var minutes = document.getElementById('timerM').value || '0';
var days = document.getElementById('timerD').value || '*';
if (hours) {
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['timer', 'add', action, hours, minutes, days]))
.then(function(res) {
if (res) {
ui.addNotification(null, E('p', _('The Refresh Timer could not been updated.')), 'error');
} else {
ui.addNotification(null, E('p', _('The Refresh Timer has been updated.')), 'info');
}
});
} else if (lineno) {
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['timer', 'remove', lineno]))
.then(function(res) {
if (res) {
ui.addNotification(null, E('p', _('The Refresh Timer could not been updated.')), 'error');
} else {
ui.addNotification(null, E('p', _('The Refresh Timer has been updated.')), 'info');
}
});
} else {
document.getElementById('timerH').focus();
return
}
L.hideModal();
})
}, _('Save'))
])
]);
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['timer', 'list']))
.then(function(res) {
document.getElementById('cronView').value = res.trim();
});
document.getElementById('timerH').focus();
return
}
if (document.getElementById('status') && document.getElementById('status').textContent.substr(0,6) === 'paused') {
ev = 'resume';
}
fs.exec_direct('/etc/init.d/banip', [ev])
}
return view.extend({
load: function () {
return Promise.all([
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['list']), {}),
L.resolveDefault(fs.exec_direct('/usr/sbin/iptables', ['-L']), null),
L.resolveDefault(fs.exec_direct('/usr/sbin/ip6tables', ['-L']), null),
L.resolveDefault(fs.read_direct('/etc/banip/banip.feeds'), ''),
L.resolveDefault(fs.read_direct('/etc/banip/banip.countries'), ''),
uci.load('banip')
]);
@ -136,36 +26,30 @@ return view.extend({
render: function (result) {
var m, s, o;
m = new form.Map('banip', 'banIP', _('Configuration of the banIP package to block ip adresses/subnets via IPSet. \
m = new form.Map('banip', 'banIP', _('Configuration of the banIP package to ban incoming and outgoing ip addresses/subnets via sets in nftables. \
For further information <a href="https://github.com/openwrt/packages/blob/master/net/banip/files/README.md" target="_blank" rel="noreferrer noopener" >check the online documentation</a>'));
/*
poll runtime information
*/
var rt_res, inf_stat, inf_ipsets, inf_sources, inf_srcarr, inf_devices, inf_devarr, inf_ifaces, inf_ifarr, inf_logterms, inf_logtarr
var inf_subnets, inf_subnarr, inf_misc, inf_flags, inf_run
var rt_res, inf_stat, inf_version, inf_elements, inf_feeds, inf_feedarray, inf_devices, inf_devicearray, inf_interfaces, inf_interfacearray
var inf_subnets, inf_subnetarray, inf_infos, inf_flags, inf_run, inf_system
pollData: poll.add(function () {
return L.resolveDefault(fs.read_direct('/tmp/ban_runtime.json'), 'null').then(function(res) {
return L.resolveDefault(fs.read_direct('/var/run/banip_runtime.json'), 'null').then(function (res) {
rt_res = JSON.parse(res);
inf_stat = document.getElementById('status');
if (inf_stat && rt_res) {
inf_stat.textContent = (rt_res.status || '-') + ' / ' + (rt_res.version || '-');
if (rt_res.status === "running") {
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['status', 'update'])).then(function (update_res) {
inf_stat.textContent = (rt_res.status + ' (' + update_res.trim() + ')' || '-');
});
if (rt_res.status === "processing") {
if (!inf_stat.classList.contains("spinning")) {
inf_stat.classList.add("spinning");
}
} else {
if (inf_stat.classList.contains("spinning")) {
inf_stat.classList.remove("spinning");
if (document.getElementById('btn_suspend')) {
if (inf_stat.textContent.substr(0,6) === 'paused') {
document.querySelector('#btn_suspend').textContent = 'Resume';
}
if (document.getElementById('status').textContent.substr(0,7) === 'enabled') {
document.querySelector('#btn_suspend').textContent = 'Suspend';
}
}
}
}
} else if (inf_stat) {
@ -174,73 +58,65 @@ return view.extend({
inf_stat.classList.remove("spinning");
}
}
inf_ipsets = document.getElementById('ipsets');
if (inf_ipsets && rt_res) {
inf_ipsets.textContent = rt_res.ipset_info || '-';
inf_version = document.getElementById('version');
if (inf_version && rt_res) {
inf_version.textContent = rt_res.version || '-';
}
inf_sources = document.getElementById('sources');
inf_srcarr = [];
if (inf_sources && rt_res) {
for (var i = 0; i < rt_res.active_sources.length; i++) {
if (i < rt_res.active_sources.length-1) {
inf_srcarr += rt_res.active_sources[i].source + ', ';
inf_elements = document.getElementById('elements');
if (inf_elements && rt_res) {
inf_elements.textContent = rt_res.element_count || '-';
}
inf_feeds = document.getElementById('feeds');
inf_feedarray = [];
if (inf_feeds && rt_res) {
for (var i = 0; i < rt_res.active_feeds.length; i++) {
if (i < rt_res.active_feeds.length - 1) {
inf_feedarray += rt_res.active_feeds[i].feed + ', ';
} else {
inf_srcarr += rt_res.active_sources[i].source
inf_feedarray += rt_res.active_feeds[i].feed
}
}
inf_sources.textContent = inf_srcarr || '-';
inf_feeds.textContent = inf_feedarray || '-';
}
inf_devices = document.getElementById('devices');
inf_devarr = [];
inf_devicearray = [];
if (inf_devices && rt_res) {
for (var i = 0; i < rt_res.active_devs.length; i++) {
if (i < rt_res.active_devs.length-1) {
inf_devarr += rt_res.active_devs[i].dev + ', ';
for (var i = 0; i < rt_res.active_devices.length; i++) {
if (i < rt_res.active_devices.length - 1) {
inf_devicearray += rt_res.active_devices[i].device + ', ';
} else {
inf_devarr += rt_res.active_devs[i].dev
inf_devicearray += rt_res.active_devices[i].device
}
}
inf_devices.textContent = inf_devarr || '-';
inf_devices.textContent = inf_devicearray || '-';
}
inf_ifaces = document.getElementById('ifaces');
inf_ifarr = [];
if (inf_ifaces && rt_res) {
for (var i = 0; i < rt_res.active_ifaces.length; i++) {
if (i < rt_res.active_ifaces.length-1) {
inf_ifarr += rt_res.active_ifaces[i].iface + ', ';
inf_interfaces = document.getElementById('interfaces');
inf_interfacearray = [];
if (inf_interfaces && rt_res) {
for (var i = 0; i < rt_res.active_interfaces.length; i++) {
if (i < rt_res.active_interfaces.length - 1) {
inf_interfacearray += rt_res.active_interfaces[i].interface + ', ';
} else {
inf_ifarr += rt_res.active_ifaces[i].iface
inf_interfacearray += rt_res.active_interfaces[i].interface
}
}
inf_ifaces.textContent = inf_ifarr || '-';
}
inf_logterms = document.getElementById('logterms');
inf_logtarr = [];
if (inf_logterms && rt_res) {
for (var i = 0; i < rt_res.active_logterms.length; i++) {
if (i < rt_res.active_logterms.length-1) {
inf_logtarr += rt_res.active_logterms[i].term + ', ';
} else {
inf_logtarr += rt_res.active_logterms[i].term
}
}
inf_logterms.textContent = inf_logtarr || '-';
inf_interfaces.textContent = inf_interfacearray || '-';
}
inf_subnets = document.getElementById('subnets');
inf_subnarr = [];
inf_subnetarray = [];
if (inf_subnets && rt_res) {
for (var i = 0; i < rt_res.active_subnets.length; i++) {
if (i < rt_res.active_subnets.length - 1) {
inf_subnarr += rt_res.active_subnets[i].subnet + ', ';
inf_subnetarray += rt_res.active_subnets[i].subnet + ', ';
} else {
inf_subnarr += rt_res.active_subnets[i].subnet
inf_subnetarray += rt_res.active_subnets[i].subnet
}
}
inf_subnets.textContent = inf_subnarr || '-';
inf_subnets.textContent = inf_subnetarray || '-';
}
inf_misc = document.getElementById('infos');
if (inf_misc && rt_res) {
inf_misc.textContent = rt_res.run_infos || '-';
inf_infos = document.getElementById('infos');
if (inf_infos && rt_res) {
inf_infos.textContent = rt_res.run_info || '-';
}
inf_flags = document.getElementById('flags');
if (inf_flags && rt_res) {
@ -250,6 +126,10 @@ return view.extend({
if (inf_run && rt_res) {
inf_run.textContent = rt_res.last_run || '-';
}
inf_system = document.getElementById('system');
if (inf_system && rt_res) {
inf_system.textContent = rt_res.system_info || '-';
}
});
}, 1);
@ -261,16 +141,20 @@ return view.extend({
return E('div', { 'class': 'cbi-section' }, [
E('h3', _('Information')),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Status / Version')),
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Status')),
E('div', { 'class': 'cbi-value-field spinning', 'id': 'status', 'style': 'color:#37c' }, '\xa0')
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('IPSet Information')),
E('div', { 'class': 'cbi-value-field', 'id': 'ipsets', 'style': 'color:#37c' },'-')
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Version')),
E('div', { 'class': 'cbi-value-field', 'id': 'version', 'style': 'color:#37c' }, '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Active Sources')),
E('div', { 'class': 'cbi-value-field', 'id': 'sources', 'style': 'color:#37c' },'-')
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Element Count')),
E('div', { 'class': 'cbi-value-field', 'id': 'elements', 'style': 'color:#37c' }, '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Active Feeds')),
E('div', { 'class': 'cbi-value-field', 'id': 'feeds', 'style': 'color:#37c' }, '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Active Devices')),
@ -278,11 +162,7 @@ return view.extend({
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Active Interfaces')),
E('div', { 'class': 'cbi-value-field', 'id': 'ifaces', 'style': 'color:#37c' },'-')
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Active Logterms')),
E('div', { 'class': 'cbi-value-field', 'id': 'logterms', 'style': 'color:#37c' },'-')
E('div', { 'class': 'cbi-value-field', 'id': 'interfaces', 'style': 'color:#37c' }, '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Active Subnets')),
@ -300,31 +180,27 @@ return view.extend({
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Last Run')),
E('div', { 'class': 'cbi-value-field', 'id': 'run', 'style': 'color:#37c' }, '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('System Information')),
E('div', { 'class': 'cbi-value-field', 'id': 'system', 'style': 'color:#37c' }, '-')
]),
E('div', { class: 'right' }, [
E('button', {
'class': 'btn cbi-button cbi-button-apply',
'class': 'btn cbi-button cbi-button-negative',
'click': ui.createHandlerFn(this, function () {
return handleAction('timer');
return handleAction('stop');
})
}, [ _('Refresh Timer...') ]),
'\xa0\xa0\xa0',
E('button', {
'class': 'btn cbi-button cbi-button-apply',
'id': 'btn_suspend',
'click': ui.createHandlerFn(this, function() {
return handleAction('suspend');
})
}, [ _('Suspend') ]),
}, [_('Stop')]),
'\xa0\xa0\xa0',
E('button', {
'class': 'btn cbi-button cbi-button-positive',
'click': ui.createHandlerFn(this, function () {
return handleAction('refresh');
return handleAction('reload');
})
}, [ _('Refresh') ]),
}, [_('Reload')]),
'\xa0\xa0\xa0',
E('button', {
'class': 'btn cbi-button cbi-button-negative',
'class': 'btn cbi-button cbi-button-positive',
'click': ui.createHandlerFn(this, function () {
return handleAction('restart');
})
@ -340,11 +216,11 @@ return view.extend({
s = m.section(form.NamedSection, 'global', 'banip', _('Settings'));
s.addremove = false;
s.tab('general', _('General Settings'));
s.tab('additional', _('Additional Settings'));
s.tab('adv_chain', _('Advanced Chain Settings'));
s.tab('adv_log', _('Advanced Log Settings'));
s.tab('adv_email', _('Advanced E-Mail Settings'));
s.tab('sources', _('Blocklist Sources'));
s.tab('advanced', _('Advanced Settings'));
s.tab('adv_chain', _('Chain/Set Settings'));
s.tab('adv_log', _('Log Settings'));
s.tab('adv_email', _('E-Mail Settings'));
s.tab('feeds', _('Blocklist Feeds'));
/*
general settings tab
@ -352,63 +228,94 @@ return view.extend({
o = s.taboption('general', form.Flag, 'ban_enabled', _('Enabled'), _('Enable the banIP service.'));
o.rmempty = false;
o = s.taboption('general', widgets.NetworkSelect, 'ban_trigger', _('Startup Trigger Interface'), _('List of available network interfaces to trigger the banIP start.'));
o.unspecified = true;
o.nocreate = true;
o.rmempty = true;
o = s.taboption('general', form.Flag, 'ban_autodetect', _('Auto Detection'), _('Detect relevant network interfaces, devices, subnets and protocols automatically.'));
o = s.taboption('general', form.Flag, 'ban_debug', _('Verbose Debug Logging'), _('Enable verbose debug logging in case of processing errors.'));
o.rmempty = false;
o = s.taboption('general', widgets.NetworkSelect, 'ban_ifaces', _('Network Interfaces'), _('Select the relevant network interfaces manually.'));
o = s.taboption('general', form.Flag, 'ban_autodetect', _('Auto Detection'), _('Detect relevant network devices, interfaces, subnets, protocols and utilities automatically.'));
o.rmempty = false;
o = s.taboption('general', form.Flag, 'ban_protov4', _('IPv4 Support'), _('Enables IPv4 support.'));
o.depends('ban_autodetect', '0');
o.optional = true;
o.retain = true;
o = s.taboption('general', form.Flag, 'ban_protov6', _('IPv6 Support'), _('Enables IPv6 support.'));
o.depends('ban_autodetect', '0');
o.optional = true;
o.retain = true;
o = s.taboption('general', widgets.DeviceSelect, 'ban_dev', _('Network Devices'), _('Select the WAN network device(s).'));
o.depends('ban_autodetect', '0');
o.unspecified = true;
o.multiple = true;
o.nocreate = true;
o.optional = true;
o.rmempty = false;
o.retain = true;
o = s.taboption('general', form.Flag, 'ban_proto4_enabled', _('IPv4 Support'), _('Enables IPv4 support in banIP.'));
o = s.taboption('general', widgets.NetworkSelect, 'ban_ifv4', _('Network Interfaces'), _('Select the logical WAN IPv4 network interface(s).'));
o.depends('ban_autodetect', '0');
o.unspecified = true;
o.multiple = true;
o.nocreate = true;
o.optional = true;
o.retain = true;
o = s.taboption('general', widgets.NetworkSelect, 'ban_ifv6', _('Network Interfaces'), _('Select the logical WAN IPv6 network interface(s).'));
o.depends('ban_autodetect', '0');
o.unspecified = true;
o.multiple = true;
o.nocreate = true;
o.optional = true;
o.retain = true;
o = s.taboption('general', form.ListValue, 'ban_fetchcmd', _('Download Utility'), _('Select one of the pre-configured download utilities.'));
o.depends('ban_autodetect', '0');
o.value('uclient-fetch');
o.value('wget');
o.value('curl');
o.value('aria2c');
o.optional = true;
o.retain = true;
o = s.taboption('general', form.Value, 'ban_fetchparm', _('Download Parameters'), _('Override the pre-configured download options for the selected download utility.'))
o.depends('ban_autodetect', '0');
o.optional = true;
o.rmempty = false;
o.retain = true;
o = s.taboption('general', form.Flag, 'ban_proto6_enabled', _('IPv6 Support'), _('Enables IPv6 support in banIP.'));
o.depends('ban_autodetect', '0');
o.optional = true;
o.rmempty = false;
o = s.taboption('general', form.Flag, 'ban_monitor_enabled', _('Log Monitor'), _('Starts a small log monitor in the background to block suspicious SSH/LuCI login attempts.'));
o.rmempty = false;
o = s.taboption('general', form.Flag, 'ban_logsrc_enabled', _('Enable SRC logging'), _('Log suspicious incoming packets - usually dropped.'));
o.rmempty = false;
o = s.taboption('general', form.Flag, 'ban_logdst_enabled', _('Enable DST logging'), _('Log suspicious outgoing packets - usually rejected. \
Logging such packets may cause an increase in latency due to it requiring additional system resources.'));
o.rmempty = false;
o = s.taboption('general', form.Flag, 'ban_whitelistonly', _('Whitelist Only'), _('Restrict the internet access from/to a small number of secure websites/IPs \
and block access from/to the rest of the internet.'));
o = s.taboption('general', widgets.NetworkSelect, 'ban_trigger', _('Startup Trigger Interface'), _('List of available network interfaces to trigger the banIP start.'));
o.unspecified = true;
o.multiple = true;
o.nocreate = true;
o.rmempty = true;
o = s.taboption('general', form.Flag, 'ban_mail_enabled', _('E-Mail Notification'), _('Send banIP related notification e-mails. \
This needs the installation and setup of the additional \'msmtp\' package.'));
o = s.taboption('general', form.Value, 'ban_triggerdelay', _('Trigger Delay'), _('Additional trigger delay in seconds before banIP processing actually starts.'));
o.placeholder = '10';
o.datatype = 'range(1,300)';
o.rmempty = true;
o = s.taboption('general', form.Flag, 'ban_deduplicate', _('Deduplicate IPs'), _('Deduplicate IP addresses across all active sets and and tidy up the local blocklist.'));
o.default = 1
o.rmempty = false;
o = s.taboption('general', form.Value, 'ban_mailreceiver', _('E-Mail Receiver Address'), _('Receiver address for banIP notification e-mails.'));
o.depends('ban_mail_enabled', '1');
o.placeholder = 'name@example.com';
o.rmempty = true;
o = s.taboption('general', form.Flag, 'ban_loginput', _('Log WAN-Input'), _('Log suspicious incoming WAN packets (dropped).'));
o.default = 1
o.rmempty = false;
o = s.taboption('general', form.Flag, 'ban_logforwardwan', _('Log WAN-Forward'), _('Log suspicious forwarded WAN packets (dropped).'));
o.default = 1
o.rmempty = false;
o = s.taboption('general', form.Flag, 'ban_logforwardlan', _('Log LAN-Forward'), _('Log suspicious forwarded LAN packets (rejected).'));
o.rmempty = false;
/*
additional settings tab
*/
o = s.taboption('additional', form.Flag, 'ban_debug', _('Verbose Debug Logging'), _('Enable verbose debug logging in case of any processing errors.'));
o.rmempty = false;
o = s.taboption('advanced', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>Changes on this tab needs a banIP service restart to take effect.</b></em>';
o = s.taboption('additional', form.ListValue, 'ban_nice', _('Service Priority'), _('The selected priority will be used for banIP background processing. \
This change requires a full banIP service restart to take effect.'));
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'));
o.value('-10', _('High Priority'));
o.value('0', _('Normal Priority (default)'));
@ -417,253 +324,98 @@ return view.extend({
o.optional = true;
o.rmempty = true;
o = s.taboption('additional', form.Value, 'ban_triggerdelay', _('Trigger Delay'), _('Additional trigger delay in seconds before banIP processing begins.'));
o.placeholder = '5';
o.datatype = 'range(1,120)';
o = s.taboption('advanced', form.ListValue, 'ban_filelimit', _('Max Open Files'), _('Increase the maximal number of open files, e.g. to handle the amount of temporary split files while loading the sets.'));
o.value('512', _('512'));
o.value('1024', _('1024 (default)'));
o.value('2048', _('2048'));
o.value('4096', _('4096'));
o.optional = true;
o.rmempty = true;
o = s.taboption('additional', form.ListValue, 'ban_maxqueue', _('Download Queue'), _('Size of the download queue for download processing in parallel.'));
o = s.taboption('advanced', form.ListValue, 'ban_cores', _('CPU Cores'), _('Limit the cpu cores used by banIP to save RAM.'));
o.value('1');
o.value('2');
o.value('4');
o.value('8');
o.value('16');
o.value('32');
o.optional = true;
o.rmempty = false;
o.rmempty = true;
o = s.taboption('additional', form.Value, 'ban_tmpbase', _('Base Temp Directory'), _('Base Temp Directory used for all banIP related runtime operations.'));
o = s.taboption('advanced', form.ListValue, 'ban_splitsize', _('Set Split Size'), _('Split external set loading after every n members to save RAM.'));
o.value('256');
o.value('512');
o.value('1024');
o.value('2048');
o.value('4096');
o.optional = true;
o.rmempty = true;
o = s.taboption('advanced', form.Value, 'ban_basedir', _('Base Directory'), _('Base working directory while banIP processing.'));
o.placeholder = '/tmp';
o.rmempty = true;
o = s.taboption('additional', form.Value, 'ban_backupdir', _('Backup Directory'), _('Target directory for compressed source list backups.'));
o.placeholder = '/tmp/banIP-Backup';
o = s.taboption('advanced', form.Value, 'ban_backupdir', _('Backup Directory'), _('Target directory for compressed source list backups.'));
o.placeholder = '/tmp/banIP-backup';
o.rmempty = true;
o = s.taboption('additional', form.Value, 'ban_reportdir', _('Report Directory'), _('Target directory for IPSet related report files.'));
o.placeholder = '/tmp/banIP-Report';
o = s.taboption('advanced', form.Value, 'ban_reportdir', _('Report Directory'), _('Target directory for IPSet related report files.'));
o.placeholder = '/tmp/banIP-report';
o.rmempty = true;
o = s.taboption('additional', form.ListValue, 'ban_fetchutil', _('Download Utility'), _('List of supported and fully pre-configured download utilities.'));
o.value('uclient-fetch');
o.value('wget');
o.value('curl');
o.value('aria2c');
o.optional = true;
o.rmempty = true;
o = s.taboption('additional', form.Flag, 'ban_fetchinsecure', _('Download Insecure'), _('Don\'t check SSL server certificates during download.'));
o.default = 0
o.rmempty = true;
o = s.taboption('additional', form.Value, 'ban_fetchparm', _('Download Parameters'), _('Manually override the pre-configured download options for the selected download utility.'))
o.optional = true;
o = s.taboption('advanced', form.Flag, 'ban_fetchinsecure', _('Download Insecure'), _('Don\'t check SSL server certificates during download.'));
o.rmempty = true;
/*
advanced chain settings tab
advanced chain/set settings tab
*/
o = s.taboption('adv_chain', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>Changes on this tab needs a full banIP service restart to take effect.</b></em>';
o.default = '<em><b>Changes on this tab needs a banIP service restart to take effect.</b></em>';
o = s.taboption('adv_chain', form.ListValue, 'ban_global_settype', _('Global IPSet Type'), _('Set the global IPset type default, to block incoming (SRC) and/or outgoing (DST) packets.'));
o.value('src+dst');
o.value('src');
o.value('dst');
o.rmempty = false;
o = s.taboption('adv_chain', form.ListValue, 'ban_target_src', _('SRC Target'), _('Set the firewall target for all SRC related rules.'));
o.value('DROP');
o.value('REJECT');
o.rmempty = false;
o = s.taboption('adv_chain', form.ListValue, 'ban_target_dst', _('DST Target'), _('Set the firewall target for all DST related rules.'));
o.value('REJECT');
o.value('DROP');
o.rmempty = false;
o = s.taboption('adv_chain', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>Individual IPSet Settings</b></em>';
o = s.taboption('adv_chain', form.ListValue, 'ban_maclist_timeout', _('Maclist Timeout'), _('Set the maclist IPSet timeout.'));
o.value('1800', _('30 minutes'));
o.value('3600', _('1 hour'));
o.value('21600', _('6 hours'));
o.value('43200', _('12 hours'));
o.value('86400', _('24 hours'));
o = s.taboption('adv_chain', form.ListValue, 'ban_nftpriority', _('Chain Priority'), _('Set the nft chain priority within the banIP table. Please note: lower values means higher priority.'));
o.value('0', _('0'));
o.value('-100', _('-100'));
o.value('-200', _('-200 (default)'));
o.value('-300', _('-300'));
o.value('-400', _('-400'));
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_chain', form.ListValue, 'ban_whitelist_timeout', _('Whitelist Timeout'), _('Set the whitelist IPSet timeout.'));
o.value('1800', _('30 minutes'));
o.value('3600', _('1 hour'));
o.value('21600', _('6 hours'));
o.value('43200', _('12 hours'));
o.value('86400', _('24 hours'));
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_chain', form.ListValue, 'ban_blacklist_timeout', _('Blacklist Timeout'), _('Set the blacklist IPSet timeout.'));
o.value('1800', _('30 minutes'));
o.value('3600', _('1 hour'));
o.value('21600', _('6 hours'));
o.value('43200', _('12 hours'));
o.value('86400', _('24 hours'));
o.optional = true;
o.rmempty = true;
var info, source, sources = [];
if (result[0]) {
sources = result[0].trim().split('\n');
}
var feed, feeds;
feeds = JSON.parse(result[0]);
o = s.taboption('adv_chain', form.MultiValue, 'ban_settype_src', _('SRC IPSet Type'), _('Set individual SRC type per IPset to block only incoming packets.'));
o.value('whitelist');
o.value('blacklist');
for (var i = 0; i < sources.length; i++) {
if (sources[i].match(/^\s+\+/)) {
source = sources[i].match(/^\s+\+\s(\w+)\s/)[1].trim();
o.value(source);
}
o = s.taboption('adv_chain', form.MultiValue, 'ban_blockinput', _('WAN-Input Chain'), _('Limit certain feeds to the WAN-Input chain.'));
for (var 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_chain', form.MultiValue, 'ban_settype_dst', _('DST IPSet Type'), _('Set individual DST type per IPset to block only outgoing packets.'));
o.value('whitelist');
o.value('blacklist');
for (var i = 0; i < sources.length; i++) {
if (sources[i].match(/^\s+\+/)) {
source = sources[i].match(/^\s+\+\s(\w+)\s/)[1].trim();
o.value(source);
}
o = s.taboption('adv_chain', form.MultiValue, 'ban_blockforwardwan', _('WAN-Forward Chain'), _('Limit certain feeds to the WAN-Forward chain.'));
for (var 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_chain', form.MultiValue, 'ban_settype_all', _('SRC+DST IPSet Type'), _('Set individual SRC+DST type per IPset to block incoming and outgoing packets.'));
o.value('whitelist');
o.value('blacklist');
for (var i = 0; i < sources.length; i++) {
if (sources[i].match(/^\s+\+/)) {
source = sources[i].match(/^\s+\+\s(\w+)\s/)[1].trim();
o.value(source);
}
o = s.taboption('adv_chain', form.MultiValue, 'ban_blockforwardlan', _('LAN-Forward Chain'), _('Limit certain feeds to the LAN-Forward chain.'));
for (var 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_chain', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>IPv4 Chains</b></em>';
/*
prepare iptables data
*/
var chain, result_v4=[], result_v6=[];
if (result[1]) {
result_v4 = result[1].trim().split('\n');
} else if (result[2]) {
result_v4 = result[2].trim().split('\n');
}
if (result[2]) {
result_v6 = result[2].trim().split('\n');
} else if (result[1]) {
result_v6 = result[1].trim().split('\n');
}
o = s.taboption('adv_chain', form.DynamicList, 'ban_lan_inputchains_4', _('LAN Input'), _('Assign one or more relevant firewall chains to banIP. The default chain used by banIP is \'input_lan_rule\'.'));
for (var i = 0; i < result_v4.length; i++) {
if (result_v4[i].match(/^Chain input[\w_]+\s+/)) {
chain = result_v4[i].match(/\s+(input[\w_]+)\s+/)[1].trim();
o.value(chain);
}
}
o.datatype = 'uciname';
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_chain', form.DynamicList, 'ban_lan_forwardchains_4', _('LAN Forward'), _('Assign one or more relevant firewall chains to banIP. The default chain used by banIP is \'forwarding_lan_rule\'.'));
for (var i = 0; i < result_v4.length; i++) {
if (result_v4[i].match(/^Chain forwarding[\w_]+\s+/)) {
chain = result_v4[i].match(/\s+(forwarding[\w_]+)\s+/)[1].trim();
o.value(chain);
}
}
o.datatype = 'uciname';
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_chain', form.DynamicList, 'ban_wan_inputchains_4', _('WAN Input'), _('Assign one or more relevant firewall chains to banIP. The default chain used by banIP is \'input_wan_rule\'.'));
for (var i = 0; i < result_v4.length; i++) {
if (result_v4[i].match(/^Chain input[\w_]+\s+/)) {
chain = result_v4[i].match(/\s+(input[\w_]+)\s+/)[1].trim();
o.value(chain);
}
}
o.datatype = 'uciname';
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_chain', form.DynamicList, 'ban_wan_forwardchains_4', _('WAN Forward'), _('Assign one or more relevant firewall chains to banIP. The default chain used by banIP is \'forwarding_wan_rule\'.'));
for (var i = 0; i < result_v4.length; i++) {
if (result_v4[i].match(/^Chain forwarding[\w_]+\s+/)) {
chain = result_v4[i].match(/\s+(forwarding[\w_]+)\s+/)[1].trim();
o.value(chain);
}
}
o.datatype = 'uciname';
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_chain', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>IPv6 Chains</b></em>';
o = s.taboption('adv_chain', form.DynamicList, 'ban_lan_inputchains_6', _('LAN Input'), _('Assign one or more relevant firewall chains to banIP. The default chain used by banIP is \'input_lan_rule\'.'));
for (var i = 0; i < result_v6.length; i++) {
if (result_v6[i].match(/^Chain input[\w_]+\s+/)) {
chain = result_v6[i].match(/\s+(input[\w_]+)\s+/)[1].trim();
o.value(chain);
}
}
o.datatype = 'uciname';
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_chain', form.DynamicList, 'ban_lan_forwardchains_6', _('LAN Forward'), _('Assign one or more relevant firewall chains to banIP. The default chain used by banIP is \'forwarding_lan_rule\'.'));
for (var i = 0; i < result_v6.length; i++) {
if (result_v6[i].match(/^Chain forwarding[\w_]+\s+/)) {
chain = result_v6[i].match(/\s+(forwarding[\w_]+)\s+/)[1].trim();
o.value(chain);
}
}
o.datatype = 'uciname';
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_chain', form.DynamicList, 'ban_wan_inputchains_6', _('WAN Input'), _('Assign one or more relevant firewall chains to banIP. The default chain used by banIP is \'input_wan_rule\'.'));
for (var i = 0; i < result_v6.length; i++) {
if (result_v6[i].match(/^Chain input[\w_]+\s+/)) {
chain = result_v6[i].match(/\s+(input[\w_]+)\s+/)[1].trim();
o.value(chain);
}
}
o.datatype = 'uciname';
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_chain', form.DynamicList, 'ban_wan_forwardchains_6', _('WAN Forward'), _('Assign one or more relevant firewall chains to banIP. The default chain used by banIP is \'forwarding_wan_rule\'.'));
for (var i = 0; i < result_v6.length; i++) {
if (result_v6[i].match(/^Chain forwarding[\w_]+\s+/)) {
chain = result_v6[i].match(/\s+(forwarding[\w_]+)\s+/)[1].trim();
o.value(chain);
}
}
o.datatype = 'uciname';
o = s.taboption('adv_chain', form.ListValue, 'ban_nftexpiry', _('Blocklist Expiry'), _('Expiry time for auto added blocklist set members.'));
o.value('10s');
o.value('1m');
o.value('5m');
o.value('1h');
o.value('2h');
o.optional = true;
o.rmempty = true;
@ -672,57 +424,37 @@ return view.extend({
*/
o = s.taboption('adv_log', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>Changes on this tab needs a full banIP service restart to take effect.</b></em>';
o.default = '<em><b>Changes on this tab needs a banIP service restart to take effect.</b></em>';
o = s.taboption('adv_log', form.ListValue, 'ban_loglimit', _('Log Limit'), _('Parse only the last stated number of log entries for suspicious events.'));
o.value('50');
o.value('100');
o.value('250');
o.value('500');
o.rmempty = false;
o = s.taboption('adv_log', form.MultiValue, 'ban_logterms', _('Log Terms'), _('Limit the log monitor to certain log terms.'));
o.value('dropbear');
o.value('sshd');
o.value('luci');
o.value('nginx');
o.value('50', _('50'));
o.value('100', _('100 (default)'));
o.value('250', _('250'));
o.value('500', _('500'));
o.value('1000', _('1000'));
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_log', form.Value, 'ban_ssh_logcount', _('SSH Log Count'), _('Number of failed ssh login repetitions of the same ip in the log before banning.'));
o.placeholder = '3';
o = s.taboption('adv_log', form.Value, 'ban_logcount', _('Log Count'), _('Number of failed login attempts of the same IP in the log before blocking.'));
o.placeholder = '1';
o.datatype = 'range(1,10)';
o.rmempty = true;
o = s.taboption('adv_log', form.Value, 'ban_luci_logcount', _('LuCI Log Count'), _('Number of failed LuCI login repetitions of the same ip in the log before banning.'));
o.placeholder = '3';
o.datatype = 'range(1,10)';
o.rmempty = true;
o = s.taboption('adv_log', form.Value, 'ban_nginx_logcount', _('NGINX Log Count'), _('Number of failed nginx requests of the same ip in the log before banning.'));
o.placeholder = '5';
o.datatype = 'range(1,20)';
o.rmempty = true;
o = s.taboption('adv_log', form.Value, 'ban_logopts_src', _('SRC Log Options'), _('Set special SRC log options, e.g. to set a limit rate.'));
o.nocreate = false;
o.unspecified = true;
o.value('-m limit --limit 2/sec', _('-m limit --limit 2/sec (default)'));
o.value('-m limit --limit 10/sec');
o.optional = true;
o.rmempty = true;
o = s.taboption('adv_log', form.Value, 'ban_logopts_dst', _('DST Log Options'), _('Set special DST log options, e.g. to set a limit rate.'));
o.nocreate = false;
o.unspecified = true;
o.value('-m limit --limit 2/sec', _('-m limit --limit 2/sec (default)'));
o.value('-m limit --limit 10/sec');
o = s.taboption('adv_log', form.DynamicList, 'ban_logterm', _('Log Terms'), _('The default log terms / regular expressions are filtering suspicious ssh, LuCI, nginx and asterisk traffic.'));
o.optional = true;
o.rmempty = true;
/*
advanced email settings tab
*/
o = s.taboption('adv_email', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>To enable email notifications, set up the \'msmtp\' package and specify a vaild E-Mail receiver address.</b></em>';
o = s.taboption('adv_email', form.Value, 'ban_mailreceiver', _('E-Mail Receiver Address'), _('Receiver address for banIP notification E-Mails, this information is required to enable E-Mail functionality.'));
o.placeholder = 'name@example.com';
o.rmempty = true;
o = s.taboption('adv_email', form.Value, 'ban_mailsender', _('E-Mail Sender Address'), _('Sender address for banIP notification E-Mails.'));
o.placeholder = 'no-reply@banIP';
o.rmempty = true;
@ -736,44 +468,35 @@ return view.extend({
o.datatype = 'uciname';
o.rmempty = true;
o = s.taboption('adv_email', form.MultiValue, 'ban_mailactions', _('E-Mail Actions'), _('Limit E-Mail trigger to certain banIP actions.'));
o.value('start');
o.value('reload');
o.value('restart');
o.value('refresh');
o.rmempty = true;
/*
blocklist sources tab
blocklist feeds tab
*/
o = s.taboption('sources', form.DummyValue, '_sub');
o = s.taboption('feeds', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>List of supported and fully pre-configured banIP sources.</b></em>';
o.default = '<em><b>List of supported and fully pre-configured banIP feeds.</b></em>';
o = s.taboption('sources', form.MultiValue, 'ban_sources', _('Sources (Info)'));
for (var i = 0; i < sources.length; i++) {
if (sources[i].match(/^\s+\+/)) {
source = sources[i].match(/^\s+\+\s(\w+)\s/)[1].trim();
info = sources[i].slice(35,70).trim();
o.value(source, source + ' (' + info + ')');
}
if (result[0]) {
var focus, feed, feeds;
feeds = JSON.parse(result[0]);
o = s.taboption('feeds', form.MultiValue, 'ban_feed', _('Feed Selection'));
for (var i = 0; i < Object.keys(feeds).length; i++) {
feed = Object.keys(feeds)[i].trim();
focus = feeds[feed].focus.trim();
o.value(feed, feed + ' (' + focus + ')');
}
o.optional = true;
o.rmempty = true;
o = s.taboption('sources', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>Country Selection</b></em>';
}
/*
prepare country data
*/
var code, country, countries = [];
if (result[3]) {
countries = result[3].trim().split('\n');
}
if (result[1]) {
countries = result[1].trim().split('\n');
o = s.taboption('sources', form.DynamicList, 'ban_countries', _('Countries'));
o = s.taboption('feeds', form.MultiValue, 'ban_country', _('Countries'));
for (var i = 0; i < countries.length; i++) {
code = countries[i].match(/^(\w+);/)[1].trim();
country = countries[i].match(/^\w+;(.*$)/)[1].trim();
@ -781,36 +504,22 @@ return view.extend({
}
o.optional = true;
o.rmempty = true;
}
o = s.taboption('sources', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>ASN Selection</b></em>';
o = s.taboption('sources', form.DynamicList, 'ban_asns', _('ASNs'));
o = s.taboption('feeds', form.DynamicList, 'ban_asn', _('ASNs'));
o.datatype = 'uinteger';
o.optional = true;
o.rmempty = true;
o = s.taboption('sources', form.DummyValue, '_sub');
o.rawhtml = true;
o.default = '<em><b>Local Sources</b></em>';
o = s.taboption('sources', form.MultiValue, 'ban_localsources', _('Local Sources'), _('Limit the selection to certain local sources.'));
o.value('maclist');
o.value('whitelist');
o.value('blacklist');
o.optional = true;
o.rmempty = true;
o = s.taboption('sources', form.DynamicList, 'ban_extrasources', _('Extra Sources'), _('Add additional, non-banIP related IPSets e.g. for reporting and queries.'));
o.datatype = 'uciname';
o.optional = true;
o.rmempty = true;
o = s.taboption('sources', form.Flag, 'ban_autoblacklist', _('Auto Blacklist'), _('Automatically transfers suspicious IPs from the log to the banIP blacklist during runtime.'));
o = s.taboption('feeds', form.Flag, 'ban_autoallowlist', _('Auto Allowlist'), _('Automatically transfers uplink IPs to the banIP allowlist.'));
o.default = 1
o.rmempty = false;
o = s.taboption('sources', form.Flag, 'ban_autowhitelist', _('Auto Whitelist'), _('Automatically transfers uplink IPs to the banIP whitelist during runtime.'));
o = s.taboption('feeds', form.Flag, 'ban_autoblocklist', _('Auto Blocklist'), _('Automatically transfers suspicious IPs to the banIP blocklist.'));
o.default = 1
o.rmempty = false;
o = s.taboption('feeds', form.Flag, 'ban_allowlistonly', _('Allowlist Only'), _('Restrict the internet access from/to a small number of secure IPs.'));
o.rmempty = false;
return m.render();

View file

@ -18,14 +18,14 @@ return view.extend({
if (res) {
log.value = res.trim();
} else {
log.value = _('No banIP related logs yet!');
log.value = _('No banIP related processing logs yet!');
}
log.scrollTop = log.scrollHeight;
});
});
return E('div', { class: 'cbi-map' },
E('div', { class: 'cbi-section' }, [
E('div', { class: 'cbi-section-descr' }, _('The syslog output, pre-filtered for banIP related messages only.')),
E('div', { class: 'cbi-section-descr' }, _('The syslog output, prefiltered for banIP-related processing log entries only.')),
E('textarea', {
'id': 'logfile',
'style': 'width: 100% !important; padding: 5px; font-family: monospace',

View file

@ -0,0 +1,231 @@
'use strict';
'require view';
'require fs';
'require ui';
/*
button handling
*/
function handleAction(report, ev) {
if (ev === 'search') {
L.ui.showModal(_('IP Search'), [
E('p', _('Search the banIP-related Sets for a specific IP.')),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
E('label', { 'style': 'padding-top:.5em', 'id': 'run' }, [
E('input', {
'class': 'cbi-input-text',
'placeholder': '192.168.0.1',
'style': 'width:300px',
'spellcheck': 'false',
'id': 'search'
})
])
]),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
'\xa0',
E('h5', _('Result')),
E('textarea', {
'id': 'result',
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
'readonly': 'readonly',
'wrap': 'off',
'rows': 20
})
]),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn cbi-button',
'click': L.hideModal
}, _('Cancel')),
' ',
E('button', {
'class': 'btn cbi-button-action',
'click': ui.createHandlerFn(this, function (ev) {
var ip = document.getElementById('search').value.trim().toLowerCase();
if (ip) {
document.getElementById('run').classList.add("spinning");
document.getElementById('search').value = ip;
document.getElementById('result').textContent = 'The search is running, please wait...';
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['search', ip])).then(function (res) {
var result = document.getElementById('result');
if (res) {
result.textContent = res.trim();
} else {
result.textContent = _('No Search results!');
}
document.getElementById('run').classList.remove("spinning");
document.getElementById('search').value = '';
})
}
document.getElementById('search').focus();
})
}, _('Search'))
])
]);
document.getElementById('search').focus();
}
if (ev === 'survey') {
var content, selectO;
content = JSON.parse(report[1]);
selectO = [E('option', { value: '' }, [_('-- Set Selection --')])];
for (var i = 0; i < Object.keys(content.nftables).length; i++) {
if (content.nftables[i].set !== undefined && content.nftables[i].set.name !== undefined) {
selectO.push(E('option', { 'value': content.nftables[i].set.name }, content.nftables[i].set.name));
}
}
L.ui.showModal(_('Set Survey'), [
E('p', _('List the elements of a specific banIP-related Set.')),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
E('label', { 'class': 'cbi-input-select', 'style': 'padding-top:.5em', 'id': 'run' }, [
E('h5', _('Set')),
E('select', { 'class': 'cbi-input-select', 'id': 'set' },
selectO
)
]),
]),
E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
'\xa0',
E('h5', _('Result')),
E('textarea', {
'id': 'result',
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
'readonly': 'readonly',
'wrap': 'off',
'rows': 20
})
]),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn cbi-button',
'click': L.hideModal
}, _('Cancel')),
' ',
E('button', {
'class': 'btn cbi-button-action',
'click': ui.createHandlerFn(this, function (ev) {
var set = document.getElementById('set').value;
if (set) {
document.getElementById('run').classList.add("spinning");
document.getElementById('result').textContent = 'The survey is running, please wait...';
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['survey', set])).then(function (res) {
var result = document.getElementById('result');
if (res) {
result.textContent = res.trim();
} else {
result.textContent = _('No Search results!');
}
document.getElementById('run').classList.remove("spinning");
document.getElementById('set').value = '';
})
}
document.getElementById('set').focus();
})
}, _('Survey'))
])
]);
document.getElementById('set').focus();
}
}
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', 'table', 'inet', 'banIP']), '{}')
]);
},
render: function (report) {
var content;
content = JSON.parse(report[0]);
var rows_sets = [];
var tbl_sets = 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)'))
])
]);
if (content.sets) {
var cnt1, cnt2, cnt3;
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 + ')' : '';
rows_sets.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)
]);
});
rows_sets.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 + ')')
]);
}
cbi_update_table(tbl_sets, rows_sets);
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
E('div', { 'class': 'cbi-section' }, [
E('p', _('This tab shows the last generated Set Report, press the \'Refresh\' button to get a new one.')),
E('p', '\xa0'),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Timestamp')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.timestamp || '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('auto-added to allowlist today')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.autoadd_allow || '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('auto-added to blocklist today')),
E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.autoadd_block || '-')
]),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn cbi-button cbi-button-apply',
'click': ui.createHandlerFn(this, function () {
return handleAction(report, 'survey');
})
}, [_('Set Survey...')]),
'\xa0\xa0\xa0',
E('button', {
'class': 'btn cbi-button cbi-button-apply',
'click': ui.createHandlerFn(this, function () {
return handleAction(report, 'search');
})
}, [_('IP Search...')]),
'\xa0\xa0\xa0',
E('button', {
'class': 'btn cbi-button cbi-button-positive',
'click': ui.createHandlerFn(this, async function () {
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['report', 'json']), '');
location.reload();
})
}, [_('Refresh')])
]),
])
,
E('br'),
E('div', { 'class': 'cbi-section' }, [
E('div', { 'class': 'left' }, [
E('h3', _('Set details')),
tbl_sets
])
])
]);
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});

View file

@ -1,37 +0,0 @@
'use strict';
'require view';
'require fs';
'require ui';
return view.extend({
load: function() {
return L.resolveDefault(fs.read_direct('/etc/banip/banip.whitelist'), '');
},
handleSave: function(ev) {
var value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n')) + '\n';
return fs.write('/etc/banip/banip.whitelist', value)
.then(function(rc) {
document.querySelector('textarea').value = value;
ui.addNotification(null, E('p', _('Whitelist changes have been saved. Refresh your banIP lists that changes take effect.')), 'info');
}).catch(function(e) {
ui.addNotification(null, E('p', _('Unable to save changes: %s').format(e.message)));
});
},
render: function(whitelist) {
return E([
E('p', {},
_('This is the local banIP whitelist to always allow certain IP/CIDR addresses.<br /> \
<em><b>Please note:</b></em> add only one IPv4 address, IPv6 address or domain name per line. Comments introduced with \'#\' are allowed - wildcards and regex are not.')),
E('p', {},
E('textarea', {
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
'spellcheck': 'false',
'wrap': 'off',
'rows': 25
}, [ whitelist != null ? whitelist : '' ])
)
]);
},
handleSaveApply: null,
handleReset: null
});

View file

@ -1,13 +0,0 @@
-- stub lua controller for 19.07 backward compatibility
module("luci.controller.banip", package.seeall)
function index()
entry({"admin", "services", "banip"}, firstchild(), _("banIP"), 60).acl_depends = { "luci-app-banip" }
entry({"admin", "services", "banip", "overview"}, view("banip/overview"), _("Overview"), 10)
entry({"admin", "services", "banip", "ipsetreport"}, view("banip/ipsetreport"), _("IPSet Report"), 20)
entry({"admin", "services", "banip", "blacklist"}, view("banip/blacklist"), _("Edit Blacklist"), 30)
entry({"admin", "services", "banip", "whitelist"}, view("banip/whitelist"), _("Edit Whitelist"), 40)
entry({"admin", "services", "banip", "maclist"}, view("banip/maclist"), _("Edit Maclist"), 50)
entry({"admin", "services", "banip", "logread"}, view("banip/logread"), _("Log View"), 60)
end

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -7,12 +7,20 @@
"path": "admin/services/banip/overview"
},
"depends": {
"acl": [ "luci-app-banip" ],
"acl": [
"luci-app-banip"
],
"fs": {
"/usr/bin/banip.sh": "executable",
"/etc/init.d/banip": "executable"
"/usr/bin/banip-service.sh": "executable",
"/etc/init.d/banip": "executable",
"/etc/banip/banip.feeds": "file",
"/etc/banip/banip.allowlist": "file",
"/etc/banip/banip.blocklist": "file",
"/etc/banip/banip.countries": "file"
},
"uci": { "banip": true }
"uci": {
"banip": true
}
}
},
"admin/services/banip/overview": {
@ -23,44 +31,44 @@
"path": "banip/overview"
}
},
"admin/services/banip/ipsetreport": {
"title": "IPSet Report",
"admin/services/banip/allowlist": {
"title": "Edit Allowlist",
"order": 20,
"action": {
"type": "view",
"path": "banip/ipsetreport"
"path": "banip/allowlist"
}
},
"admin/services/banip/blacklist": {
"title": "Edit Blacklist",
"admin/services/banip/blocklist": {
"title": "Edit Blocklist",
"order": 30,
"action": {
"type": "view",
"path": "banip/blacklist"
"path": "banip/blocklist"
}
},
"admin/services/banip/whitelist": {
"title": "Edit Whitelist",
"admin/services/banip/setreport": {
"title": "Set Reporting",
"order": 40,
"action": {
"type": "view",
"path": "banip/whitelist"
"path": "banip/setreport"
}
},
"admin/services/banip/maclist": {
"title": "Edit Maclist",
"admin/services/banip/firewall_log": {
"title": "Firewall Log",
"order": 50,
"action": {
"type": "view",
"path": "banip/maclist"
"path": "banip/firewall_log"
}
},
"admin/services/banip/logread": {
"title": "Log View",
"admin/services/banip/processing_log": {
"title": "Processing Log",
"order": 60,
"action": {
"type": "view",
"path": "banip/logread"
"path": "banip/processing_log"
}
}
}

View file

@ -2,37 +2,78 @@
"luci-app-banip": {
"description": "Grant access to LuCI app banIP",
"write": {
"uci": [ "banip" ],
"uci": [
"banip"
],
"file": {
"/etc/banip/*": [ "read" ],
"/etc/banip/banip.blacklist": [ "write" ],
"/etc/banip/banip.whitelist": [ "write" ],
"/etc/banip/banip.maclist": [ "write" ]
"/etc/banip/*": [
"read"
],
"/etc/banip/banip.allowlist": [
"write"
],
"/etc/banip/banip.blocklist": [
"write"
]
}
},
"read": {
"cgi-io": [ "exec" ],
"cgi-io": [
"exec"
],
"file": {
"/var/run/banip.pid": [ "read" ],
"/tmp/ban_runtime.json": [ "read" ],
"/sbin/logread -e banIP-": [ "exec" ],
"/usr/sbin/logread -e banIP-": [ "exec" ],
"/usr/sbin/iptables -L": [ "exec" ],
"/usr/sbin/ip6tables -L": [ "exec" ],
"/etc/init.d/banip list" : [ "exec" ],
"/etc/init.d/banip refresh" : [ "exec" ],
"/etc/init.d/banip reload" : [ "exec" ],
"/etc/init.d/banip restart" : [ "exec" ],
"/etc/init.d/banip suspend" : [ "exec" ],
"/etc/init.d/banip resume" : [ "exec" ],
"/etc/init.d/banip report gen" : [ "exec" ],
"/etc/init.d/banip report json" : [ "exec" ],
"/etc/init.d/banip timer list" : [ "exec" ],
"/etc/init.d/banip timer remove [0-9]*" : [ "exec" ],
"/etc/init.d/banip timer add * [0-9]* [0-9*]* [1-7,-*]*" : [ "exec" ],
"/etc/init.d/banip query *" : [ "exec" ]
"/etc/banip/banip.feeds": [
"read"
],
"/etc/banip/banip.countries": [
"read"
],
"/var/run/banip.pid": [
"read"
],
"/var/run/banip_runtime.json": [
"read"
],
"/sbin/logread -e banIP-": [
"exec"
],
"/usr/sbin/logread -e banIP-": [
"exec"
],
"/sbin/logread -e banIP/": [
"exec"
],
"/usr/sbin/logread -e banIP/": [
"exec"
],
"/usr/sbin/nft -tj list table inet banIP": [
"exec"
],
"/etc/init.d/banip stop": [
"exec"
],
"/etc/init.d/banip reload": [
"exec"
],
"/etc/init.d/banip restart": [
"exec"
],
"/etc/init.d/banip report json": [
"exec"
],
"/etc/init.d/banip search *": [
"exec"
],
"/etc/init.d/banip survey *": [
"exec"
],
"/etc/init.d/banip status *": [
"exec"
]
},
"uci": [ "banip" ]
"uci": [
"banip"
]
}
}
}