Blackhole route for VPN configuration.

luci-app-ruantiblock: UI changes for settings.js.
ruantiblock-mod-lua, ruantiblock-mod-py: Added BLLIST_CIDR_EXCLUDED option.
This commit is contained in:
gSpot
2025-09-15 18:25:20 +03:00
parent 493cc103b8
commit 4f68d13026
15 changed files with 440 additions and 255 deletions
+3 -3
View File
@@ -10,9 +10,9 @@ LUCI_APP=1
HTTPS_DNS_PROXY=1 HTTPS_DNS_PROXY=1
OWRT_VERSION="current" OWRT_VERSION="current"
RUAB_VERSION="2.1.7-r1" RUAB_VERSION="2.1.8-r1"
RUAB_MOD_LUA_VERSION="2.1.7-r1" RUAB_MOD_LUA_VERSION="2.1.8-r1"
RUAB_LUCI_APP_VERSION="2.1.7-r1" RUAB_LUCI_APP_VERSION="2.1.8-r1"
BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master" BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master"
PKG_DIR="/tmp" PKG_DIR="/tmp"
+1 -1
View File
@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-ruantiblock PKG_NAME:=luci-app-ruantiblock
PKG_VERSION:=2.1.7 PKG_VERSION:=2.1.8
PKG_RELEASE:=1 PKG_RELEASE:=1
LUCI_TITLE:=LuCI support for ruantiblock LUCI_TITLE:=LuCI support for ruantiblock
LUCI_DEPENDS:=+ruantiblock LUCI_DEPENDS:=+ruantiblock
@@ -192,138 +192,88 @@ return view.extend({
s.addremove = false; s.addremove = false;
/* Main settings tab */ /* General settings tab */
s.tab('main_tab', _('Main settings')); s.tab('general_tab', _('General settings'));
// ENABLE_LOGGING // ENABLE_LOGGING
o = s.taboption('main_tab', form.Flag, 'enable_logging', o = s.taboption('general_tab', form.Flag, 'enable_logging',
_('Logging events')); _('Logging events'));
o.rmempty = false; o.rmempty = false;
// update_at_startup // update_at_startup
o = s.taboption('main_tab', form.Flag, 'update_at_startup', o = s.taboption('general_tab', form.Flag, 'update_at_startup',
_('Update at startup')); _('Update at startup'));
o.description = _('Update blacklist after system startup'); o.description = _('Update blacklist after system startup');
o.rmempty = false; o.rmempty = false;
// PROXY_LOCAL_CLIENTS // PROXY_LOCAL_CLIENTS
o = s.taboption('main_tab', form.Flag, 'proxy_local_clients', o = s.taboption('general_tab', form.Flag, 'proxy_local_clients',
_('Apply proxy rules to router application traffic')); _('Apply proxy rules to router application traffic'));
o.rmempty = false; o.rmempty = false;
// NFTSET_CLEAR_SETS // NFTSET_CLEAR_SETS
o = s.taboption('main_tab', form.Flag, 'nftset_clear_sets', o = s.taboption('general_tab', form.Flag, 'nftset_clear_sets',
_('Clean up nftsets before updating blacklist')); _('Clean up nftsets before updating blacklist'));
o.description = _('Reduces RAM consumption during update'); o.description = _('Reduces RAM consumption during update');
o.rmempty = false; o.rmempty = false;
// ALLOWED_HOSTS_MODE // ALLOWED_HOSTS_MODE
o = s.taboption('main_tab', form.ListValue, 'allowed_hosts_mode', o = s.taboption('general_tab', form.ListValue, 'allowed_hosts_mode',
_('Host filter')); _('Host filter'));
o.value('0', _('Disabled')); o.value('0', _('Disabled'));
o.value('1', _('Only listed hosts')); o.value('1', _('Only listed hosts'));
o.value('2', _('All hosts except listed')); o.value('2', _('All hosts except listed'));
o.description = _('Restriction of hosts that are allowed to bypass blocking'); o.description = _('Restriction the local network hosts that are allowed to bypass blocking');
// ALLOWED_HOSTS_LIST // ALLOWED_HOSTS_LIST
o = s.taboption('main_tab', form.DynamicList, 'allowed_hosts_list', o = s.taboption('general_tab', form.DynamicList, 'allowed_hosts_list',
_('IP addresses for host filter')); _('IP addresses for host filter'));
o.datatype = 'ip4addr'; o.datatype = 'ip4addr';
// ENABLE_TMP_DOWNLOADS
/* Tor tab */ o = s.taboption('general_tab', form.Flag, 'enable_tmp_downloads',
_('Safe blacklist update'),
s.tab('tor_tab', _('Tor mode')); _('If update fails, the old blacklist configuration will be retained. Temporary files are used, when updating the blacklist (increases memory consumption).'));
// TOR_TRANS_PORT
o = s.taboption('tor_tab', form.Value, 'tor_trans_port',
_('Transparent proxy port'));
o.rmempty = false;
o.default = tools.defaultConfig.tor_trans_port;
o.datatype = 'port';
// ONION_DNS_ADDR
o = s.taboption('tor_tab', form.Value, 'onion_dns_addr',
_("Optional DNS resolver for '.onion' zone"), '<code>ipaddress#port</code>');
o.rmempty = false;
o.default = tools.defaultConfig.onion_dns_addr;
o.validate = this.validateIpPort;
// Torrc edit dialog
o = s.taboption('tor_tab', form.Button, '_torrc_btn',
_('Tor configuration file'));
o.onclick = () => torrc_edit.show();
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';
/* VPN tab */
s.tab('vpn_tab', _('VPN mode'));
// IF_VPN
o = s.taboption('vpn_tab', widgets.DeviceSelect, 'if_vpn',
_('VPN interface'));
o.multiple = false;
o.noaliases = true;
o.rmempty = false;
o.default = tools.defaultConfig.if_vpn;
// VPN_GW_IP
o = s.taboption('vpn_tab', form.Value, 'vpn_gw_ip',
_('VPN gateway IP address'),
_('If not specified, the VPN interface address is used (or peer address for PPP protocols)'));
o.datatype = 'ip4addr(1)';
// VPN_ROUTE_CHECK
o = s.taboption('vpn_tab', form.ListValue, 'vpn_route_check',
_('Type of adding a VPN rule to the routing table'));
o.value('0', 'hotplug.d');
o.value('1', 'ruab_route_check');
o.description = _('hotplug.d - default option for many VPN applications that supported by OpenWrt.') +
'<br />' +
_('ruab_route_check - script that regularly checks an entry in the routing table.');
/* Tproxy tab */
s.tab('tproxy_tab', _('Transparent proxy mode'));
// T_PROXY_TYPE
o = s.taboption('tproxy_tab', form.ListValue, 't_proxy_type',
_('Proxy type'));
o.value('0', _('redirect'));
o.value('1', _('tproxy'));
o.description = _('Statement in nftables rules');
// T_PROXY_PORT_TCP
o = s.taboption('tproxy_tab', form.Value, 't_proxy_port_tcp',
_('Transparent proxy TCP port'));
o.rmempty = false;
o.default = tools.defaultConfig.t_proxy_port_tcp;
o.datatype = 'port';
// T_PROXY_ALLOW_UDP
o = s.taboption('tproxy_tab', form.Flag, 't_proxy_allow_udp',
_('Send UDP traffic to transparent proxy'));
o.rmempty = false; o.rmempty = false;
o.default = 0; o.default = 0;
// T_PROXY_PORT_UDP // BYPASS_MODE
o = s.taboption('tproxy_tab', form.Value, 't_proxy_port_udp', o = s.taboption('general_tab', form.Flag, 'bypass_mode',
_('Transparent proxy UDP port')); _('Enable exclusion list'), _('List of hosts that are excluded from block bypass (always available directly)'));
o.rmempty = false; o.rmempty = false;
o.default = tools.defaultConfig.t_proxy_port_udp; o.default = 0;
o.datatype = 'port';
// BYPASS_ENTRIES edit dialog
o = s.taboption('general_tab', form.Button, '_bypass_entries_btn',
_('Exclusion list'));
o.onclick = () => bypass_entries_edit.show();
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';
// BYPASS_ENTRIES_DNS
o = s.taboption('general_tab', form.Value, 'bypass_entries_dns',
_('DNS server that is used for the FQDN entries of exclusion list'), '<code>ipaddress[#port]</code>');
o.validate = this.validateIpPort;
/* Blacklist tab */ /* Main blacklist tab */
s.tab('blacklist_tab', _('Blacklist settings')); s.tab('main_blacklist_tab', _('Main blacklist'));
o = s.taboption('main_blacklist_tab', form.SectionValue, 'config', form.NamedSection,
'config');
s.anonymous = true;
s.addremove = false;
ss = o.subsection;
/* Main settings tab */
ss.tab('b_settings_tab', _('Main settings'));
// PROXY_MODE // PROXY_MODE
o = s.taboption('blacklist_tab', form.ListValue, 'proxy_mode', o = ss.taboption('b_settings_tab', form.ListValue, 'proxy_mode',
_('Proxy mode')); _('Proxy mode'));
o.value('1', 'Tor'); o.value('1', 'Tor');
o.value('2', 'VPN'); o.value('2', 'VPN');
@@ -331,7 +281,7 @@ return view.extend({
o.default = tools.defaultConfig.proxy_mode; o.default = tools.defaultConfig.proxy_mode;
// BLLIST_PRESET // BLLIST_PRESET
let bllist_preset = s.taboption('blacklist_tab', form.ListValue, let bllist_preset = ss.taboption('b_settings_tab', form.ListValue,
'bllist_preset', _('Blacklist update mode')); 'bllist_preset', _('Blacklist update mode'));
bllist_preset.description = _('Blacklist sources') + ':'; bllist_preset.description = _('Blacklist sources') + ':';
bllist_preset.value('', _('user entries only')); bllist_preset.value('', _('user entries only'));
@@ -347,7 +297,7 @@ return view.extend({
}); });
// BLLIST_MODULE // BLLIST_MODULE
let bllist_module = s.taboption('blacklist_tab', form.ListValue, let bllist_module = ss.taboption('b_settings_tab', form.ListValue,
'bllist_module', _('Blacklist module') + '*'); 'bllist_module', _('Blacklist module') + '*');
bllist_module.value('', _('disabled')); bllist_module.value('', _('disabled'));
bllist_module.depends({ bllist_preset: new RegExp('^($|' + tools.appName + ')'), '!reverse': true }); bllist_module.depends({ bllist_preset: new RegExp('^($|' + tools.appName + ')'), '!reverse': true });
@@ -355,49 +305,100 @@ return view.extend({
Object.entries(this.parsers).forEach( Object.entries(this.parsers).forEach(
e => bllist_module.value(e[1], e[0])); e => bllist_module.value(e[1], e[0]));
// ENABLE_BLLIST_PROXY
o = s.taboption('blacklist_tab', form.Flag, 'enable_bllist_proxy',
_('Downloading a blacklist via proxy'), _('Turn on if blacklist source is blocked'));
o.rmempty = false;
o.default = 0;
// ENABLE_TMP_DOWNLOADS
o = s.taboption('blacklist_tab', form.Flag, 'enable_tmp_downloads',
_('Safe blacklist update'),
_('If update fails, the old blacklist configuration will be retained. Temporary files are used, when updating the blacklist (increases memory consumption).'));
o.rmempty = false;
o.default = 0;
// ENABLE_FPROXY // ENABLE_FPROXY
o = s.taboption('blacklist_tab', form.Flag, 'enable_fproxy', o = ss.taboption('b_settings_tab', form.Flag, 'enable_fproxy',
_('Enable full proxy mode')); _('Enable full proxy mode'));
o.description = _('All traffic of the specified hosts passes through the proxy, without a blacklist'); o.description = _('All traffic of the specified hosts passes through the proxy, without a blacklist');
o.rmempty = false; o.rmempty = false;
o.default = 0; o.default = 0;
// FPROXY_LIST // FPROXY_LIST
o = s.taboption('blacklist_tab', form.DynamicList, 'fproxy_list', o = ss.taboption('b_settings_tab', form.DynamicList, 'fproxy_list',
_('IP addresses for full proxy mode')); _('IP addresses for full proxy mode'));
o.datatype = 'ip4addr'; o.datatype = 'ip4addr';
// BYPASS_MODE // ENABLE_BLLIST_PROXY
o = s.taboption('blacklist_tab', form.Flag, 'bypass_mode', o = ss.taboption('b_settings_tab', form.Flag, 'enable_bllist_proxy',
_('Enable exclusion list'), _('List of hosts that are excluded from block bypass (always available directly)')); _('Downloading a blacklist via proxy'), _('Turn on if blacklist source is blocked'));
o.rmempty = false; o.rmempty = false;
o.default = 0; o.default = 0;
// BYPASS_ENTRIES edit dialog
o = s.taboption('blacklist_tab', form.Button, '_bypass_entries_btn', /* Tor tab */
_('Exclusion list'));
o.onclick = () => bypass_entries_edit.show(); ss.tab('b_tor_tab', _('Tor mode'));
// TOR_TRANS_PORT
o = ss.taboption('b_tor_tab', form.Value, 'tor_trans_port',
_('Transparent proxy port'));
o.rmempty = false;
o.default = tools.defaultConfig.tor_trans_port;
o.datatype = 'port';
// ONION_DNS_ADDR
o = ss.taboption('b_tor_tab', form.Value, 'onion_dns_addr',
_("Optional DNS resolver for '.onion' zone"), '<code>ipaddress#port</code>');
o.rmempty = false;
o.default = tools.defaultConfig.onion_dns_addr;
o.validate = this.validateIpPort;
// Torrc edit dialog
o = ss.taboption('b_tor_tab', form.Button, '_torrc_btn',
_('Tor configuration file'));
o.onclick = () => torrc_edit.show();
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
// BYPASS_ENTRIES_DNS
o = s.taboption('blacklist_tab', form.Value, 'bypass_entries_dns',
_('DNS server that is used for the FQDN entries of exclusion list'), '<code>ipaddress[#port]</code>');
o.validate = this.validateIpPort;
/* VPN tab */
ss.tab('b_vpn_tab', _('VPN mode'));
// IF_VPN
o = ss.taboption('b_vpn_tab', widgets.DeviceSelect, 'if_vpn',
_('VPN interface'));
o.multiple = false;
o.noaliases = true;
o.rmempty = false;
o.default = tools.defaultConfig.if_vpn;
// VPN_GW_IP
o = ss.taboption('b_vpn_tab', form.Value, 'vpn_gw_ip',
_('VPN gateway IP address'),
_('If not specified, the VPN interface address is used (or peer address for PPP protocols)'));
o.datatype = 'ip4addr(1)';
/* Tproxy tab */
ss.tab('b_tproxy_tab', _('Transparent proxy mode'));
// T_PROXY_TYPE
o = ss.taboption('b_tproxy_tab', form.ListValue, 't_proxy_type',
_('Proxy type'));
o.value('0', _('redirect'));
o.value('1', _('tproxy'));
o.description = _('Statement in nftables rules');
// T_PROXY_PORT_TCP
o = ss.taboption('b_tproxy_tab', form.Value, 't_proxy_port_tcp',
_('Transparent proxy TCP port'));
o.rmempty = false;
o.default = tools.defaultConfig.t_proxy_port_tcp;
o.datatype = 'port';
// T_PROXY_ALLOW_UDP
o = ss.taboption('b_tproxy_tab', form.Flag, 't_proxy_allow_udp',
_('Send UDP traffic to transparent proxy'));
o.rmempty = false;
o.default = 0;
// T_PROXY_PORT_UDP
o = ss.taboption('b_tproxy_tab', form.Value, 't_proxy_port_udp',
_('Transparent proxy UDP port'));
o.rmempty = false;
o.default = tools.defaultConfig.t_proxy_port_udp;
o.datatype = 'port';
if(availableParsers) { if(availableParsers) {
bllist_preset.description += '<br /> ( * - ' + _('requires installed blacklist module') + ' )'; bllist_preset.description += '<br /> ( * - ' + _('requires installed blacklist module') + ' )';
@@ -405,103 +406,103 @@ return view.extend({
/* Parser settings tab */ /* Parser settings tab */
s.tab('parser_settings_tab', _('Module settings')); ss.tab('b_parser_settings_tab', _('Module settings'));
// BLLIST_MIN_ENTRIES // BLLIST_MIN_ENTRIES
o = s.taboption('parser_settings_tab', form.Value, 'bllist_min_entries', o = ss.taboption('b_parser_settings_tab', form.Value, 'bllist_min_entries',
_('Minimum allowed number of entries')); _('Minimum allowed number of entries'));
o.description = _('If less than the specified number of entries are received from the source, then the lists are not updated'); o.description = _('If less than the specified number of entries are received from the source, then the lists are not updated');
o.rmempty = false; o.rmempty = false;
o.datatype = 'uinteger'; o.datatype = 'uinteger';
// BLLIST_FQDN_FILTER // BLLIST_FQDN_FILTER
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_fqdn_filter', o = ss.taboption('b_parser_settings_tab', form.Flag, 'bllist_fqdn_filter',
_('Enable FQDN filter')); _('Enable FQDN filter'));
o.description = _('Pick domains from blacklist by FQDN filter patterns'); o.description = _('Pick domains from blacklist by FQDN filter patterns');
o.rmempty = false; o.rmempty = false;
// BLLIST_FQDN_FILTER_TYPE // BLLIST_FQDN_FILTER_TYPE
o = s.taboption('parser_settings_tab', form.ListValue, 'bllist_fqdn_filter_type', o = ss.taboption('b_parser_settings_tab', form.ListValue, 'bllist_fqdn_filter_type',
_('FQDN filter type')); _('FQDN filter type'));
o.value('0', _('All entries except matching patterns')); o.value('0', _('All entries except matching patterns'));
o.value('1', _('Only entries matching patterns')); o.value('1', _('Only entries matching patterns'));
// BLLIST_FQDN_FILTER_FILE edit dialog // BLLIST_FQDN_FILTER_FILE edit dialog
o = s.taboption('parser_settings_tab', form.Button, '_fqdn_filter_btn', o = ss.taboption('b_parser_settings_tab', form.Button, '_fqdn_filter_btn',
_('FQDN filter')); _('FQDN filter'));
o.onclick = () => fqdn_filter_edit.show(); o.onclick = () => fqdn_filter_edit.show();
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
// BLLIST_SD_LIMIT // BLLIST_SD_LIMIT
o = s.taboption('parser_settings_tab', form.Value, 'bllist_sd_limit', o = ss.taboption('b_parser_settings_tab', form.Value, 'bllist_sd_limit',
_('Subdomains limit')); _('Subdomains limit'));
o.description = _('The number of subdomains in the domain, upon reaching which the entire 2nd level domain is added to the list'); o.description = _('The number of subdomains in the domain, upon reaching which the entire 2nd level domain is added to the list');
o.rmempty = false; o.rmempty = false;
o.datatype = 'uinteger'; o.datatype = 'uinteger';
// BLLIST_GR_EXCLUDED_SLD_FILE edit dialog // BLLIST_GR_EXCLUDED_SLD_FILE edit dialog
o = s.taboption('parser_settings_tab', form.Button, '_gr_excluded_sld_btn', o = ss.taboption('b_parser_settings_tab', form.Button, '_gr_excluded_sld_btn',
_('2nd level domains that are excluded from optimization')); _('2nd level domains that are excluded from optimization'));
o.onclick = () => gr_excluded_sld_edit.show(); o.onclick = () => gr_excluded_sld_edit.show();
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
// BLLIST_ENABLE_IDN // BLLIST_ENABLE_IDN
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_enable_idn', o = ss.taboption('b_parser_settings_tab', form.Flag, 'bllist_enable_idn',
_('Convert cyrillic domains to punycode')); _('Convert cyrillic domains to punycode'));
o.rmempty = false; o.rmempty = false;
// BLLIST_ALT_NSLOOKUP // BLLIST_ALT_NSLOOKUP
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_alt_nslookup', o = ss.taboption('b_parser_settings_tab', form.Flag, 'bllist_alt_nslookup',
_('Use optional DNS resolver')); _('Use optional DNS resolver'));
o.rmempty = false; o.rmempty = false;
// BLLIST_ALT_DNS_ADDR // BLLIST_ALT_DNS_ADDR
o = s.taboption('parser_settings_tab', form.Value, 'bllist_alt_dns_addr', o = ss.taboption('b_parser_settings_tab', form.Value, 'bllist_alt_dns_addr',
_('Optional DNS resolver'), '<code>ipaddress[#port]</code>'); _('Optional DNS resolver'), '<code>ipaddress[#port]</code>');
o.rmempty = false; o.rmempty = false;
o.validate = this.validateIpPort; o.validate = this.validateIpPort;
// BLLIST_IP_FILTER // BLLIST_IP_FILTER
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_ip_filter', o = ss.taboption('b_parser_settings_tab', form.Flag, 'bllist_ip_filter',
_('Enable IP filter')); _('Enable IP filter'));
o.description = _('Pick IP addresses from blacklist by IP filter patterns'); o.description = _('Pick IP addresses from blacklist by IP filter patterns');
o.rmempty = false; o.rmempty = false;
// BLLIST_IP_FILTER_TYPE // BLLIST_IP_FILTER_TYPE
o = s.taboption('parser_settings_tab', form.ListValue, 'bllist_ip_filter_type', o = ss.taboption('b_parser_settings_tab', form.ListValue, 'bllist_ip_filter_type',
_('IP filter type')); _('IP filter type'));
o.value('0', _('All entries except matching patterns')); o.value('0', _('All entries except matching patterns'));
o.value('1', _('Only entries matching patterns')); o.value('1', _('Only entries matching patterns'));
// BLLIST_IP_FILTER_FILE edit dialog // BLLIST_IP_FILTER_FILE edit dialog
o = s.taboption('parser_settings_tab', form.Button, '_ip_filter_btn', o = ss.taboption('b_parser_settings_tab', form.Button, '_ip_filter_btn',
_('IP filter')); _('IP filter'));
o.onclick = () => ip_filter_edit.show(); o.onclick = () => ip_filter_edit.show();
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
// BLLIST_IP_LIMIT // BLLIST_IP_LIMIT
o = s.taboption('parser_settings_tab', form.Value, 'bllist_ip_limit', _('IP limit')); o = ss.taboption('b_parser_settings_tab', form.Value, 'bllist_ip_limit', _('IP limit'));
o.description = _("The number of IP addresses in the subnet, upon reaching which the entire '/24' subnet is added to the list"); o.description = _("The number of IP addresses in the subnet, upon reaching which the entire '/24' subnet is added to the list");
o.rmempty = false; o.rmempty = false;
o.datatype = 'uinteger'; o.datatype = 'uinteger';
// BLLIST_GR_EXCLUDED_NETS_FILE edit dialog // BLLIST_GR_EXCLUDED_NETS_FILE edit dialog
o = s.taboption('parser_settings_tab', form.Button, '_gr_excluded_nets_btn', o = ss.taboption('b_parser_settings_tab', form.Button, '_gr_excluded_nets_btn',
_('IP subnet patterns (/24) that are excluded from optimization')); _('IP subnet patterns (/24) that are excluded from optimization'));
o.onclick = () => gr_excluded_nets_edit.show(); o.onclick = () => gr_excluded_nets_edit.show();
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
// BLLIST_SUMMARIZE_IP // BLLIST_SUMMARIZE_IP
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_summarize_ip', o = ss.taboption('b_parser_settings_tab', form.Flag, 'bllist_summarize_ip',
_('Summarize IP ranges')); _('Summarize IP ranges'));
o.rmempty = false; o.rmempty = false;
// BLLIST_SUMMARIZE_CIDR // BLLIST_SUMMARIZE_CIDR
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_summarize_cidr', o = ss.taboption('b_parser_settings_tab', form.Flag, 'bllist_summarize_cidr',
_("Summarize '/24' networks")); _("Summarize '/24' networks"));
o.rmempty = false; o.rmempty = false;
}; };
@@ -525,6 +526,12 @@ return view.extend({
ss.tab('u_main_tab', _('Main settings')); ss.tab('u_main_tab', _('Main settings'));
// description
o = ss.taboption('u_main_tab', form.Value, 'u_description',
_("Description"));
o.datatype = 'maxlength(50)';
o.modalonly = null;
// U_ENABLED // U_ENABLED
o = ss.taboption('u_main_tab', form.Flag, 'u_enabled', o = ss.taboption('u_main_tab', form.Flag, 'u_enabled',
_('Enabled'), _('Enabled'),
@@ -534,12 +541,6 @@ return view.extend({
o.editable = true; o.editable = true;
o.modalonly = false; o.modalonly = false;
// description
o = ss.taboption('u_main_tab', form.Value, 'u_description',
_("Description"));
o.datatype = 'maxlength(100)';
o.modalonly = null;
// U_PROXY_MODE // U_PROXY_MODE
o = ss.taboption('u_main_tab', form.ListValue, 'u_proxy_mode', o = ss.taboption('u_main_tab', form.ListValue, 'u_proxy_mode',
_('Proxy mode')); _('Proxy mode'));
@@ -615,6 +616,7 @@ return view.extend({
o.value('0', _('redirect')); o.value('0', _('redirect'));
o.value('1', _('tproxy')); o.value('1', _('tproxy'));
o.description = _('Statement in nftables rules'); o.description = _('Statement in nftables rules');
o.modalonly = true;
// U_T_PROXY_PORT_TCP // U_T_PROXY_PORT_TCP
o = ss.taboption('u_tproxy_tab', form.Value, 'u_t_proxy_port_tcp', o = ss.taboption('u_tproxy_tab', form.Value, 'u_t_proxy_port_tcp',
@@ -655,9 +657,6 @@ return view.extend({
'<br /><code>#comment<br />domain.net<br />sub.domain.com 8.8.8.8<br />sub.domain.com 8.8.8.8#53<br />74.125.131.19<br />74.125.0.0/16</code>' '<br /><code>#comment<br />domain.net<br />sub.domain.com 8.8.8.8<br />sub.domain.com 8.8.8.8#53<br />74.125.131.19<br />74.125.0.0/16</code>'
); );
// DEBUG
console.log(tools.userListsDir + '/' + s.section);
o.modalonly = true; o.modalonly = true;
// U_ENTRIES_REMOTE // U_ENTRIES_REMOTE
@@ -681,6 +680,7 @@ return view.extend({
let map_promise = m.render(); let map_promise = m.render();
map_promise.then(node => node.classList.add('fade-in')); map_promise.then(node => node.classList.add('fade-in'));
return map_promise; return map_promise;
}, },
+8 -5
View File
@@ -58,9 +58,6 @@ msgstr "Автообновление"
msgid "Blacklist module" msgid "Blacklist module"
msgstr "Модуль блэклиста" msgstr "Модуль блэклиста"
msgid "Blacklist settings"
msgstr "Настройки блэклиста"
msgid "Blacklist sources" msgid "Blacklist sources"
msgstr "Источники блэклиста" msgstr "Источники блэклиста"
@@ -194,6 +191,9 @@ msgstr "Не удалось получить статус инициализац
msgid "Filter settings" msgid "Filter settings"
msgstr "Настройки фильтра" msgstr "Настройки фильтра"
msgid "General settings"
msgstr "Общие настройки"
msgid "Get all entries" msgid "Get all entries"
msgstr "Все записи" msgstr "Все записи"
@@ -278,6 +278,9 @@ msgstr "Уровни логирования"
msgid "Logread not found" msgid "Logread not found"
msgstr "Logread не найден" msgstr "Logread не найден"
msgid "Main blacklist"
msgstr "Основной блэклист"
msgid "Main settings" msgid "Main settings"
msgstr "Основные настройки" msgstr "Основные настройки"
@@ -403,8 +406,8 @@ msgstr "Обновить лог"
msgid "Reset" msgid "Reset"
msgstr "Сбросить" msgstr "Сбросить"
msgid "Restriction of hosts that are allowed to bypass blocking" msgid "Restriction the local network hosts that are allowed to bypass blocking"
msgstr "Ограничение хостов, которым разрешено обходить блокировки" msgstr "Ограничение хостов локальной сети, которым разрешено обходить блокировки"
msgid "Ruantiblock" msgid "Ruantiblock"
msgstr "Ruantiblock" msgstr "Ruantiblock"
@@ -43,9 +43,6 @@ msgstr ""
msgid "Blacklist module" msgid "Blacklist module"
msgstr "" msgstr ""
msgid "Blacklist settings"
msgstr ""
msgid "Blacklist sources" msgid "Blacklist sources"
msgstr "" msgstr ""
@@ -179,6 +176,9 @@ msgstr ""
msgid "Filter settings" msgid "Filter settings"
msgstr "" msgstr ""
msgid "General settings"
msgstr ""
msgid "Get all entries" msgid "Get all entries"
msgstr "" msgstr ""
@@ -260,6 +260,9 @@ msgstr ""
msgid "Logread not found" msgid "Logread not found"
msgstr "" msgstr ""
msgid "Main blacklist"
msgstr ""
msgid "Main settings" msgid "Main settings"
msgstr "" msgstr ""
@@ -373,7 +376,7 @@ msgstr ""
msgid "Reset" msgid "Reset"
msgstr "" msgstr ""
msgid "Restriction of hosts that are allowed to bypass blocking" msgid "Restriction the local network hosts that are allowed to bypass blocking"
msgstr "" msgstr ""
msgid "Ruantiblock" msgid "Ruantiblock"
+1 -1
View File
@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock-mod-lua PKG_NAME:=ruantiblock-mod-lua
PKG_VERSION:=2.1.7 PKG_VERSION:=2.1.8
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt> PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
@@ -1,5 +1,5 @@
--[[ --[[
(с) 2020 gSpot <https://github.com/gSpotx2f> (с) 2020 gSpot <https://github.com/gSpotx2f/iptool-lua>
Some functions for manipulating IPv4 addresses. Some functions for manipulating IPv4 addresses.
@@ -98,6 +98,7 @@ local function summarize_address_range(first, last)
end end
local nbits = math.min(count_righthand_zero_bits(first, ip_bits), bit_length(last - first + 1) - 1) local nbits = math.min(count_righthand_zero_bits(first, ip_bits), bit_length(last - first + 1) - 1)
ret_val = {[1] = first, [2] = (ip_bits - nbits)} ret_val = {[1] = first, [2] = (ip_bits - nbits)}
first = first + lshift(1, nbits) first = first + lshift(1, nbits)
if first - 1 == ipv4_capacity then if first - 1 == ipv4_capacity then
return return
@@ -154,6 +155,50 @@ local function get_supernet(network, new_prefix)
return band(network_address, lshift(netmask, diff_prefixlen)) return band(network_address, lshift(netmask, diff_prefixlen))
end end
local function overlap_ip(ip, network)
local network_address, prefixlen
if type(network) == "string" then
network_address, prefixlen = get_network_addr(network)
elseif type(network) == "table" then
network_address, prefixlen = network[1], network[2]
else
return
end
ip = ip_to_int(ip)
if ip == nil then
return
end
local offset = ipv4_length - prefixlen
return (rshift(ip, offset) == rshift(network_address, offset))
end
local function check_network(net)
local network_address, prefixlen
if type(net) == "string" then
network_address, prefixlen = get_network_addr(net)
elseif type(net) == "table" then
network_address, prefixlen = net[1], net[2]
else
return
end
return network_address, prefixlen
end
local function overlap_net(subnet, network)
local network_address_1, prefixlen_1 = check_network(subnet)
local network_address_2, prefixlen_2 = check_network(network)
if (network_address_1 == nil or prefixlen_1 == nil or
network_address_2 == nil or prefixlen_2 == nil) then
return
end
if network_address_1 == network_address_2 then
return true
end
local offset = ipv4_length - math.min(prefixlen_1, prefixlen_2)
return (rshift(network_address_1, offset) == rshift(network_address_2, offset))
end
return { return {
validate_ip = validate_ip, validate_ip = validate_ip,
ip_to_int = ip_to_int, ip_to_int = ip_to_int,
@@ -162,4 +207,6 @@ return {
get_network_addr = get_network_addr, get_network_addr = get_network_addr,
hosts_from_network = hosts_from_network, hosts_from_network = hosts_from_network,
get_supernet = get_supernet, get_supernet = get_supernet,
overlap_ip = overlap_ip,
overlap_net = overlap_net,
} }
@@ -83,6 +83,8 @@ local Config = Class(nil, {
["BLLIST_FQDN_EXCLUDED_FILE"] = true, ["BLLIST_FQDN_EXCLUDED_FILE"] = true,
["BLLIST_IP_EXCLUDED_ENABLE"] = true, ["BLLIST_IP_EXCLUDED_ENABLE"] = true,
["BLLIST_IP_EXCLUDED_FILE"] = true, ["BLLIST_IP_EXCLUDED_FILE"] = true,
["BLLIST_CIDR_EXCLUDED_ENABLE"] = true,
["BLLIST_CIDR_EXCLUDED_FILE"] = true,
}, },
BLLIST_FQDN_FILTER_PATTERNS = {}, BLLIST_FQDN_FILTER_PATTERNS = {},
BLLIST_IP_FILTER_PATTERNS = {}, BLLIST_IP_FILTER_PATTERNS = {},
@@ -91,6 +93,7 @@ local Config = Class(nil, {
BLLIST_GR_EXCLUDED_NETS_PATTERNS = {}, BLLIST_GR_EXCLUDED_NETS_PATTERNS = {},
BLLIST_FQDN_EXCLUDED_ITEMS = {}, BLLIST_FQDN_EXCLUDED_ITEMS = {},
BLLIST_IP_EXCLUDED_ITEMS = {}, BLLIST_IP_EXCLUDED_ITEMS = {},
BLLIST_CIDR_EXCLUDED_ITEMS = {},
-- iconv type: standalone iconv or lua-iconv (standalone, lua) -- iconv type: standalone iconv or lua-iconv (standalone, lua)
ICONV_TYPE = "standalone", ICONV_TYPE = "standalone",
-- standalone iconv -- standalone iconv
@@ -99,7 +102,7 @@ local Config = Class(nil, {
encoding = "UTF-8", encoding = "UTF-8",
site_encoding = "", site_encoding = "",
http_send_headers = { http_send_headers = {
["User-Agent"] = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/130.0", ["User-Agent"] = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/142.0",
}, },
connect_timeout = nil, connect_timeout = nil,
}) })
@@ -168,60 +171,7 @@ Config.BLLIST_SUMMARIZE_IP = remap_bool(Config.BLLIST_SUMMARIZE_IP)
Config.BLLIST_SUMMARIZE_CIDR = remap_bool(Config.BLLIST_SUMMARIZE_CIDR) Config.BLLIST_SUMMARIZE_CIDR = remap_bool(Config.BLLIST_SUMMARIZE_CIDR)
Config.BLLIST_FQDN_EXCLUDED_ENABLE = remap_bool(Config.BLLIST_FQDN_EXCLUDED_ENABLE) Config.BLLIST_FQDN_EXCLUDED_ENABLE = remap_bool(Config.BLLIST_FQDN_EXCLUDED_ENABLE)
Config.BLLIST_IP_EXCLUDED_ENABLE = remap_bool(Config.BLLIST_IP_EXCLUDED_ENABLE) Config.BLLIST_IP_EXCLUDED_ENABLE = remap_bool(Config.BLLIST_IP_EXCLUDED_ENABLE)
Config.BLLIST_CIDR_EXCLUDED_ENABLE = remap_bool(Config.BLLIST_CIDR_EXCLUDED_ENABLE)
-- Loading filters
function Config:load_filter_files()
function load_file(file, t, is_array)
local file_handler = io.open(file, "r")
if file_handler then
for line in file_handler:lines() do
if #line > 0 and line:match("^[^#]") then
if is_array then
t[#t + 1] = line
else
t[line] = true
end
end
end
file_handler:close()
end
end
if self.BLLIST_FQDN_FILTER then
load_file(self.BLLIST_FQDN_FILTER_FILE, self.BLLIST_FQDN_FILTER_PATTERNS)
end
if self.BLLIST_IP_FILTER then
load_file(self.BLLIST_IP_FILTER_FILE, self.BLLIST_IP_FILTER_PATTERNS)
end
if self.BLLIST_GR_EXCLUDED_SLD_FILE then
load_file(self.BLLIST_GR_EXCLUDED_SLD_FILE, self.BLLIST_GR_EXCLUDED_SLD_PATTERNS)
end
if self.BLLIST_GR_EXCLUDED_SLD_MASKS_FILE then
load_file(self.BLLIST_GR_EXCLUDED_SLD_MASKS_FILE, self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS, true)
end
if self.BLLIST_GR_EXCLUDED_NETS_FILE then
load_file(self.BLLIST_GR_EXCLUDED_NETS_FILE, self.BLLIST_GR_EXCLUDED_NETS_PATTERNS)
end
if self.BLLIST_FQDN_EXCLUDED_ENABLE then
load_file(self.BLLIST_FQDN_EXCLUDED_FILE, self.BLLIST_FQDN_EXCLUDED_ITEMS)
end
if self.BLLIST_IP_EXCLUDED_ENABLE then
load_file(self.BLLIST_IP_EXCLUDED_FILE, self.BLLIST_IP_EXCLUDED_ITEMS)
end
end
function Config:check_sld_masks(sld)
if #self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS > 0 then
for _, pattern in ipairs(self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS) do
if sld:find(pattern) then
return true
end
end
end
return false
end
Config:load_filter_files()
-- Importing packages -- Importing packages
@@ -250,6 +200,7 @@ end
if not it then if not it then
Config.BLLIST_SUMMARIZE_CIDR = false Config.BLLIST_SUMMARIZE_CIDR = false
Config.BLLIST_SUMMARIZE_IP = false Config.BLLIST_SUMMARIZE_IP = false
Config.BLLIST_CIDR_EXCLUDED_ENABLE = false
end end
--[[ --[[
local zlib = prequire("zlib") local zlib = prequire("zlib")
@@ -272,6 +223,113 @@ else
error("Config.ICONV_TYPE should be either 'lua' or 'standalone'") error("Config.ICONV_TYPE should be either 'lua' or 'standalone'")
end end
-- Loading filters
function Config:load_filter_files()
function load_file(file, t, is_array, func)
local file_handler = io.open(file, "r")
if file_handler then
for line in file_handler:lines() do
if #line > 0 and not line:match("^#") then
if func then
line = func(line)
end
if line ~= nil then
if is_array then
t[#t + 1] = line
else
t[line] = true
end
end
end
end
file_handler:close()
end
end
if self.BLLIST_FQDN_FILTER then
load_file(self.BLLIST_FQDN_FILTER_FILE, self.BLLIST_FQDN_FILTER_PATTERNS, true)
end
if self.BLLIST_IP_FILTER then
load_file(self.BLLIST_IP_FILTER_FILE, self.BLLIST_IP_FILTER_PATTERNS, true)
end
if self.BLLIST_GR_EXCLUDED_SLD_FILE then
load_file(self.BLLIST_GR_EXCLUDED_SLD_FILE, self.BLLIST_GR_EXCLUDED_SLD_PATTERNS)
end
if self.BLLIST_GR_EXCLUDED_SLD_MASKS_FILE then
load_file(self.BLLIST_GR_EXCLUDED_SLD_MASKS_FILE, self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS, true)
end
if self.BLLIST_GR_EXCLUDED_NETS_FILE then
load_file(self.BLLIST_GR_EXCLUDED_NETS_FILE, self.BLLIST_GR_EXCLUDED_NETS_PATTERNS)
end
if self.BLLIST_FQDN_EXCLUDED_ENABLE then
load_file(self.BLLIST_FQDN_EXCLUDED_FILE, self.BLLIST_FQDN_EXCLUDED_ITEMS)
end
if self.BLLIST_IP_EXCLUDED_ENABLE then
load_file(self.BLLIST_IP_EXCLUDED_FILE, self.BLLIST_IP_EXCLUDED_ITEMS)
end
if self.BLLIST_CIDR_EXCLUDED_ENABLE then
load_file(self.BLLIST_CIDR_EXCLUDED_FILE, self.BLLIST_CIDR_EXCLUDED_ITEMS, true,
function(l)
if l:match("^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?/%d%d?$") then
local a, p = it.get_network_addr(l)
if a ~= nil and p ~= nil then
return { [1] = a, [2] = p }
end
end
return
end
)
end
end
function Config:check_filter(str, filter_patterns, reverse)
if filter_patterns and str then
for _, pattern in ipairs(filter_patterns) do
if str:match(pattern) then
return not reverse
end
end
end
return reverse
end
function Config:check_sld_masks(sld)
if #self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS > 0 then
for _, pattern in ipairs(self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS) do
if sld:find(pattern) then
return true
end
end
end
return false
end
function Config:check_cidr_overlap_ip(ip)
if #self.BLLIST_CIDR_EXCLUDED_ITEMS > 0 then
for _, net in ipairs(self.BLLIST_CIDR_EXCLUDED_ITEMS) do
if it.overlap_ip(ip, net) then
return true
end
end
end
return false
end
function Config:check_cidr_overlap_net(ip)
if #self.BLLIST_CIDR_EXCLUDED_ITEMS > 0 then
for _, net in ipairs(self.BLLIST_CIDR_EXCLUDED_ITEMS) do
if it.overlap_net(ip, net) then
return true
end
end
end
return false
end
Config:load_filter_files()
------------------------------ Classes ------------------------------- ------------------------------ Classes -------------------------------
local BlackListParser = Class(Config, { local BlackListParser = Class(Config, {
@@ -323,17 +381,6 @@ function BlackListParser:convert_to_punycode(input)
return input and (idn.encode(input)) return input and (idn.encode(input))
end end
function BlackListParser:check_filter(str, filter_patterns, reverse)
if filter_patterns and str then
for pattern in pairs(filter_patterns) do
if str:match(pattern) then
return not reverse
end
end
end
return reverse
end
function BlackListParser:get_subnet(ip) function BlackListParser:get_subnet(ip)
return ip:match("^(%d+%.%d+%.%d+%.)%d+$") return ip:match("^(%d+%.%d+%.%d+%.)%d+$")
end end
@@ -707,6 +754,23 @@ function OptimizeConfig:new(t)
return instance return instance
end end
function OptimizeConfig:_exclude_nets()
local ip_table = {}
for ip, subnet in pairs(self.ip_table) do
if not self:check_cidr_overlap_ip(ip) then
ip_table[ip] = subnet
end
end
self.ip_table = ip_table
local cidr_table = {}
for net in pairs(self.cidr_table) do
if not self:check_cidr_overlap_net(net) then
cidr_table[net] = true
end
end
self.cidr_table = cidr_table
end
function OptimizeConfig:_remove_subdomains() function OptimizeConfig:_remove_subdomains()
local tld_table = {} local tld_table = {}
for fqdn, sld in pairs(self.fqdn_table) do for fqdn, sld in pairs(self.fqdn_table) do
@@ -792,6 +856,9 @@ function OptimizeConfig:optimize()
self:_union(self.fqdn_table, i.fqdn_table) self:_union(self.fqdn_table, i.fqdn_table)
self:_union(self.sld_table, i.sld_table) self:_union(self.sld_table, i.sld_table)
end end
if self.BLLIST_CIDR_EXCLUDED_ENABLE then
self:_exclude_nets()
end
self:_remove_subdomains() self:_remove_subdomains()
self:_optimize_fqdn_table() self:_optimize_fqdn_table()
self:_optimize_ip_table() self:_optimize_ip_table()
@@ -1146,6 +1213,7 @@ if parser_classes then
for _, i in ipairs(parser_instances) do for _, i in ipairs(parser_instances) do
ret_list[i:run()] = true ret_list[i:run()] = true
end end
local return_sum = 0 local return_sum = 0
for i, _ in pairs(ret_list) do for i, _ in pairs(ret_list) do
return_sum = return_sum + i return_sum = return_sum + i
@@ -1161,4 +1229,5 @@ if parser_classes then
else else
error("Wrong configuration! (Config.BLLIST_MODE, Config.BLLIST_SOURCE)") error("Wrong configuration! (Config.BLLIST_MODE, Config.BLLIST_SOURCE)")
end end
os.exit(ret_list[1] and 1 or (ret_list[2] and 2 or 0)) os.exit(ret_list[1] and 1 or (ret_list[2] and 2 or 0))
+1 -1
View File
@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock-mod-py PKG_NAME:=ruantiblock-mod-py
PKG_VERSION:=2.1.7 PKG_VERSION:=2.1.8
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt> PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
@@ -8,7 +8,8 @@
""" """
from contextlib import contextmanager from contextlib import contextmanager
from ipaddress import IPv4Address, IPv4Network, summarize_address_range from ipaddress import (IPv4Address, IPv4Network, summarize_address_range,
AddressValueError, NetmaskValueError)
import os import os
import re import re
import socket import socket
@@ -68,14 +69,17 @@ class Config:
"BLLIST_FQDN_EXCLUDED_FILE", "BLLIST_FQDN_EXCLUDED_FILE",
"BLLIST_IP_EXCLUDED_ENABLE", "BLLIST_IP_EXCLUDED_ENABLE",
"BLLIST_IP_EXCLUDED_FILE", "BLLIST_IP_EXCLUDED_FILE",
"BLLIST_CIDR_EXCLUDED_ENABLE",
"BLLIST_CIDR_EXCLUDED_FILE",
] ]
BLLIST_FQDN_FILTER_PATTERNS = set() BLLIST_FQDN_FILTER_PATTERNS = []
BLLIST_IP_FILTER_PATTERNS = set() BLLIST_IP_FILTER_PATTERNS = []
BLLIST_GR_EXCLUDED_SLD_PATTERNS = set() BLLIST_GR_EXCLUDED_SLD_PATTERNS = set()
BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS = [] BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS = []
BLLIST_GR_EXCLUDED_NETS_PATTERNS = set() BLLIST_GR_EXCLUDED_NETS_PATTERNS = set()
BLLIST_FQDN_EXCLUDED_ITEMS = set() BLLIST_FQDN_EXCLUDED_ITEMS = set()
BLLIST_IP_EXCLUDED_ITEMS = set() BLLIST_IP_EXCLUDED_ITEMS = set()
BLLIST_CIDR_EXCLUDED_ITEMS = []
@classmethod @classmethod
def _load_config(cls, cfg_dict): def _load_config(cls, cfg_dict):
@@ -119,15 +123,20 @@ class Config:
}) })
@classmethod @classmethod
def _load_filter(cls, file_path, filter_patterns, is_array=False): def _load_filter(cls, file_path, filter_patterns, is_array=False, func=None):
try: try:
with open(file_path, "rt") as file_handler: with open(file_path, "rt") as file_handler:
for line in file_handler: for line in file_handler:
if line and re.match("[^#]", line): if line and not re.match(r"(^#|^$)", line):
value = line.strip()
if func:
value = func(value)
if value is None:
continue
if is_array: if is_array:
filter_patterns.append(line.strip()) filter_patterns.append(value)
else: else:
filter_patterns.add(line.strip()) filter_patterns.add(value)
except OSError: except OSError:
pass pass
@@ -135,13 +144,13 @@ class Config:
def load_fqdn_filter(cls, file_path=None): def load_fqdn_filter(cls, file_path=None):
if cls.BLLIST_FQDN_FILTER: if cls.BLLIST_FQDN_FILTER:
cls._load_filter(file_path or cls.BLLIST_FQDN_FILTER_FILE, cls._load_filter(file_path or cls.BLLIST_FQDN_FILTER_FILE,
cls.BLLIST_FQDN_FILTER_PATTERNS) cls.BLLIST_FQDN_FILTER_PATTERNS, is_array=True)
@classmethod @classmethod
def load_ip_filter(cls, file_path=None): def load_ip_filter(cls, file_path=None):
if cls.BLLIST_IP_FILTER: if cls.BLLIST_IP_FILTER:
cls._load_filter(file_path or cls.BLLIST_IP_FILTER_FILE, cls._load_filter(file_path or cls.BLLIST_IP_FILTER_FILE,
cls.BLLIST_IP_FILTER_PATTERNS) cls.BLLIST_IP_FILTER_PATTERNS, is_array=True)
@classmethod @classmethod
def load_gr_excluded_sld(cls, file_path=None): def load_gr_excluded_sld(cls, file_path=None):
@@ -173,6 +182,30 @@ class Config:
cls._load_filter(file_path or cls.BLLIST_IP_EXCLUDED_FILE, cls._load_filter(file_path or cls.BLLIST_IP_EXCLUDED_FILE,
cls.BLLIST_IP_EXCLUDED_ITEMS) cls.BLLIST_IP_EXCLUDED_ITEMS)
@staticmethod
def makeIPv4Network(s):
net = None
try:
net = IPv4Network(s)
except (AddressValueError, NetmaskValueError):
pass
return net
@classmethod
def load_cidr_excluded(cls, file_path=None):
if cls.BLLIST_CIDR_EXCLUDED_ENABLE:
cls._load_filter(file_path or cls.BLLIST_CIDR_EXCLUDED_FILE,
cls.BLLIST_CIDR_EXCLUDED_ITEMS, is_array=True,
func=cls.makeIPv4Network)
@staticmethod
def _check_filter(string, filter_patterns, reverse=False):
if filter_patterns and string:
for pattern in filter_patterns:
if pattern and pattern.search(string):
return not reverse
return reverse
def check_sld_masks(self, sld): def check_sld_masks(self, sld):
if self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS: if self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS:
for pattern in self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS: for pattern in self.BLLIST_GR_EXCLUDED_SLD_MASKS_PATTERNS:
@@ -180,6 +213,18 @@ class Config:
return True return True
return False return False
def check_cidr_overlap(self, ip):
if self.BLLIST_CIDR_EXCLUDED_ITEMS:
try:
ip_obj = IPv4Network(ip)
except (AddressValueError, NetmaskValueError):
pass
else:
for net in self.BLLIST_CIDR_EXCLUDED_ITEMS:
if net.overlaps(ip_obj):
return True
return False
class ParserError(Exception): class ParserError(Exception):
def __init__(self, reason=None): def __init__(self, reason=None):
@@ -212,7 +257,7 @@ class BlackListParser(Config):
self.output_fqdn_count = 0 self.output_fqdn_count = 0
self.ssl_unverified = False self.ssl_unverified = False
self.send_headers_dict = { self.send_headers_dict = {
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/130.0", "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/142.0",
} }
### Proxies (ex.: self.proxies = {"http": "http://192.168.0.1:8080", "https": "http://192.168.0.1:8080"}) ### Proxies (ex.: self.proxies = {"http": "http://192.168.0.1:8080", "https": "http://192.168.0.1:8080"})
self.proxies = None self.proxies = None
@@ -303,14 +348,6 @@ class BlackListParser(Config):
except UnicodeError: except UnicodeError:
pass pass
@staticmethod
def _check_filter(string, filter_patterns, reverse=False):
if filter_patterns and string:
for pattern in filter_patterns:
if pattern and pattern.search(string):
return not reverse
return reverse
def _get_subnet(self, ip_addr): def _get_subnet(self, ip_addr):
regexp_obj = self.ip_pattern.fullmatch(ip_addr) regexp_obj = self.ip_pattern.fullmatch(ip_addr)
return regexp_obj.group(1) if regexp_obj else None return regexp_obj.group(1) if regexp_obj else None
@@ -511,6 +548,19 @@ class OptimizeConfig(Config):
self.ip_count = 0 self.ip_count = 0
self.output_fqdn_count = 0 self.output_fqdn_count = 0
def _exclude_nets(self):
if self.BLLIST_CIDR_EXCLUDED_ENABLE:
ip_dict = {}
for ip, subnet in self.ip_dict.items():
if not self.check_cidr_overlap(ip):
ip_dict[ip] = subnet
self.ip_dict = ip_dict
cidr_set = set()
for net in self.cidr_set:
if not self.check_cidr_overlap(net):
cidr_set.add(net)
self.cidr_set = cidr_set
def _remove_subdomains(self): def _remove_subdomains(self):
tld_dict = {} tld_dict = {}
for fqdn, sld in self.fqdn_dict.items(): for fqdn, sld in self.fqdn_dict.items():
@@ -571,6 +621,7 @@ class OptimizeConfig(Config):
self.ip_subnet_dict.update(i.ip_subnet_dict) self.ip_subnet_dict.update(i.ip_subnet_dict)
self.fqdn_dict.update(i.fqdn_dict) self.fqdn_dict.update(i.fqdn_dict)
self.sld_dict.update(i.sld_dict) self.sld_dict.update(i.sld_dict)
self._exclude_nets()
self._remove_subdomains() self._remove_subdomains()
self._optimize_fqdn_dict() self._optimize_fqdn_dict()
self._optimize_ip_dict() self._optimize_ip_dict()
@@ -831,6 +882,7 @@ if __name__ == "__main__":
Config.load_gr_excluded_nets() Config.load_gr_excluded_nets()
Config.load_fqdn_excluded() Config.load_fqdn_excluded()
Config.load_ip_excluded() Config.load_ip_excluded()
Config.load_cidr_excluded()
parsers_dict = { parsers_dict = {
"ip": {"rublacklist": [RblIp], "zapret-info": [ZiIp], "antifilter": [AfIp], "fz": [FzIp], "ruantiblock": [Ra]}, "ip": {"rublacklist": [RblIp], "zapret-info": [ZiIp], "antifilter": [AfIp], "fz": [FzIp], "ruantiblock": [Ra]},
"fqdn": {"rublacklist": [RblFQDN, RblDPI], "zapret-info": [ZiFQDN], "antifilter": [AfFQDN], "fz": [FzFQDN], "ruantiblock": [Ra]}, "fqdn": {"rublacklist": [RblFQDN, RblDPI], "zapret-info": [ZiFQDN], "antifilter": [AfFQDN], "fz": [FzFQDN], "ruantiblock": [Ra]},
+1 -1
View File
@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock PKG_NAME:=ruantiblock
PKG_VERSION:=2.1.7 PKG_VERSION:=2.1.8
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt> PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
@@ -121,6 +121,10 @@ BLLIST_IP_FILTER_FILE="/etc/ruantiblock/ip_filter"
BLLIST_IP_EXCLUDED_ENABLE=0 BLLIST_IP_EXCLUDED_ENABLE=0
### Файл с записями IP/CIDR для опции BLLIST_IP_EXCLUDED_ENABLE ### Файл с записями IP/CIDR для опции BLLIST_IP_EXCLUDED_ENABLE
BLLIST_IP_EXCLUDED_FILE="/etc/ruantiblock/ip_excluded" BLLIST_IP_EXCLUDED_FILE="/etc/ruantiblock/ip_excluded"
### Включение опции исключения IP входящих в подсети CIDR
BLLIST_CIDR_EXCLUDED_ENABLE=0
### Файл с записями IP/CIDR для опции BLLIST_CIDR_EXCLUDED_ENABLE
BLLIST_CIDR_EXCLUDED_FILE="/etc/ruantiblock/cidr_excluded"
### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - выкл) ### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - выкл)
BLLIST_SD_LIMIT=16 BLLIST_SD_LIMIT=16
### Файл с SLD не подлежащими группировке при оптимизации (одна запись на строку) ### Файл с SLD не подлежащими группировке при оптимизации (одна запись на строку)
+4
View File
@@ -157,6 +157,10 @@ export BLLIST_IP_FILTER_FILE="${CONFIG_DIR}/ip_filter"
export BLLIST_IP_EXCLUDED_ENABLE=0 export BLLIST_IP_EXCLUDED_ENABLE=0
### Файл с записями IP/CIDR для опции BLLIST_IP_EXCLUDED_ENABLE ### Файл с записями IP/CIDR для опции BLLIST_IP_EXCLUDED_ENABLE
export BLLIST_IP_EXCLUDED_FILE="${CONFIG_DIR}/ip_excluded" export BLLIST_IP_EXCLUDED_FILE="${CONFIG_DIR}/ip_excluded"
### Включение опции исключения IP входящих в подсети CIDR
export BLLIST_CIDR_EXCLUDED_ENABLE=0
### Файл с записями IP/CIDR для опции BLLIST_CIDR_EXCLUDED_ENABLE
export BLLIST_CIDR_EXCLUDED_FILE="${CONFIG_DIR}/cidr_excluded"
### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - выкл) ### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - выкл)
export BLLIST_SD_LIMIT=0 export BLLIST_SD_LIMIT=0
### Файл с SLD не подлежащими группировке при оптимизации (одна запись на строку) ### Файл с SLD не подлежащими группировке при оптимизации (одна запись на строку)
@@ -22,8 +22,8 @@ CheckIfaceStatus() {
} }
VpnRouteInstanceStatus() { VpnRouteInstanceStatus() {
local _vpn_route_table_id=$1 local _route_table_id=$1
[ -n "$($IP_CMD route show table $_vpn_route_table_id 2> /dev/null)" ] && return 0 $IP_CMD route show table $_route_table_id 2> /dev/null | $AWK_CMD 'BEGIN {code=1} /^(default|local)/ {code=0} END {exit code}' && return 0
return 1 return 1
} }
@@ -62,11 +62,12 @@ NftRouteAdd() {
echo 0 > "/proc/sys/net/ipv4/conf/${_if_vpn}/rp_filter" echo 0 > "/proc/sys/net/ipv4/conf/${_if_vpn}/rp_filter"
NftRouteDelete "$_route_table_id" 2> /dev/null NftRouteDelete "$_route_table_id" 2> /dev/null
$IP_CMD rule add fwmark "$_pkts_mark" table "$_route_table_id" priority "$VPN_RULE_PRIO" $IP_CMD rule add fwmark "$_pkts_mark" table "$_route_table_id" priority "$VPN_RULE_PRIO"
$IP_CMD route add default via "$_vpn_ip" table "$_route_table_id" $IP_CMD route add default via "$_vpn_ip" table "$_route_table_id" metric 100
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo " Error! An error occurred while adding the route. Routing table id=${_route_table_id}, VPN gateway IP=${_vpn_ip}" >&2 echo " Error! An error occurred while adding the route. Routing table id=${_route_table_id}, VPN gateway IP=${_vpn_ip}" >&2
MakeLogRecord "err" "Error! An error occurred while adding the route. Routing table id=${_route_table_id}, VPN gateway IP=${_vpn_ip}" MakeLogRecord "err" "Error! An error occurred while adding the route. Routing table id=${_route_table_id}, VPN gateway IP=${_vpn_ip}"
fi fi
$IP_CMD route add blackhole default table "$_route_table_id" metric 200
if [ $DEBUG -ge 1 ]; then if [ $DEBUG -ge 1 ]; then
echo " nft_functions.NftRouteAdd: ${IP_CMD} rule add fwmark ${_pkts_mark} table ${_route_table_id} priority ${VPN_RULE_PRIO}" >&2 echo " nft_functions.NftRouteAdd: ${IP_CMD} rule add fwmark ${_pkts_mark} table ${_route_table_id} priority ${VPN_RULE_PRIO}" >&2
@@ -80,7 +81,7 @@ NftRouteAdd() {
NftRouteStatus() { NftRouteStatus() {
local _route_table_id=$1 local _route_table_id=$1
[ -n "$($IP_CMD route show table "$_route_table_id" 2> /dev/null)" ] && return 0 $IP_CMD route show table $_route_table_id 2> /dev/null | $AWK_CMD 'BEGIN {code=1} /^(default|local)/ {code=0} END {exit code}' && return 0
return 1 return 1
} }
@@ -90,7 +91,9 @@ NftAddBaseChains() {
$NFT_CMD add chain $NFT_TABLE "$NFT_BLLIST_CHAIN" $NFT_CMD add chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
$NFT_CMD add chain $NFT_TABLE "$NFT_FPROXY_CHAIN" { type filter hook prerouting priority ${_chain_prio_fproxy}\; policy accept\; } $NFT_CMD add chain $NFT_TABLE "$NFT_FPROXY_CHAIN" { type filter hook prerouting priority ${_chain_prio_fproxy}\; policy accept\; }
$NFT_CMD add chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" { type filter hook prerouting priority ${_chain_prio_first}\; policy accept\; } $NFT_CMD add chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" { type filter hook prerouting priority ${_chain_prio_first}\; policy accept\; }
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_FPROXY_CHAIN" meta iif lo return
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_FPROXY_CHAIN" ip daddr "@${NFTSET_FPROXY_PRIVATE}" return NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_FPROXY_CHAIN" ip daddr "@${NFTSET_FPROXY_PRIVATE}" return
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" meta iif lo return
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" "$NFT_ALLOWED_HOSTS_PATTERN" NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" "$NFT_ALLOWED_HOSTS_PATTERN"
if [ "$BYPASS_MODE" = "1" ]; then if [ "$BYPASS_MODE" = "1" ]; then
for _set in "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN" for _set in "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN"