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:
parent
79f7120b9f
commit
dcc94119ce
48 changed files with 22011 additions and 22024 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
});
|
|
@ -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
|
||||
});
|
|
@ -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
|
||||
});
|
|
@ -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
|
||||
});
|
File diff suppressed because it is too large
Load diff
|
@ -4,36 +4,36 @@
|
|||
'require fs';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
load: function () {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.stat('/sbin/logread'), null),
|
||||
L.resolveDefault(fs.stat('/usr/sbin/logread'), null)
|
||||
]);
|
||||
},
|
||||
render: function(stat) {
|
||||
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) {
|
||||
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 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('textarea', {
|
||||
'id': 'logfile',
|
||||
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
|
||||
'readonly': 'readonly',
|
||||
'wrap': 'off',
|
||||
'rows': 25
|
||||
})
|
||||
]));
|
||||
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',
|
||||
'readonly': 'readonly',
|
||||
'wrap': 'off',
|
||||
'rows': 25
|
||||
})
|
||||
]));
|
||||
},
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
|
@ -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
|
||||
});
|
|
@ -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
|
||||
});
|
|
@ -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
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue