mirror of
https://github.com/openwrt/luci.git
synced 2026-04-15 10:51:51 +00:00
833 lines
35 KiB
JavaScript
833 lines
35 KiB
JavaScript
'use strict';
|
||
'require dom';
|
||
'require view';
|
||
'require poll';
|
||
'require fs';
|
||
'require ui';
|
||
'require uci';
|
||
'require form';
|
||
'require uqr';
|
||
'require tools.widgets as widgets';
|
||
|
||
/*
|
||
button handling
|
||
*/
|
||
function handleAction(ev) {
|
||
const status = document.getElementById('status');
|
||
const map = document.querySelector('.cbi-map');
|
||
if (ev === 'restart' || ev === 'reload') {
|
||
return dom.callClassMethod(map, 'save')
|
||
.then(L.bind(ui.changes.apply, ui.changes))
|
||
.then(function () {
|
||
document.querySelectorAll('.cbi-page-actions button').forEach(function (btn) {
|
||
btn.disabled = true;
|
||
btn.blur();
|
||
});
|
||
return fs.exec_direct('/etc/init.d/adblock', [ev]);
|
||
});
|
||
} else {
|
||
if (ev !== 'stop') {
|
||
document.querySelectorAll('.cbi-page-actions button').forEach(function (btn) {
|
||
btn.disabled = true;
|
||
btn.blur();
|
||
});
|
||
if (status && status.textContent.startsWith('paused')) {
|
||
ev = 'resume';
|
||
}
|
||
}
|
||
return fs.exec_direct('/etc/init.d/adblock', [ev]);
|
||
}
|
||
}
|
||
|
||
return view.extend({
|
||
load: function () {
|
||
return Promise.all([
|
||
L.resolveDefault(fs.read_direct('/etc/adblock/adblock.custom.feeds'), ''),
|
||
L.resolveDefault(fs.read_direct('/etc/adblock/adblock.feeds'), ''),
|
||
L.resolveDefault(fs.read_direct('/etc/adblock/adblock.categories'), ''),
|
||
uci.load('adblock').catch(() => 0)
|
||
]);
|
||
},
|
||
|
||
render: function (result) {
|
||
/*
|
||
config check
|
||
*/
|
||
if (!result[3] || result[3].length === 0) {
|
||
ui.addNotification(null, E('p', _('No adblock config found!')), 'error');
|
||
return;
|
||
}
|
||
|
||
/*
|
||
main map
|
||
*/
|
||
let m, s, o;
|
||
m = new form.Map('adblock', 'Adblock', _('Configuration of the adblock package to block ad/abuse domains by using DNS. \
|
||
For further information please check the %s.'.format(`<a style="color:#37c;font-weight:bold;" href="https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md" target="_blank" rel="noreferrer noopener" >${_('online documentation')}</a>`)));
|
||
|
||
/*
|
||
set text content helper function
|
||
*/
|
||
const setText = (id, value) => {
|
||
const el = document.getElementById(id);
|
||
if (el) {
|
||
el.textContent = value || '-';
|
||
}
|
||
};
|
||
|
||
/*
|
||
poll runtime information
|
||
*/
|
||
let parseErrCount = 0;
|
||
poll.add(function () {
|
||
return L.resolveDefault(fs.stat('/var/run/adb_runtime.json'), null).then(function (stat) {
|
||
if (!stat) {
|
||
return;
|
||
}
|
||
return L.resolveDefault(fs.read_direct('/var/run/adb_runtime.json'), null).then(function (res) {
|
||
const status = document.getElementById('status');
|
||
const buttons = document.querySelectorAll('.cbi-page-actions button');
|
||
let info = null;
|
||
try {
|
||
info = JSON.parse(res);
|
||
parseErrCount = 0;
|
||
if (!poll.active()) {
|
||
poll.start();
|
||
}
|
||
} catch (e) {
|
||
info = null;
|
||
parseErrCount++;
|
||
if (status) {
|
||
status.textContent = '-';
|
||
buttons.forEach(function (btn) {
|
||
btn.disabled = false;
|
||
});
|
||
status.classList.remove('spinning');
|
||
if (parseErrCount >= 5) {
|
||
ui.addNotification(null, E('p', _('Unable to parse the adblock runtime information!')), 'error');
|
||
poll.stop();
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
if (status && info) {
|
||
status.textContent = `${info.adblock_status || '-'} (frontend: ${info.frontend_ver || '-'} / backend: ${info.backend_ver || '-'})`;
|
||
if (info.adblock_status === "processing") {
|
||
buttons.forEach(function (btn) {
|
||
btn.disabled = true;
|
||
btn.blur();
|
||
});
|
||
if (!status.classList.contains("spinning")) {
|
||
status.classList.add("spinning");
|
||
}
|
||
} else {
|
||
status.classList.remove("spinning");
|
||
if (document.getElementById('btn_suspend')) {
|
||
if (info.adblock_status === 'paused') {
|
||
document.querySelector('#btn_suspend').textContent = 'Resume';
|
||
}
|
||
if (info.adblock_status === 'enabled') {
|
||
document.querySelector('#btn_suspend').textContent = 'Suspend';
|
||
}
|
||
}
|
||
buttons.forEach(function (btn) {
|
||
btn.disabled = false;
|
||
});
|
||
}
|
||
}
|
||
if (info) {
|
||
setText('domains', info.blocked_domains);
|
||
setText('feeds', info.active_feeds?.join(' '));
|
||
setText('backend', info.dns_backend);
|
||
setText('ifaces', info.run_ifaces);
|
||
setText('run', info.run_information);
|
||
setText('flags', info.run_flags);
|
||
setText('last', info.last_run);
|
||
setText('sys', info.system_info);
|
||
}
|
||
});
|
||
});
|
||
}, 2);
|
||
|
||
/*
|
||
runtime information and buttons
|
||
*/
|
||
s = m.section(form.NamedSection, 'global');
|
||
s.render = L.bind(function (view, section_id) {
|
||
return E('div', { 'class': 'cbi-section' }, [
|
||
E('h3', _('Information')),
|
||
E('div', { 'class': 'cbi-value' }, [
|
||
E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Status / Version')),
|
||
E('div', { 'class': 'cbi-value-field spinning', 'id': 'status', 'style': 'margin-bottom:-5px;color:#37c;' }, '\xa0')
|
||
]),
|
||
E('div', { 'class': 'cbi-value' }, [
|
||
E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Blocked Domains')),
|
||
E('div', { 'class': 'cbi-value-field', 'id': 'domains', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
|
||
]),
|
||
E('div', { 'class': 'cbi-value' }, [
|
||
E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Active Feeds')),
|
||
E('div', { 'class': 'cbi-value-field', 'id': 'feeds', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
|
||
]),
|
||
E('div', { 'class': 'cbi-value' }, [
|
||
E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('DNS Backend')),
|
||
E('div', { 'class': 'cbi-value-field', 'id': 'backend', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
|
||
]),
|
||
E('div', { 'class': 'cbi-value' }, [
|
||
E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Run Interfaces')),
|
||
E('div', { 'class': 'cbi-value-field', 'id': 'ifaces', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
|
||
]),
|
||
E('div', { 'class': 'cbi-value' }, [
|
||
E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Run Information')),
|
||
E('div', { 'class': 'cbi-value-field', 'id': 'run', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
|
||
]),
|
||
E('div', { 'class': 'cbi-value' }, [
|
||
E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Run Flags')),
|
||
E('div', { 'class': 'cbi-value-field', 'id': 'flags', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
|
||
]),
|
||
E('div', { 'class': 'cbi-value' }, [
|
||
E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Last Run')),
|
||
E('div', { 'class': 'cbi-value-field', 'id': 'last', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
|
||
]),
|
||
E('div', { 'class': 'cbi-value' }, [
|
||
E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('System Info')),
|
||
E('div', { 'class': 'cbi-value-field', 'id': 'sys', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
|
||
])
|
||
]);
|
||
}, o, this);
|
||
|
||
/*
|
||
tabbed config section
|
||
*/
|
||
s = m.section(form.NamedSection, 'global', 'adblock', _('Settings'));
|
||
s.addremove = false;
|
||
s.tab('general', _('General Settings'));
|
||
s.tab('additional', _('Additional Settings'));
|
||
s.tab('firewall', _('Firewall Settings'));
|
||
s.tab('adv_dns', _('Advanced DNS Settings'));
|
||
s.tab('adv_report', _('Advanced Report Settings'));
|
||
s.tab('adv_email', _('Advanced E-Mail Settings'));
|
||
s.tab('feeds', _('Feed Selection'));
|
||
|
||
/*
|
||
general settings tab
|
||
*/
|
||
o = s.taboption('general', form.DummyValue, '_sub');
|
||
o.rawhtml = true;
|
||
o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs an adblock service restart to take effect.') + '</em>'
|
||
+ '<hr style="width: 200px; height: 1px;" />';
|
||
|
||
o = s.taboption('general', form.Flag, 'adb_enabled', _('Enabled'), _('Enable the adblock service.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('general', widgets.NetworkSelect, 'adb_trigger', _('Startup Trigger Interface'), _('List of available network interfaces to trigger the adblock start.'));
|
||
o.multiple = true;
|
||
o.nocreate = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('general', form.Value, 'adb_triggerdelay', _('Trigger Delay'), _('Additional trigger delay in seconds before adblock processing begins.'));
|
||
o.placeholder = '5';
|
||
o.datatype = 'range(1,300)';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('general', form.Flag, 'adb_tld', _('TLD Compression'), _('The top level domain compression removes thousands of needless host entries from the final DNS blocklist.'));
|
||
o.default = 1;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('general', form.Flag, 'adb_safesearch', _('Enable SafeSearch'), _('Enforcing SafeSearch for google, bing, brave, duckduckgo, yandex, youtube and pixabay.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('general', form.MultiValue, 'adb_safesearchlist', _('Limit SafeSearch'), _('Limit SafeSearch to certain providers.'));
|
||
o.depends('adb_safesearch', '1');
|
||
o.value('google');
|
||
o.value('bing');
|
||
o.value('brave');
|
||
o.value('duckduckgo');
|
||
o.value('yandex');
|
||
o.value('youtube');
|
||
o.value('pixabay');
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('general', form.Flag, 'adb_report', _('DNS Report'), _('Gather DNS related network traffic via tcpdump and provide a DNS Report on demand. \
|
||
This needs the additional \'tcpdump\' or \'tcpdump-mini\' package installation and a full adblock service restart to take effect.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('general', form.Flag, 'adb_mail', _('E-Mail Notification'), _('Send adblock related notification e-mails. \
|
||
This needs the additional \'msmtp\' package installation.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('general', form.Value, 'adb_mailreceiver', _('E-Mail Receiver Address'), _('Receiver address for adblock notification e-mails.'));
|
||
o.depends('adb_mail', '1');
|
||
o.placeholder = 'name@example.com';
|
||
o.rmempty = true;
|
||
|
||
/*
|
||
additional settings tab
|
||
*/
|
||
o = s.taboption('additional', form.DummyValue, '_sub');
|
||
o.rawhtml = true;
|
||
o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs an adblock service restart to take effect.') + '</em>'
|
||
+ '<hr style="width: 200px; height: 1px;" />';
|
||
|
||
o = s.taboption('additional', form.Flag, 'adb_debug', _('Verbose Debug Logging'), _('Enable verbose debug logging in case of any processing errors.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('additional', form.ListValue, 'adb_cores', _('CPU Cores'), _('Limit the cpu cores used by adblock to save RAM, autodetected by default.'));
|
||
o.value('1');
|
||
o.value('2');
|
||
o.value('4');
|
||
o.value('8');
|
||
o.value('16');
|
||
o.placeholder = _('-- default --');
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('additional', form.ListValue, 'adb_nicelimit', _('Nice Level'), _('The selected priority will be used for adblock background processing.'));
|
||
o.value('-20', _('Highest Priority'));
|
||
o.value('-10', _('High Priority'));
|
||
o.value('0', _('Normal Priority'));
|
||
o.value('10', _('Less Priority'));
|
||
o.value('19', _('Least Priority'));
|
||
o.default = '0';
|
||
o.placeholder = _('-- default --');
|
||
o.create = true;
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('additional', form.Value, 'adb_basedir', _('Base Directory'), _('Base working directory during adblock processing.'));
|
||
o.placeholder = '/tmp';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('additional', form.Value, 'adb_backupdir', _('Backup Directory'), _('Target directory for blocklist backups.'));
|
||
o.placeholder = '/tmp/adblock-backup';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('additional', form.ListValue, 'adb_fetchcmd', _('Download Utility'), _('List of supported and fully pre-configured download utilities.'));
|
||
o.value('uclient-fetch');
|
||
o.value('wget');
|
||
o.value('curl');
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('additional', form.Flag, 'adb_fetchinsecure', _('Download Insecure'), _('Don\'t check SSL server certificates during download.'));
|
||
o.default = 0;
|
||
o.rmempty = true;
|
||
|
||
/*
|
||
firewall settings tab
|
||
*/
|
||
o = s.taboption('firewall', form.DummyValue, '_fw_sub1');
|
||
o.rawhtml = true;
|
||
o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs an adblock service restart to take effect.') + '</em>'
|
||
+ '<hr style="width: 200px; height: 1px;" />'
|
||
+ '<em style="color:#37c;font-weight:bold;">' + _('External Unfiltered DNS Policy (MAC-/Interface‑based DNS bypass)') + '</em>';
|
||
|
||
o = s.taboption('firewall', form.Flag, 'adb_nftallow', _('Enable Unfiltered DNS Routing'), _('Routes selected MACs or interfaces to an unfiltered external DNS resolver, bypassing local adblock.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('firewall', form.DynamicList, 'adb_nftmacallow', _('MAC DNS Filter Targets'), _('Devices with listed MAC addresses will always use the configured unfiltered DNS server.'));
|
||
o.depends('adb_nftallow', '1');
|
||
o.datatype = 'macaddr';
|
||
o.placeholder = '00:11:22:33:44:55';
|
||
o.multiple = true;
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', widgets.DeviceSelect, 'adb_nftdevallow', _('Interface DNS Filter Targets'), _('Entire interfaces or VLANs will be routed to the unfiltered DNS server.'));
|
||
o.depends('adb_nftallow', '1');
|
||
o.multiple = true;
|
||
o.nocreate = true;
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.Value, 'adb_allowdnsv4', _('IPv4 DNS Resolver'), _('External IPv4 DNS resolver applied to MACs and interfaces using the unfiltered DNS policy.'));
|
||
o.depends('adb_nftallow', '1');
|
||
o.datatype = 'ip4addr("nomask")';
|
||
o.value('86.54.11.100', _('DNS4EU (unfiltered)'));
|
||
o.value('94.140.14.140', _('AdGuard (unfiltered)'));
|
||
o.value('76.76.2.0', _('Control D (unfiltered)'));
|
||
o.value('1.1.1.1', _('Cloudflare (unfiltered)'));
|
||
o.value('9.9.9.10', _('Quad9 (unfiltered)'));
|
||
o.value('185.150.99.255', _('Digitale Gesellschaft (unfiltered)'));
|
||
o.default = '86.54.11.100';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.Value, 'adb_allowdnsv6', _('IPv6 DNS Resolver'), _('External IPv6 DNS resolver applied to MACs and interfaces using the unfiltered DNS policy.'));
|
||
o.depends('adb_nftallow', '1');
|
||
o.datatype = 'ip6addr("nomask")';
|
||
o.value('2a13:1001::86:54:11:100', _('DNS4EU (unfiltered)'));
|
||
o.value('2a10:50c0::1:ff', _('AdGuard (unfiltered)'));
|
||
o.value('2606:1a40::', _('Control D (unfiltered)'));
|
||
o.value('2606:4700:4700::1111', _('Cloudflare (unfiltered)'));
|
||
o.value('2620:fe::10', _('Quad9 (unfiltered)'));
|
||
o.value('2a07:6b47:6b47::255', _('Digitale Gesellschaft (unfiltered)'));
|
||
o.default = '2a13:1001::86:54:11:100';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.DummyValue, '_fw_sub2');
|
||
o.rawhtml = true;
|
||
o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('External Filtered DNS Policy (MAC-/Interface‑based DNS bypass)') + '</em>';
|
||
|
||
o = s.taboption('firewall', form.Flag, 'adb_nftblock', _('Enable Filtered DNS Routing'), _('Routes selected MACs or interfaces to a filtered external DNS resolver, bypassing local adblock.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('firewall', form.DynamicList, 'adb_nftmacblock', _('MAC DNS Filter Targets'), _('Devices with listed MAC addresses will always use the configured filtered DNS server.'));
|
||
o.depends('adb_nftblock', '1');
|
||
o.datatype = 'macaddr';
|
||
o.placeholder = '00:11:22:33:44:55';
|
||
o.multiple = true;
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', widgets.DeviceSelect, 'adb_nftdevblock', _('Interface DNS Filter Targets'), _('Entire interfaces or VLANs will be routed to the filtered DNS server.'));
|
||
o.depends('adb_nftblock', '1');
|
||
o.multiple = true;
|
||
o.nocreate = true;
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.Value, 'adb_blockdnsv4', _('IPv4 DNS Resolver'), _('External IPv4 DNS resolver applied to MACs and interfaces using the filtered DNS policy.'));
|
||
o.depends('adb_nftblock', '1');
|
||
o.datatype = 'ip4addr("nomask")';
|
||
o.value('86.54.11.1', _('DNS4EU (protective)'));
|
||
o.value('86.54.11.12', _('DNS4EU (protective+family)'));
|
||
o.value('86.54.11.13', _('DNS4EU (protective+adblock)'));
|
||
o.value('86.54.11.11', _('DNS4EU (protective+family+adblock)'));
|
||
o.value('176.9.93.198', _('dnsforge (normal)'));
|
||
o.value('49.12.43.208', _('dnsforge (clean)'));
|
||
o.value('49.12.222.213', _('dnsforge (hard)'));
|
||
o.value('94.140.14.14', _('AdGuard (default)'));
|
||
o.value('94.140.14.15', _('AdGuard (family)'));
|
||
o.value('76.76.10.0', _('Control D (security)'));
|
||
o.value('76.76.10.10', _('Control D (family)'));
|
||
o.value('76.76.10.11', _('Control D (adblock)'));
|
||
o.value('1.1.1.2', _('Cloudflare (malware)'));
|
||
o.value('1.1.1.3', _('Cloudflare (malware+family)'));
|
||
o.value('9.9.9.9', _('Quad9 (malware)'));
|
||
o.default = '86.54.11.13';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.Value, 'adb_blockdnsv6', _('IPv6 DNS Resolver'), _('External IPv6 DNS resolver applied to MACs and interfaces using the filtered DNS policy.'));
|
||
o.depends('adb_nftblock', '1');
|
||
o.datatype = 'ip6addr("nomask")';
|
||
o.value('2a13:1001::86:54:11:1', _('DNS4EU (protective)'));
|
||
o.value('2a13:1001::86:54:11:12', _('DNS4EU (protective+family)'));
|
||
o.value('2a13:1001::86:54:11:13', _('DNS4EU (protective+adblock)'));
|
||
o.value('2a13:1001::86:54:11:11', _('DNS4EU (protective+family+adblock)'));
|
||
o.value('2a01:4f8:151:34aa::198', _('dnsforge (normal)'));
|
||
o.value('2a01:4f8:c012:ed89::208', _('dnsforge (clean)'));
|
||
o.value('2a01:4f8:c17:2c61::213', _('dnsforge (hard)'));
|
||
o.value('2a10:50c0::ad1:ff', _('AdGuard (default)'));
|
||
o.value('2a10:50c0::bad1:ff', _('AdGuard (family)'));
|
||
o.value('2606:1a40:1::', _('Control D (security)'));
|
||
o.value('2606:1a40:1::1', _('Control D (family)'));
|
||
o.value('2606:1a40:1::2', _('Control D (adblock)'));
|
||
o.value('2606:4700:4700::1112', _('Cloudflare (malware)'));
|
||
o.value('2606:4700:4700::1113', _('Cloudflare (malware+family)'));
|
||
o.value('2620:fe::fe', _('Quad9 (malware)'));
|
||
o.default = '2a13:1001::86:54:11:13';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.DummyValue, '_fw_sub3');
|
||
o.rawhtml = true;
|
||
o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('External Remote DNS Policy (temporary MAC‑based remote DNS bypass)') + '</em>';
|
||
|
||
o = s.taboption('firewall', form.Flag, 'adb_nftremote', _('Enable Remote DNS Routing'), _('Allows temporary access to an unfiltered external DNS resolver, bypassing local adblock.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('firewall', form.DynamicList, 'adb_nftmacremote', _('MAC Remote Filter Targets'), _('Listed MAC addresses are allowed to use the remote DNS bypass.'));
|
||
o.depends('adb_nftremote', '1');
|
||
o.datatype = 'macaddr';
|
||
o.placeholder = '00:11:22:33:44:55';
|
||
o.multiple = true;
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.Value, 'adb_nftremotetimeout', _('Remote DNS Timeout'), _('Time limit in minutes for using the remote DNS bypass per listed MAC address.'));
|
||
o.depends('adb_nftremote', '1');
|
||
o.datatype = 'range(1,300)';
|
||
o.value('5', _('5 minutes'));
|
||
o.value('10', _('10 minutes'));
|
||
o.value('15', _('15 minutes'));
|
||
o.value('30', _('30 minutes'));
|
||
o.value('60', _('60 minutes'));
|
||
o.default = '15';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.Value, 'adb_remotednsv4', _('IPv4 Remote DNS Resolver'), _('External IPv4 DNS resolver applied to MACs using the unfiltered remote DNS policy.'));
|
||
o.depends('adb_nftremote', '1');
|
||
o.datatype = 'ip4addr("nomask")';
|
||
o.value('86.54.11.100', _('DNS4EU (unfiltered)'));
|
||
o.value('94.140.14.140', _('AdGuard (unfiltered)'));
|
||
o.value('76.76.2.0', _('Control D (unfiltered)'));
|
||
o.value('1.1.1.1', _('Cloudflare (unfiltered)'));
|
||
o.value('9.9.9.10', _('Quad9 (unfiltered)'));
|
||
o.value('185.150.99.255', _('Digitale Gesellschaft (unfiltered)'));
|
||
o.default = '86.54.11.100';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.Value, 'adb_remotednsv6', _('IPv6 Remote DNS Resolver'), _('External IPv6 DNS resolver applied to MACs using the unfiltered remote DNS policy.'));
|
||
o.depends('adb_nftremote', '1');
|
||
o.datatype = 'ip6addr("nomask")';
|
||
o.value('2a13:1001::86:54:11:100', _('DNS4EU (unfiltered)'));
|
||
o.value('2a10:50c0::1:ff', _('AdGuard (unfiltered)'));
|
||
o.value('2606:1a40::', _('Control D (unfiltered)'));
|
||
o.value('2606:4700:4700::1111', _('Cloudflare (unfiltered)'));
|
||
o.value('2620:fe::10', _('Quad9 (unfiltered)'));
|
||
o.value('2a07:6b47:6b47::255', _('Digitale Gesellschaft (unfiltered)'));
|
||
o.default = '2a13:1001::86:54:11:100';
|
||
o.rmempty = true;
|
||
|
||
const url = `${window.location.protocol}//${window.location.hostname}/cgi-bin/adblock`;
|
||
const options = {
|
||
pixelSize: 3,
|
||
margin: 1,
|
||
ecLevel: 'M',
|
||
whiteColor: 'white',
|
||
blackColor: 'black'
|
||
};
|
||
const svg = uqr.renderSVG(url, options);
|
||
o = s.taboption('firewall', form.DummyValue, '_fw_qr', _('QRCode for Remote Access'));
|
||
o.rawhtml = true;
|
||
o.default = svg;
|
||
|
||
o = s.taboption('firewall', form.DummyValue, '_fw_sub4');
|
||
o.rawhtml = true;
|
||
o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('External DNS Bridge (Zero‑Downtime during DNS Restarts)') + '</em>';
|
||
|
||
o = s.taboption('firewall', form.Flag, 'adb_nftbridge', _('Enable DNS Bridge'), _('Enables a temporary DNS bridge to an external DNS resolver during local DNS restarts.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('firewall', form.Value, 'adb_bridgednsv4', _('IPv4 DNS Resolver'), _('External IPv4 DNS resolver used during bridging.'));
|
||
o.depends('adb_nftbridge', '1');
|
||
o.datatype = 'ip4addr("nomask")';
|
||
o.value('86.54.11.1', _('DNS4EU (protective)'));
|
||
o.value('86.54.11.12', _('DNS4EU (protective+family)'));
|
||
o.value('86.54.11.13', _('DNS4EU (protective+adblock)'));
|
||
o.value('86.54.11.11', _('DNS4EU (protective+family+adblock)'));
|
||
o.value('176.9.93.198', _('dnsforge (normal)'));
|
||
o.value('49.12.43.208', _('dnsforge (clean)'));
|
||
o.value('49.12.222.213', _('dnsforge (hard)'));
|
||
o.value('94.140.14.14', _('AdGuard (default)'));
|
||
o.value('94.140.14.15', _('AdGuard (family)'));
|
||
o.value('76.76.10.0', _('Control D (security)'));
|
||
o.value('76.76.10.10', _('Control D (family)'));
|
||
o.value('76.76.10.11', _('Control D (adblock)'));
|
||
o.value('1.1.1.2', _('Cloudflare (malware)'));
|
||
o.value('1.1.1.3', _('Cloudflare (malware+family)'));
|
||
o.value('9.9.9.9', _('Quad9 (malware)'));
|
||
o.value('86.54.11.100', _('DNS4EU (unfiltered)'));
|
||
o.value('94.140.14.140', _('AdGuard (unfiltered)'));
|
||
o.value('76.76.2.0', _('Control D (unfiltered)'));
|
||
o.value('1.1.1.1', _('Cloudflare (unfiltered)'));
|
||
o.value('9.9.9.10', _('Quad9 (unfiltered)'));
|
||
o.value('185.150.99.255', _('Digitale Gesellschaft (unfiltered)'));
|
||
o.default = '86.54.11.13';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.Value, 'adb_bridgednsv6', _('IPv6 DNS Resolver'), _('External IPv6 DNS resolver used during bridging.'));
|
||
o.depends('adb_nftbridge', '1');
|
||
o.datatype = 'ip6addr("nomask")';
|
||
o.value('2a13:1001::86:54:11:1', _('DNS4EU (protective)'));
|
||
o.value('2a13:1001::86:54:11:12', _('DNS4EU (protective+family)'));
|
||
o.value('2a13:1001::86:54:11:13', _('DNS4EU (protective+adblock)'));
|
||
o.value('2a13:1001::86:54:11:11', _('DNS4EU (protective+family+adblock)'));
|
||
o.value('2a01:4f8:151:34aa::198', _('dnsforge (normal)'));
|
||
o.value('2a01:4f8:c012:ed89::208', _('dnsforge (clean)'));
|
||
o.value('2a01:4f8:c17:2c61::213', _('dnsforge (hard)'));
|
||
o.value('2a10:50c0::ad1:ff', _('AdGuard (default)'));
|
||
o.value('2a10:50c0::bad1:ff', _('AdGuard (family)'));
|
||
o.value('2606:1a40:1::', _('Control D (security)'));
|
||
o.value('2606:1a40:1::1', _('Control D (family)'));
|
||
o.value('2606:1a40:1::2', _('Control D (adblock)'));
|
||
o.value('2606:4700:4700::1112', _('Cloudflare (malware)'));
|
||
o.value('2606:4700:4700::1113', _('Cloudflare (malware+family)'));
|
||
o.value('2620:fe::fe', _('Quad9 (malware)'));
|
||
o.value('2a13:1001::86:54:11:100', _('DNS4EU (unfiltered)'));
|
||
o.value('2a10:50c0::1:ff', _('AdGuard (unfiltered)'));
|
||
o.value('2606:1a40::', _('Control D (unfiltered)'));
|
||
o.value('2606:4700:4700::1111', _('Cloudflare (unfiltered)'));
|
||
o.value('2620:fe::10', _('Quad9 (unfiltered)'));
|
||
o.value('2a07:6b47:6b47::255', _('Digitale Gesellschaft (unfiltered)'));
|
||
o.default = '2a13:1001::86:54:11:13';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.DummyValue, '_fw_sub5');
|
||
o.rawhtml = true;
|
||
o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('Local DNS Enforcement') + '</em>';
|
||
|
||
o = s.taboption('firewall', form.Flag, 'adb_nftforce', _('Force Local DNS'), _('Redirect all local DNS queries from specified LAN zones to the local DNS resolver, applies to UDP and TCP protocol.'));
|
||
o.rmempty = false;
|
||
|
||
o = s.taboption('firewall', widgets.DeviceSelect, 'adb_nftdevforce', _('Forced Devices/VLANs'), _('Firewall LAN Devices/VLANs that should be forced locally.'));
|
||
o.depends('adb_nftforce', '1');
|
||
o.multiple = true;
|
||
o.nocreate = true;
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('firewall', form.DynamicList, 'adb_nftportforce', _('Forced Ports'), _('Firewall ports that should be forced locally.'));
|
||
o.depends('adb_nftforce', '1');
|
||
o.multiple = true;
|
||
o.nocreate = false;
|
||
o.datatype = 'port';
|
||
o.value('53');
|
||
o.value('853');
|
||
o.value('5353');
|
||
o.rmempty = true;
|
||
|
||
/*
|
||
advanced dns settings tab
|
||
*/
|
||
o = s.taboption('adv_dns', form.DummyValue, '_sub');
|
||
o.rawhtml = true;
|
||
o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs an adblock service restart to take effect.') + '</em>'
|
||
+ '<hr style="width: 200px; height: 1px;" />';
|
||
|
||
o = s.taboption('adv_dns', form.ListValue, 'adb_dns', _('DNS Backend'), _('List of supported DNS backends.'));
|
||
o.value('dnsmasq', _('dnsmasq'));
|
||
o.value('unbound', _('unbound'));
|
||
o.value('named', _('bind'));
|
||
o.value('smartdns', _('smartdns'));
|
||
o.value('kresd', _('kresd'));
|
||
o.value('raw', _('raw'));
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_dns', form.Value, 'adb_dnsinstance', _('DNS Instance'), _('Set the dns backend instance used by adblock.'));
|
||
o.depends('adb_dns', 'dnsmasq');
|
||
o.depends('adb_dns', 'smartdns');
|
||
o.datatype = 'uinteger';
|
||
o.placeholder = '0';
|
||
o.default = '0';
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_dns', form.Flag, 'adb_dnsshift', _('Shift DNS Blocklist'), _('Shift the final DNS blocklist to the backup directory and only set a soft link to this file in memory. \
|
||
As long as your backup directory resides on an external drive, enable this option to save memory.'));
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_dns', form.Flag, 'adb_dnsflush', _('Flush DNS Cache'), _('Empty the DNS cache before adblock processing starts to reduce the memory consumption.'));
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_dns', form.Value, 'adb_lookupdomain', _('DNS Lookup Domain'), _('Domain to check for a successful DNS backend restart.'));
|
||
o.placeholder = 'localhost';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_dns', form.Value, 'adb_dnsdir', _('DNS Directory'), _('Overwrite the default target directory for the generated blocklist.'));
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_dns', form.Value, 'adb_dnstimeout', _('DNS Restart Timeout'), _('Timeout to wait for a successful DNS backend restart.'));
|
||
o.placeholder = '20';
|
||
o.datatype = 'range(5,60)';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_dns', form.Flag, 'adb_jail', _('Jail Mode'), _('Only domains on the allowlist are permitted, all other DNS requests are rejected.'));
|
||
o.rmempty = true;
|
||
|
||
/*
|
||
advanced report settings tab
|
||
*/
|
||
o = s.taboption('adv_report', form.DummyValue, '_sub');
|
||
o.rawhtml = true;
|
||
o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs an adblock service restart to take effect.') + '</em>'
|
||
+ '<hr style="width: 200px; height: 1px;" />';
|
||
|
||
o = s.taboption('adv_report', widgets.DeviceSelect, 'adb_repiface', _('Report Interface'), _('List of available network devices used by tcpdump.'));
|
||
o.nocreate = false;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_report', form.Value, 'adb_reportdir', _('Report Directory'), _('Target directory for DNS related report files.'));
|
||
o.placeholder = '/tmp/adblock-report';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_report', form.Value, 'adb_repchunkcnt', _('Report Chunk Count'), _('Report chunk count used by tcpdump.'));
|
||
o.placeholder = '5';
|
||
o.datatype = 'range(1,10)';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_report', form.Value, 'adb_repchunksize', _('Report Chunk Size'), _('Report chunk size used by tcpdump in MByte.'));
|
||
o.placeholder = '1';
|
||
o.datatype = 'range(1,10)';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_report', form.DynamicList, 'adb_repport', _('Report Ports'), _('The list of ports used by tcpdump.'));
|
||
o.datatype = 'port';
|
||
o.placeholder = '53';
|
||
o.multiple = true;
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_report', form.Flag, 'adb_represolve', _('Resolve IPs'), _('Resolve reporting IP addresses by using reverse DNS (PTR) lookups.'));
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_report', form.Flag, 'adb_map', _('GeoIP Map'), _('Enable a GeoIP map that shows the geographical location of the blocked domains.'));
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
/*
|
||
advanced email settings tab
|
||
*/
|
||
o = s.taboption('adv_email', form.DummyValue, '_sub');
|
||
o.rawhtml = true;
|
||
o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs an adblock service restart to take effect.') + '</em>'
|
||
+ '<hr style="width: 200px; height: 1px;" />';
|
||
|
||
o = s.taboption('adv_email', form.Value, 'adb_mailsender', _('E-Mail Sender Address'), _('Sender address for adblock notification E-Mails.'));
|
||
o.placeholder = 'no-reply@adblock';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_email', form.Value, 'adb_mailtopic', _('E-Mail Topic'), _('Topic for adblock notification E-Mails.'));
|
||
o.placeholder = 'adblock notification';
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('adv_email', form.Value, 'adb_mailprofile', _('E-Mail Profile'), _('Profile used by \'msmtp\' for adblock notification E-Mails.'));
|
||
o.placeholder = 'adb_notify';
|
||
o.rmempty = true;
|
||
|
||
/*
|
||
feed selection tab
|
||
*/
|
||
let chain, descr;
|
||
let feeds = null;
|
||
|
||
if (result[0] && result[0].trim() !== "") {
|
||
try {
|
||
feeds = JSON.parse(result[0]);
|
||
} catch (e) {
|
||
ui.addNotification(null, E('p', _('Unable to parse the custom feed file!')), 'error');
|
||
}
|
||
}
|
||
if (!feeds && result[1] && result[1].trim() !== "") {
|
||
try {
|
||
feeds = JSON.parse(result[1]);
|
||
} catch (e) {
|
||
ui.addNotification(null, E('p', _('Unable to parse the default feed file!')), 'error');
|
||
}
|
||
}
|
||
|
||
o = s.taboption('feeds', form.DummyValue, '_sub');
|
||
o.rawhtml = true;
|
||
o.default = '<em style="color:#37c;font-weight:bold;">' + _('Changes on this tab needs an adblock service reload to take effect.') + '</em>'
|
||
+ '<hr style="width: 200px; height: 1px;" />'
|
||
+ '<em style="color:#37c;font-weight:bold;">' + _('External Blocklist Feeds') + '</em>';
|
||
|
||
if (feeds && Object.keys(feeds).length) {
|
||
o = s.taboption('feeds', form.MultiValue, 'adb_feed', _('Blocklist Feed'));
|
||
const feedKeys = Object.keys(feeds);
|
||
for (const feed of feedKeys) {
|
||
chain = feeds[feed].size?.trim() || 'in';
|
||
descr = feeds[feed].descr?.trim() || '-';
|
||
o.value(feed.trim(), feed.trim() + ' (' + chain + ', ' + descr + ')');
|
||
}
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
}
|
||
|
||
/*
|
||
prepare category data
|
||
*/
|
||
const categories = result[2] ? result[2].trim().split('\n') : [];
|
||
|
||
function addCategoryOptions(option, prefix) {
|
||
for (const line of categories) {
|
||
const cat = line.match(/^(\w+);(.*?)(?:;(.*))?$/);
|
||
if (!cat || cat[1].trim() !== prefix) continue;
|
||
cat[3] !== undefined
|
||
? option.value(cat[3].trim(), cat[2].trim())
|
||
: option.value(cat[2].trim());
|
||
}
|
||
}
|
||
|
||
o = s.taboption('feeds', form.DummyValue, '_feeds1');
|
||
o.rawhtml = true;
|
||
o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('1Hosts List Selection') + '</em>';
|
||
|
||
o = s.taboption('feeds', form.DynamicList, 'adb_hst_feed', _('Categories'));
|
||
addCategoryOptions(o, 'hst');
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('feeds', form.DummyValue, '_feeds2');
|
||
o.rawhtml = true;
|
||
o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('Hagezi List Selection') + '</em>';
|
||
|
||
o = s.taboption('feeds', form.DynamicList, 'adb_hag_feed', _('Categories'));
|
||
addCategoryOptions(o, 'hag');
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('feeds', form.DummyValue, '_feeds3');
|
||
o.rawhtml = true;
|
||
o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('IPFire List Selection') + '</em>';
|
||
|
||
o = s.taboption('feeds', form.DynamicList, 'adb_ipf_feed', _('Categories'));
|
||
addCategoryOptions(o, 'ipf');
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('feeds', form.DummyValue, '_feeds4');
|
||
o.rawhtml = true;
|
||
o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('StevenBlack List Selection') + '</em>';
|
||
|
||
o = s.taboption('feeds', form.DynamicList, 'adb_stb_feed', _('Categories'));
|
||
addCategoryOptions(o, 'stb');
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
o = s.taboption('feeds', form.DummyValue, '_feeds5');
|
||
o.rawhtml = true;
|
||
o.default = '<hr style="width: 200px; height: 1px;" /><em style="color:#37c;font-weight:bold;">' + _('UTCapitole Archive Selection') + '</em>';
|
||
|
||
o = s.taboption('feeds', form.DynamicList, 'adb_utc_feed', _('Categories'));
|
||
addCategoryOptions(o, 'utc');
|
||
o.optional = true;
|
||
o.rmempty = true;
|
||
|
||
/*
|
||
action buttons
|
||
*/
|
||
s = m.section(form.NamedSection, 'global');
|
||
s.render = L.bind(function () {
|
||
return E('div', { 'class': 'cbi-page-actions' }, [
|
||
E('button', {
|
||
'class': 'btn cbi-button cbi-button-negative important',
|
||
'style': 'float:none;margin-right:.4em;',
|
||
'title': 'Stop',
|
||
'click': function () {
|
||
return handleAction('stop');
|
||
}
|
||
}, [_('Stop')]),
|
||
E('button', {
|
||
'class': 'btn cbi-button cbi-button-apply important',
|
||
'style': 'float:none;margin-right:.4em;',
|
||
'id': 'btn_suspend',
|
||
'title': 'Suspend/Resume',
|
||
'click': function () {
|
||
return handleAction('suspend');
|
||
}
|
||
}, [_('Suspend')]),
|
||
E('button', {
|
||
'class': 'btn cbi-button cbi-button-positive important',
|
||
'style': 'float:none;margin-right:.4em;',
|
||
'title': 'Save & Reload',
|
||
'click': function () {
|
||
return handleAction('reload');
|
||
}
|
||
}, [_('Save & Reload')]),
|
||
E('button', {
|
||
'class': 'btn cbi-button cbi-button-positive important',
|
||
'style': 'float:none',
|
||
'title': 'Save & Restart',
|
||
'click': function () {
|
||
return handleAction('restart');
|
||
}
|
||
}, [_('Save & Restart')])
|
||
]);
|
||
});
|
||
return m.render();
|
||
},
|
||
handleSaveApply: null,
|
||
handleSave: null,
|
||
handleReset: null
|
||
});
|