diff --git a/autoinstall/2.x/autoinstall.sh b/autoinstall/2.x/autoinstall.sh index a19c721..2e91c54 100755 --- a/autoinstall/2.x/autoinstall.sh +++ b/autoinstall/2.x/autoinstall.sh @@ -10,9 +10,9 @@ LUCI_APP=1 HTTPS_DNS_PROXY=1 OWRT_VERSION="current" -RUAB_VERSION="2.1.8-r1" -RUAB_MOD_LUA_VERSION="2.1.8-r1" -RUAB_LUCI_APP_VERSION="2.1.8-r2" +RUAB_VERSION="2.1.9-r1" +RUAB_MOD_LUA_VERSION="2.1.9-r1" +RUAB_LUCI_APP_VERSION="2.1.9-r1" BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master" PKG_DIR="/tmp" diff --git a/luci-app-ruantiblock/Makefile b/luci-app-ruantiblock/Makefile index 82b3bb3..476ffac 100644 --- a/luci-app-ruantiblock/Makefile +++ b/luci-app-ruantiblock/Makefile @@ -5,8 +5,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-ruantiblock -PKG_VERSION:=2.1.8 -PKG_RELEASE:=2 +PKG_VERSION:=2.1.9 +PKG_RELEASE:=1 LUCI_TITLE:=LuCI support for ruantiblock LUCI_DEPENDS:=+ruantiblock LUCI_PKGARCH:=all diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/info.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/info.js index 563d8c0..ff9eb44 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/info.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/info.js @@ -296,8 +296,8 @@ return view.extend({ } else { update_status.append( E('tr', { 'class': 'tr' }, [ - E('td', { 'class': 'td left' }, - _('Last blacklist update')), + E('td', { 'class': 'td left', 'style': 'width:33%' }, + _('Last blacklist update') + ':'), E('td', { 'class': 'td left' }, _('No data')), ]) ); diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js index 5037907..56793f9 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js @@ -55,13 +55,17 @@ return baseclass.extend({ infoLabelError : E('span', { 'class': 'label-status error' }, _('Error')), blacklistPresets: { - 'ruantiblock-fqdn': [ 'ruantiblock', 'fqdn', 'https://github.com/gSpotx2f/ruantiblock_blacklist' ], - 'ruantiblock-ip' : [ 'ruantiblock', 'ip', 'https://github.com/gSpotx2f/ruantiblock_blacklist' ], - 'zapret-info-fqdn': [ '*zapret-info', 'fqdn', 'https://github.com/zapret-info/z-i' ], - 'zapret-info-ip' : [ '*zapret-info', 'ip', 'https://github.com/zapret-info/z-i' ], - 'rublacklist-fqdn': [ '*rublacklist', 'fqdn', 'https://rublacklist.net' ], - 'rublacklist-ip' : [ '*rublacklist', 'ip', 'https://rublacklist.net' ], - 'antifilter-ip' : [ '*antifilter', 'ip', 'https://antifilter.download' ], + 'ruantiblock-fqdn' : [ 'ruantiblock', 'fqdn', 'https://github.com/gSpotx2f/ruantiblock_blacklist' ], + 'ruantiblock-ip' : [ 'ruantiblock', 'ip', 'https://github.com/gSpotx2f/ruantiblock_blacklist' ], + 'zapret-info-fqdn' : [ '*zapret-info', 'fqdn', 'https://github.com/zapret-info/z-i' ], + 'zapret-info-fqdn-only': [ '*zapret-info', 'fqdn-only', 'https://github.com/zapret-info/z-i' ], + 'zapret-info-ip' : [ '*zapret-info', 'ip', 'https://github.com/zapret-info/z-i' ], + 'rublacklist-fqdn' : [ '*rublacklist', 'fqdn', 'https://rublacklist.net' ], + 'rublacklist-fqdn-only': [ '*rublacklist', 'fqdn-only', 'https://rublacklist.net' ], + 'rublacklist-ip' : [ '*rublacklist', 'ip', 'https://rublacklist.net' ], + 'antifilter-fqdn' : [ '*antifilter', 'fqdn', 'https://antifilter.download' ], + 'antifilter-fqdn-only' : [ '*antifilter', 'fqdn-only', 'https://antifilter.download' ], + 'antifilter-ip' : [ '*antifilter', 'ip', 'https://antifilter.download' ], }, defaultConfig: { diff --git a/ruantiblock-mod-lua/Makefile b/ruantiblock-mod-lua/Makefile index b58b12b..7dfa75c 100644 --- a/ruantiblock-mod-lua/Makefile +++ b/ruantiblock-mod-lua/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ruantiblock-mod-lua -PKG_VERSION:=2.1.8 +PKG_VERSION:=2.1.9 PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot diff --git a/ruantiblock-mod-lua/files/usr/libexec/ruantiblock/ruab_parser.lua b/ruantiblock-mod-lua/files/usr/libexec/ruantiblock/ruab_parser.lua index 5cee447..6b4d690 100755 --- a/ruantiblock-mod-lua/files/usr/libexec/ruantiblock/ruab_parser.lua +++ b/ruantiblock-mod-lua/files/usr/libexec/ruantiblock/ruab_parser.lua @@ -67,7 +67,9 @@ local Config = Class(nil, { ["RBL_IP_URL"] = true, ["RBL_DPI_URL"] = true, ["ZI_ALL_URL"] = true, + ["AF_IP_FULL_URL"] = true, ["AF_IP_URL"] = true, + ["AF_NET_URL"] = true, ["AF_FQDN_URL"] = true, ["FZ_URL"] = true, ["DL_IPSET_URL"] = true, @@ -85,6 +87,8 @@ local Config = Class(nil, { ["BLLIST_IP_EXCLUDED_FILE"] = true, ["BLLIST_CIDR_EXCLUDED_ENABLE"] = true, ["BLLIST_CIDR_EXCLUDED_FILE"] = true, + ["BLLIST_ORG_EXCLUDED_ENABLE"] = true, + ["BLLIST_ORG_EXCLUDED_FILE"] = true, }, BLLIST_FQDN_FILTER_PATTERNS = {}, BLLIST_IP_FILTER_PATTERNS = {}, @@ -94,6 +98,7 @@ local Config = Class(nil, { BLLIST_FQDN_EXCLUDED_ITEMS = {}, BLLIST_IP_EXCLUDED_ITEMS = {}, BLLIST_CIDR_EXCLUDED_ITEMS = {}, + BLLIST_ORG_EXCLUDED_ITEMS = {}, -- iconv type: standalone iconv or lua-iconv (standalone, lua) ICONV_TYPE = "standalone", -- standalone iconv @@ -102,7 +107,7 @@ local Config = Class(nil, { encoding = "UTF-8", site_encoding = "", http_send_headers = { - ["User-Agent"] = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/142.0", + ["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0", }, connect_timeout = nil, }) @@ -117,7 +122,9 @@ function Config:load_config(t) ["RBL_IP_URL"] = true, ["RBL_DPI_URL"] = true, ["ZI_ALL_URL"] = true, + ["AF_IP_FULL_URL"] = true, ["AF_IP_URL"] = true, + ["AF_NET_URL"] = true, ["AF_FQDN_URL"] = true, ["FZ_URL"] = true, ["DL_IPSET_URL"] = true, @@ -172,6 +179,7 @@ Config.BLLIST_SUMMARIZE_CIDR = remap_bool(Config.BLLIST_SUMMARIZE_CIDR) 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_CIDR_EXCLUDED_ENABLE = remap_bool(Config.BLLIST_CIDR_EXCLUDED_ENABLE) +Config.BLLIST_ORG_EXCLUDED_ENABLE = remap_bool(Config.BLLIST_ORG_EXCLUDED_ENABLE) -- Importing packages @@ -281,6 +289,9 @@ function Config:load_filter_files() end ) end + if self.BLLIST_ORG_EXCLUDED_ENABLE then + load_file(self.BLLIST_ORG_EXCLUDED_FILE, self.BLLIST_ORG_EXCLUDED_ITEMS) + end end function Config:check_filter(str, filter_patterns, reverse) @@ -329,7 +340,6 @@ end Config:load_filter_files() - ------------------------------ Classes ------------------------------- local BlackListParser = Class(Config, { @@ -356,27 +366,42 @@ function BlackListParser:new(t) instance.fqdn_count = 0 instance.fqdn_records_count = 0 instance.fqdn_table = {} - instance.iconv_handler = iconv and iconv.open(instance.encoding, instance.site_encoding) or nil + instance.iconv_handler_fqdn = iconv and iconv.open(instance.encoding, instance.site_encoding) or nil + instance.iconv_handler_org = iconv and iconv.open(instance.site_encoding, instance.encoding) or nil instance.buff = "" instance.http_codes = {} return instance end -function BlackListParser:convert_encoding(input) +function BlackListParser:encoding_iconv(input, from, to) local output - if self.ICONV_TYPE == "lua" and self.iconv_handler then - output = self.iconv_handler:iconv(input) + local handler = assert(io.popen('printf \'%s\' \'' .. input .. '\' | ' .. self.ICONV_CMD .. ' -f "' .. from .. '" -t "' .. to .. '"', 'r')) + output = handler:read("*a") + handler:close() + return (output) +end + +function BlackListParser:encoding_lua(input, handler) + local output + if handler then + output = handler:iconv(input) + end + return (output) +end + +function BlackListParser:convert_encoding(input, handler, from, to) + local output + if self.ICONV_TYPE == "lua" then + output = self:encoding_lua(input, handler) elseif self.ICONV_TYPE == "standalone" and self.ICONV_CMD then - local iconv_handler = assert(io.popen('printf \'%s\' \'' .. input .. '\' | ' .. self.ICONV_CMD .. ' -f "' .. self.site_encoding .. '" -t "' .. self.encoding .. '"', 'r')) - output = iconv_handler:read("*a") - iconv_handler:close() + output = self:encoding_iconv(input, from, to) end return (output) end function BlackListParser:convert_to_punycode(input) if self.site_encoding and self.site_encoding ~= "" then - input = self:convert_encoding(input) + input = self:convert_encoding(input, self.iconv_handler_fqdn, self.site_encoding, self.encoding) end return input and (idn.encode(input)) end @@ -422,7 +447,7 @@ function BlackListParser:fqdn_value_processing(value) end if not self.BLLIST_FQDN_FILTER or (self.BLLIST_FQDN_FILTER and not self:check_filter(value, self.BLLIST_FQDN_FILTER_PATTERNS, self.BLLIST_FQDN_FILTER_TYPE)) then if value:match("^" .. self.fqdn_pattern .. "$") then - elseif self.BLLIST_ENABLE_IDN and value:match("^[^\\/&%?]-[^\\/&%?%.]+%.[^\\/&%?%.]+%.?$") then + elseif self.BLLIST_ENABLE_IDN and value:match('^[^",%%\\/&%?]-[^",%%\\/&%?%.]+%.[^",%%\\/&%?%.]+%.?$') then value = self:convert_to_punycode(value) if not value then return false @@ -440,6 +465,16 @@ function BlackListParser:fqdn_value_processing(value) return true end +function BlackListParser:org_value_processing(value) + if value == "" then + return false + end + if self.BLLIST_ORG_EXCLUDED_ENABLE and self.BLLIST_ORG_EXCLUDED_ITEMS[value] then + return true + end + return false +end + function BlackListParser:parser_func() -- Must be overridden by a subclass error("Method BlackListParser:parser_func() must be overridden by a subclass!") @@ -519,6 +554,16 @@ end function BlackListParser:run() local return_code = 0 + if self.site_encoding and self.site_encoding ~= "" then + local t = {} + for i in pairs(self.BLLIST_ORG_EXCLUDED_ITEMS) do + local v = self:convert_encoding(i, self.iconv_handler_org, self.encoding, self.site_encoding) + if v then + t[v] = true + end + end + self.BLLIST_ORG_EXCLUDED_ITEMS = t + end if self:download_files(self.url) then if (self.fqdn_count + self.ip_count + self.cidr_count) > self.BLLIST_MIN_ENTRIES then return_code = 0 @@ -969,8 +1014,26 @@ local Rbl = Class(BlackListParser, { function Rbl:parser_func() return function(chunk) if chunk and chunk ~= "" then - for fqdn_str, ip_str in chunk:gmatch('"domains": %["?(.-)"?%].-"ips": %[([a-f0-9/.:", ]*)%].-') do - fqdn_parser_func(self, ip_str, fqdn_str) + for org_str, fqdn_str, ip_str in chunk:gmatch('"name": "(.-)".-"domains": %["?(.-)"?%].-"ips": %[([a-f0-9/.:", ]*)%].-') do + if org_str == "" or not self:org_value_processing(org_str) then + fqdn_parser_func(self, ip_str, fqdn_str) + end + end + end + return true + end +end + +local RblFQDN = Class(Rbl, { +}) + +function RblFQDN:parser_func() + return function(chunk) + if chunk and chunk ~= "" then + for org_str, fqdn_str in chunk:gmatch('"name": "(.-)".-"domains": %["?(.-)"?%].-') do + if org_str == "" or not self:org_value_processing(org_str) then + fqdn_parser_func(self, nil, fqdn_str) + end end end return true @@ -978,12 +1041,21 @@ function Rbl:parser_func() end local RblIp = Class(Rbl, { - url = Config.RBL_IP_URL, - records_separator = ",", - ip_string_pattern = "([a-f0-9/.:]+)", - parser_func = ip_parser_func, }) +function RblIp:parser_func() + return function(chunk) + if chunk and chunk ~= "" then + for org_str, ip_str in chunk:gmatch('"name": "(.-)".-"domains": %["?.-"?%].-"ips": %[([a-f0-9/.:", ]*)%].-') do + if org_str == "" or not self:org_value_processing(org_str) then + self:ip_value_processing(ip_str) + end + end + end + return true + end +end + local RblDPI = Class(BlackListParser, { url = Config.RBL_DPI_URL, BLLIST_MIN_ENTRIES = 0, @@ -1050,8 +1122,26 @@ end function Zi:parser_func() return function(chunk) if chunk and chunk ~= "" then - for ip_str, fqdn_str in chunk:gmatch("([^;]-);([^;]-);.-" .. self.records_separator) do - fqdn_parser_func(self, ip_str, fqdn_str) + for ip_str, fqdn_str, org_str in chunk:gmatch("([^;]-);([^;]-);[^;]-;([^;]-);.-" .. self.records_separator) do + if org_str == "" or not self:org_value_processing(org_str) then + fqdn_parser_func(self, ip_str, fqdn_str) + end + end + end + return true + end +end + +local ZiFQDN = Class(Zi, { +}) + +function ZiFQDN:parser_func() + return function(chunk) + if chunk and chunk ~= "" then + for fqdn_str, org_str in chunk:gmatch("[^;]-;([^;]-);[^;]-;([^;]-);.-" .. self.records_separator) do + if org_str == "" or not self:org_value_processing(org_str) then + fqdn_parser_func(self, nil, fqdn_str) + end end end return true @@ -1059,10 +1149,21 @@ function Zi:parser_func() end local ZiIp = Class(Zi, { - ip_string_pattern = "([a-f0-9%.:/ |]+);.-\n", - parser_func = ip_parser_func, }) +function ZiIp:parser_func() + return function(chunk) + if chunk and chunk ~= "" then + for ip_str, org_str in chunk:gmatch("([^;]-);[^;]-;[^;]-;([^;]-);.-" .. self.records_separator) do + if org_str == "" or not self:org_value_processing(org_str) then + self:ip_value_processing(ip_str) + end + end + end + return true + end +end + -- antifilter local Af = Class(BlackListParser, { @@ -1081,12 +1182,36 @@ function Af:parser_func() end end -local AfIp = Class(Af, { +local AfIpFull = Class(BlackListParser, { + url = Config.AF_IP_FULL_URL, + ip_string_pattern = "(.-)\n", +}) + +function AfIpFull:parser_func() + return function(chunk) + if chunk and chunk ~= "" then + chunk = chunk:gsub("/32", "") + for ip_string in chunk:gmatch(self.ip_string_pattern) do + self:ip_value_processing(ip_string) + end + end + return true + end +end + +local AfIp = Class(BlackListParser, { url = Config.AF_IP_URL, ip_string_pattern = "(.-)\n", parser_func = ip_parser_func, }) +local AfNet = Class(BlackListParser, { + url = Config.AF_NET_URL, + BLLIST_MIN_ENTRIES = 0, + ip_string_pattern = "(.-)\n", + parser_func = ip_parser_func, +}) + -- fz139 local Fz = Class(BlackListParser, { @@ -1099,14 +1224,37 @@ function Fz:parser_func() return function(chunk) if chunk and chunk ~= "" then for entry in chunk:gmatch("(.-)" .. self.records_separator) do - local fqdn_str = entry:match("<%!%[CDATA%[(.-)%]%]>") - if fqdn_str ~= nil and #fqdn_str > 0 and not fqdn_str:match("^" .. self.ip_pattern .. "$") and self:fqdn_value_processing(fqdn_str) then - else - for ip_str in entry:gmatch("(.-)") do - self:ip_value_processing(ip_str) + local org_str = entry:match('org="(.-)"') + if org_str == "" or not self:org_value_processing(org_str) then + local fqdn_str = entry:match("<%!%[CDATA%[(.-)%]%]>") + if fqdn_str ~= nil and #fqdn_str > 0 and not fqdn_str:match("^" .. self.ip_pattern .. "$") and self:fqdn_value_processing(fqdn_str) then + else + for ip_str in entry:gmatch("(.-)") do + self:ip_value_processing(ip_str) + end + for ip_str in entry:gmatch("(.-)") do + self:ip_value_processing(ip_str) + end end - for ip_str in entry:gmatch("(.-)") do - self:ip_value_processing(ip_str) + end + end + end + return true + end +end + +local FzFQDN = Class(Fz, { +}) + +function FzFQDN:parser_func() + return function(chunk) + if chunk and chunk ~= "" then + for entry in chunk:gmatch("(.-)" .. self.records_separator) do + local org_str = entry:match('org="(.-)"') + if org_str == "" or not self:org_value_processing(org_str) then + local fqdn_str = entry:match("<%!%[CDATA%[(.-)%]%]>") + if fqdn_str ~= nil and #fqdn_str > 0 and not fqdn_str:match("^" .. self.ip_pattern .. "$") then + self:fqdn_value_processing(fqdn_str) end end end @@ -1122,11 +1270,14 @@ function FzIp:parser_func() return function(chunk) if chunk and chunk ~= "" then for entry in chunk:gmatch("(.-)" .. self.records_separator) do - for ip_str in entry:gmatch("(.-)") do - self:ip_value_processing(ip_str) - end - for ip_str in entry:gmatch("(.-)") do - self:ip_value_processing(ip_str) + local org_str = entry:match('org="(.-)"') + if org_str == "" or not self:org_value_processing(org_str) then + for ip_str in entry:gmatch("(.-)") do + self:ip_value_processing(ip_str) + end + for ip_str in entry:gmatch("(.-)") do + self:ip_value_processing(ip_str) + end end end end @@ -1199,8 +1350,18 @@ end ----------------------------- Main section ------------------------------ local parsers_table = { - ["ip"] = {["rublacklist"] = {RblIp}, ["zapret-info"] = {ZiIp}, ["antifilter"] = {AfIp}, ["fz"] = {FzIp}, ["ruantiblock"] = {Ra}}, - ["fqdn"] = {["rublacklist"] = {Rbl, RblDPI}, ["zapret-info"] = {Zi}, ["antifilter"] = {Af}, ["fz"] = {Fz}, ["ruantiblock"] = {Ra}}, + ["ip"] = { + ["rublacklist"] = {RblIp}, ["zapret-info"] = {ZiIp}, + ["antifilter"] = {AfIpFull, AfNet}, ["fz"] = {FzIp}, ["ruantiblock"] = {Ra}, + }, + ["fqdn"] = { + ["rublacklist"] = {Rbl, RblDPI}, ["zapret-info"] = {Zi}, + ["antifilter"] = {Af, AfNet}, ["fz"] = {Fz}, ["ruantiblock"] = {Ra}, + }, + ["fqdn-only"] = { + ["rublacklist"] = {RblFQDN, RblDPI}, ["zapret-info"] = {ZiFQDN}, + ["antifilter"] = {Af}, ["fz"] = {FzFQDN}, ["ruantiblock"] = {Ra}, + }, } local ret_list = {} @@ -1213,7 +1374,6 @@ if parser_classes then for _, i in ipairs(parser_instances) do ret_list[i:run()] = true end - local return_sum = 0 for i, _ in pairs(ret_list) do return_sum = return_sum + i @@ -1229,5 +1389,4 @@ if parser_classes then else error("Wrong configuration! (Config.BLLIST_MODE, Config.BLLIST_SOURCE)") end - os.exit(ret_list[1] and 1 or (ret_list[2] and 2 or 0)) diff --git a/ruantiblock-mod-py/Makefile b/ruantiblock-mod-py/Makefile index 2b6bbcc..3edb694 100644 --- a/ruantiblock-mod-py/Makefile +++ b/ruantiblock-mod-py/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ruantiblock-mod-py -PKG_VERSION:=2.1.8 +PKG_VERSION:=2.1.9 PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot diff --git a/ruantiblock-mod-py/files/usr/libexec/ruantiblock/ruab_parser.py b/ruantiblock-mod-py/files/usr/libexec/ruantiblock/ruab_parser.py index 77e18cb..e627158 100755 --- a/ruantiblock-mod-py/files/usr/libexec/ruantiblock/ruab_parser.py +++ b/ruantiblock-mod-py/files/usr/libexec/ruantiblock/ruab_parser.py @@ -53,7 +53,9 @@ class Config: "RBL_IP_URL", "RBL_DPI_URL", "ZI_ALL_URL", + "AF_IP_FULL_URL", "AF_IP_URL", + "AF_NET_URL", "AF_FQDN_URL", "FZ_URL", "DL_IPSET_URL", @@ -71,6 +73,8 @@ class Config: "BLLIST_IP_EXCLUDED_FILE", "BLLIST_CIDR_EXCLUDED_ENABLE", "BLLIST_CIDR_EXCLUDED_FILE", + "BLLIST_ORG_EXCLUDED_ENABLE", + "BLLIST_ORG_EXCLUDED_FILE", ] BLLIST_FQDN_FILTER_PATTERNS = [] BLLIST_IP_FILTER_PATTERNS = [] @@ -80,12 +84,13 @@ class Config: BLLIST_FQDN_EXCLUDED_ITEMS = set() BLLIST_IP_EXCLUDED_ITEMS = set() BLLIST_CIDR_EXCLUDED_ITEMS = [] + BLLIST_ORG_EXCLUDED_ITEMS = set() @classmethod def _load_config(cls, cfg_dict): def normalize_string(string): - return re.sub('"', '', string) + return string.replace('"', '') config_sets = set() config_arrays = { @@ -93,7 +98,9 @@ class Config: "RBL_IP_URL", "RBL_DPI_URL", "ZI_ALL_URL", + "AF_IP_FULL_URL", "AF_IP_URL", + "AF_NET_URL", "AF_FQDN_URL", "FZ_URL", "DL_IPSET_URL", @@ -198,6 +205,12 @@ class Config: cls.BLLIST_CIDR_EXCLUDED_ITEMS, is_array=True, func=cls.makeIPv4Network) + @classmethod + def load_org_excluded(cls, file_path=None): + if cls.BLLIST_ORG_EXCLUDED_ENABLE: + cls._load_filter(file_path or cls.BLLIST_ORG_EXCLUDED_FILE, + cls.BLLIST_ORG_EXCLUDED_ITEMS) + @staticmethod def _check_filter(string, filter_patterns, reverse=False): if filter_patterns and string: @@ -257,7 +270,7 @@ class BlackListParser(Config): self.output_fqdn_count = 0 self.ssl_unverified = False self.send_headers_dict = { - "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/142.0", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0", } ### Proxies (ex.: self.proxies = {"http": "http://192.168.0.1:8080", "https": "http://192.168.0.1:8080"}) self.proxies = None @@ -411,6 +424,12 @@ class BlackListParser(Config): else: raise FieldValueError() + def org_value_processing(self, value): + if not value: + return + if self.BLLIST_ORG_EXCLUDED_ENABLE and value in self.BLLIST_ORG_EXCLUDED_ITEMS: + return True + def parser_func(self): """Must be overridden by a subclass""" raise NotImplementedError() @@ -669,30 +688,34 @@ class WriteConfigFiles(Config): f"{cidr_count} {ip_count} {fqdn_count}") -class RblFQDN(BlackListParser): +class RblHybrid(BlackListParser): def __init__(self): super().__init__() self.url = self.RBL_ALL_URL self.records_separator = '{"appearDate": ' self.ips_separator = ", " + self.entry_regexp = re.compile(r'"domains": \["?(.*?)"?\].*?"ips": \[([a-f0-9/.:", ]*)\]') + self.org_value_regexp = re.compile(r'"name": "(.*?)"') def parser_func(self): for url in self.url: for entry in self._split_entries(url): - res = re.search(r'"domains": \["?(.*?)"?\].*?"ips": \[([a-f0-9/.:", ]*)\]', entry) - if not res: - continue - ip_string = res.group(2).replace('"', "") - fqdn_string = res.group(1) - if fqdn_string: - try: - self.fqdn_value_processing(fqdn_string) - except FieldValueError: + org = self.org_value_regexp.search(entry) + if not org or not self.org_value_processing(org.group(1)): + res = self.entry_regexp.search(entry) + if not res: + continue + ip_string = res.group(2).replace('"', "") + fqdn_string = res.group(1) + if fqdn_string: + try: + self.fqdn_value_processing(fqdn_string) + except FieldValueError: + for i in ip_string.split(self.ips_separator): + self.ip_value_processing(i) + else: for i in ip_string.split(self.ips_separator): self.ip_value_processing(i) - else: - for i in ip_string.split(self.ips_separator): - self.ip_value_processing(i) class RblDPI(BlackListParser): def __init__(self): @@ -700,11 +723,12 @@ class RblDPI(BlackListParser): self.url = self.RBL_DPI_URL self.BLLIST_MIN_ENTRIES = 0 self.records_separator = '{"domains"' + self.entry_regexp = re.compile(r': \[(.*?)\]') def parser_func(self): for url in self.url: for entry in self._split_entries(url): - res = re.search(r': \[(.*?)\]', entry) + res = self.entry_regexp.search(entry) if not res: continue fqdn_string = res.group(1) @@ -715,19 +739,40 @@ class RblDPI(BlackListParser): except FieldValueError: pass -class RblIp(BlackListParser): - def __init__(self): - super().__init__() - self.url = self.RBL_IP_URL - self.records_separator = "," +class RblFQDN(RblHybrid): def parser_func(self): for url in self.url: for entry in self._split_entries(url): - self.ip_value_processing(re.sub(r'[\[\]" ]', "", entry)) + org = self.org_value_regexp.search(entry) + if not org or not self.org_value_processing(org.group(1)): + res = self.entry_regexp.search(entry) + if not res: + continue + fqdn_string = res.group(1) + if fqdn_string: + try: + self.fqdn_value_processing(fqdn_string) + except FieldValueError: + pass -class ZiFQDN(BlackListParser): +class RblIp(RblHybrid): + def parser_func(self): + for url in self.url: + for entry in self._split_entries(url): + org = self.org_value_regexp.search(entry) + if not org or not self.org_value_processing(org.group(1)): + res = self.entry_regexp.search(entry) + if not res: + continue + ip_string = res.group(2).replace('"', "") + if ip_string: + for i in ip_string.split(self.ips_separator): + self.ip_value_processing(i) + + +class ZiHybrid(BlackListParser): def __init__(self): super().__init__() self.url = self.ZI_ALL_URL @@ -750,26 +795,48 @@ class ZiFQDN(BlackListParser): for entry in self._split_entries(url): entry_list = entry.split(self.fields_separator) try: - if entry_list[1]: - try: - self.fqdn_value_processing(entry_list[1]) - except FieldValueError: + if not entry_list[3] or not self.org_value_processing(entry_list[3]): + if entry_list[1]: + try: + self.fqdn_value_processing(entry_list[1]) + except FieldValueError: + for i in entry_list[0].split(self.ips_separator): + self.ip_value_processing(i) + else: for i in entry_list[0].split(self.ips_separator): - self.ip_value_processing(i) - else: - for i in entry_list[0].split(self.ips_separator): - self.ip_value_processing(i) + self.ip_value_processing(i) except IndexError: pass -class ZiIp(ZiFQDN): +class ZiFQDN(ZiHybrid): def parser_func(self): for url in self.url: for entry in self._split_entries(url): entry_list = entry.split(self.fields_separator) - for i in entry_list[0].split(self.ips_separator): - self.ip_value_processing(i) + try: + if not entry_list[3] or not self.org_value_processing(entry_list[3]): + if entry_list[1]: + try: + self.fqdn_value_processing(entry_list[1]) + except FieldValueError: + pass + except IndexError: + pass + + +class ZiIp(ZiHybrid): + def parser_func(self): + for url in self.url: + for entry in self._split_entries(url): + entry_list = entry.split(self.fields_separator) + try: + if not entry_list[3] or not self.org_value_processing(entry_list[3]): + for i in entry_list[0].split(self.ips_separator): + self.ip_value_processing(i) + except IndexError: + pass + class AfFQDN(BlackListParser): def __init__(self, *args, **kwargs): @@ -782,7 +849,19 @@ class AfFQDN(BlackListParser): try: self.fqdn_value_processing(entry) except FieldValueError: - self.ip_value_processing(entry) + pass + + +class AfIpFull(BlackListParser): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.url = self.AF_IP_FULL_URL + self.entry_regexp = re.compile(r"/32$") + + def parser_func(self): + for url in self.url: + for entry in self._split_entries(url): + self.ip_value_processing(self.entry_regexp.sub("", entry)) class AfIp(BlackListParser): @@ -796,7 +875,19 @@ class AfIp(BlackListParser): self.ip_value_processing(entry) -class FzFQDN(BlackListParser): +class AfNet(BlackListParser): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.BLLIST_MIN_ENTRIES = 0 + self.url = self.AF_NET_URL + + def parser_func(self): + for url in self.url: + for entry in self._split_entries(url): + self.ip_value_processing(entry) + + +class FzHybrid(BlackListParser): def __init__(self): super().__init__() self.url = self.FZ_URL @@ -805,36 +896,55 @@ class FzFQDN(BlackListParser): self.fqdn_value_regexp = re.compile(r"<\!\[CDATA\[(.*?)\]\]>", re.U) self.ip_value_regexp = re.compile(r"(.*?)") self.cidr_value_regexp = re.compile(r"(.*?)") + self.org_value_regexp = re.compile(r'org="(.*?)"') def parser_func(self): for url in self.url: for entry in self._split_entries(url): - res = self.fqdn_value_regexp.search(entry) - if res and res.group(1): - try: - self.fqdn_value_processing(res.group(1)) - except FieldValueError: - pass - else: - continue - for i in self.ip_value_regexp.finditer(entry): - if i.group(1): - self.ip_value_processing(i.group(1)) - for i in self.cidr_value_regexp.finditer(entry): - if i.group(1): - self.ip_value_processing(i.group(1)) + org = self.org_value_regexp.search(entry) + if not org or not self.org_value_processing(org.group(1)): + res = self.fqdn_value_regexp.search(entry) + if res and res.group(1): + try: + self.fqdn_value_processing(res.group(1)) + except FieldValueError: + pass + else: + continue + for i in self.ip_value_regexp.finditer(entry): + if i.group(1): + self.ip_value_processing(i.group(1)) + for i in self.cidr_value_regexp.finditer(entry): + if i.group(1): + self.ip_value_processing(i.group(1)) -class FzIp(FzFQDN): +class FzFQDN(FzHybrid): def parser_func(self): for url in self.url: for entry in self._split_entries(url): - for i in self.ip_value_regexp.finditer(entry): - if i.group(1): - self.ip_value_processing(i.group(1)) - for i in self.cidr_value_regexp.finditer(entry): - if i.group(1): - self.ip_value_processing(i.group(1)) + org = self.org_value_regexp.search(entry) + if not org or not self.org_value_processing(org.group(1)): + res = self.fqdn_value_regexp.search(entry) + if res and res.group(1): + try: + self.fqdn_value_processing(res.group(1)) + except FieldValueError: + pass + + +class FzIp(FzHybrid): + def parser_func(self): + for url in self.url: + for entry in self._split_entries(url): + org = self.org_value_regexp.search(entry) + if not org or not self.org_value_processing(org.group(1)): + for i in self.ip_value_regexp.finditer(entry): + if i.group(1): + self.ip_value_processing(i.group(1)) + for i in self.cidr_value_regexp.finditer(entry): + if i.group(1): + self.ip_value_processing(i.group(1)) class Ra(BlackListParser): @@ -883,9 +993,20 @@ if __name__ == "__main__": Config.load_fqdn_excluded() Config.load_ip_excluded() Config.load_cidr_excluded() + Config.load_org_excluded() parsers_dict = { - "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]}, + "ip": { + "rublacklist": [RblIp], "zapret-info": [ZiIp], + "antifilter": [AfIpFull, AfNet], "fz": [FzIp], "ruantiblock": [Ra], + }, + "fqdn": { + "rublacklist": [RblHybrid, RblDPI], "zapret-info": [ZiHybrid], + "antifilter": [AfFQDN, AfNet], "fz": [FzHybrid], "ruantiblock": [Ra], + }, + "fqdn-only": { + "rublacklist": [RblFQDN, RblDPI], "zapret-info": [ZiFQDN], + "antifilter": [AfFQDN], "fz": [FzFQDN], "ruantiblock": [Ra], + }, } try: parser_classes = parsers_dict[Config.BLLIST_MODE][Config.BLLIST_SOURCE] diff --git a/ruantiblock/Makefile b/ruantiblock/Makefile index 4a9be76..380e2aa 100644 --- a/ruantiblock/Makefile +++ b/ruantiblock/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ruantiblock -PKG_VERSION:=2.1.8 +PKG_VERSION:=2.1.9 PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot diff --git a/ruantiblock/files/etc/ruantiblock/fqdn_filter b/ruantiblock/files/etc/ruantiblock/fqdn_filter index caebd7c..44a42b1 100644 --- a/ruantiblock/files/etc/ruantiblock/fqdn_filter +++ b/ruantiblock/files/etc/ruantiblock/fqdn_filter @@ -14,14 +14,13 @@ al[ck]o [cs]pravk bets? igr[ova]+ -olimp +ol[iy]mp p[o0]ker leon jackpot spin loto bcity -stavka lotery fortuna blackja @@ -36,6 +35,8 @@ cash market kupit drug +mefedron +narco farma apteka drop @@ -53,14 +54,15 @@ putan intim escort feya -^1[-]?win +1[-]?win[-] +[.]win +#[.-]win vegas gamble fishka vavada gold avtomat -[.]win pin[-]?up stav[ko] luck @@ -84,3 +86,27 @@ kraken zerkalo ^1w ^1x +pin[ck]o +^gamm?a[0-9-] +^zooma +^flagman[0-9-] +cactus[0-9-] +^stake[0-9-] +arkada[0-9-] +^selector[0-9-] +^7k[0-9-] +gizbo +^888 +^monro[0-9-] +^martin[0-9-] +^kometa[0-9-] +^kush[0-9-] +clubnika +vodka +syka +shot[0-9-] +twin[0-9-] +irwin[c0-9-] +columbus +cryptoboss +#lord diff --git a/ruantiblock/files/etc/ruantiblock/gr_excluded_sld b/ruantiblock/files/etc/ruantiblock/gr_excluded_sld index b1aae7d..cbbc5fc 100644 --- a/ruantiblock/files/etc/ruantiblock/gr_excluded_sld +++ b/ruantiblock/files/etc/ruantiblock/gr_excluded_sld @@ -18,3 +18,4 @@ dyndns.org dynsip.org mydns.jp mooo.com +github.io diff --git a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf index 916b114..9b246de 100644 --- a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf +++ b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf @@ -99,7 +99,7 @@ BLLIST_MODULE="" ### Настройки модулей-парсеров ### -### Режим обхода блокировок: ruantiblock-fqdn, ruantiblock-ip, zapret-info-fqdn, zapret-info-ip, rublacklist-fqdn, rublacklist-ip, antifilter-ip, fz-fqdn, fz-ip +### Режим обхода блокировок: ruantiblock-ip, ruantiblock-fqdn, ruantiblock-fqdn-only, zapret-info-ip, zapret-info-fqdn, zapret-info-fqdn-only, rublacklist-ip, rublacklist-fqdn, rublacklist-fqdn-only, antifilter-ip, antifilter-fqdn, antifilter-fqdn-only, fz-ip, fz-fqdn, fz-fqdn-only BLLIST_PRESET="" ### В случае если из источника получено менее указанного кол-ва записей, то обновления списков не происходит BLLIST_MIN_ENTRIES=3000 @@ -141,6 +141,10 @@ BLLIST_FQDN_FILTER_FILE="/etc/ruantiblock/fqdn_filter" BLLIST_FQDN_EXCLUDED_ENABLE=0 ### Файл с записями FQDN для опции BLLIST_FQDN_EXCLUDED_ENABLE BLLIST_FQDN_EXCLUDED_FILE="/etc/ruantiblock/fqdn_excluded" +### Включение опции исключения записей определённых гос.органов из блэклиста +BLLIST_ORG_EXCLUDED_ENABLE=0 +### Файл с записями для опции BLLIST_ORG_EXCLUDED_ENABLE +BLLIST_ORG_EXCLUDED_FILE="/etc/ruantiblock/org_excluded" ### Обрезка www[0-9]. в FQDN (0 - выкл, 1 - вкл) BLLIST_STRIP_WWW=1 ### Преобразование кириллических доменов в punycode (0 - выкл, 1 - вкл) diff --git a/ruantiblock/files/usr/bin/ruantiblock b/ruantiblock/files/usr/bin/ruantiblock index 869f700..7ed21ee 100755 --- a/ruantiblock/files/usr/bin/ruantiblock +++ b/ruantiblock/files/usr/bin/ruantiblock @@ -135,7 +135,7 @@ export BLLIST_MODULE="" ############################## -### Режим обхода блокировок: ruantiblock-fqdn, ruantiblock-ip, zapret-info-fqdn, zapret-info-ip, rublacklist-fqdn, rublacklist-ip, antifilter-ip, fz-fqdn, fz-ip +### Режим обхода блокировок: ruantiblock-ip, ruantiblock-fqdn, zapret-info-ip, zapret-info-fqdn, zapret-info-fqdn-only, rublacklist-ip, rublacklist-fqdn, rublacklist-fqdn-only, antifilter-ip, antifilter-fqdn, antifilter-fqdn-only, fz-ip, fz-fqdn, fz-fqdn-only export BLLIST_PRESET="" ### В случае если из источника получено менее указанного кол-ва записей, то обновления списков не происходит export BLLIST_MIN_ENTRIES=3000 @@ -177,6 +177,10 @@ export BLLIST_FQDN_FILTER_FILE="${CONFIG_DIR}/fqdn_filter" export BLLIST_FQDN_EXCLUDED_ENABLE=0 ### Файл с записями FQDN для опции BLLIST_FQDN_EXCLUDED_ENABLE export BLLIST_FQDN_EXCLUDED_FILE="${CONFIG_DIR}/fqdn_excluded" +### Включение опции исключения записей определённых гос.органов из блэклиста +export BLLIST_ORG_EXCLUDED_ENABLE=0 +### Файл с записями для опции BLLIST_ORG_EXCLUDED_ENABLE +export BLLIST_ORG_EXCLUDED_FILE="${CONFIG_DIR}/org_excluded" ### Обрезка www[0-9]. в FQDN (0 - выкл, 1 - вкл) export BLLIST_STRIP_WWW=1 ### Преобразование кириллических доменов в punycode (0 - выкл, 1 - вкл) diff --git a/ruantiblock/files/usr/share/ruantiblock/blacklist_sources b/ruantiblock/files/usr/share/ruantiblock/blacklist_sources index 7288371..fce6f66 100644 --- a/ruantiblock/files/usr/share/ruantiblock/blacklist_sources +++ b/ruantiblock/files/usr/share/ruantiblock/blacklist_sources @@ -6,10 +6,13 @@ export RBL_DPI_URL="https://reestr.rublacklist.net/api/v3/dpi/" export RBL_ENCODING="" ## zapret-info export ZI_ALL_URL="https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-00.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-01.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-02.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-03.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-04.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-05.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-06.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-07.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-08.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-09.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-10.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-11.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-12.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-13.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-14.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-15.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-16.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-17.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-18.csv https://raw.githubusercontent.com/zapret-info/z-i/refs/heads/master/dump-19.csv" +# export ZI_ALL_URL="https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-00.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-01.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-02.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-03.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-04.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-05.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-06.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-07.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-08.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-09.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-10.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-11.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-12.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-13.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-14.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-15.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-16.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-17.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-18.csv?format=raw https://sourceforge.net/p/zapret-info/code/HEAD/tree/dump-19.csv?format=raw" #export ZI_ALL_URL="https://app.assembla.com/spaces/z-i/git/source/master/dump.csv?_format=raw" export ZI_ENCODING="CP1251" ## antifilter -export AF_IP_URL="https://antifilter.download/list/allyouneed.lst" +export AF_IP_FULL_URL="https://antifilter.download/list/ipresolve.lst" +export AF_IP_URL="https://antifilter.download/list/ip.lst" +export AF_NET_URL="https://antifilter.download/list/subnet.lst" export AF_FQDN_URL="https://antifilter.download/list/domains.lst" export AF_ENCODING="" ## fz @@ -21,13 +24,17 @@ case "$BLLIST_PRESET" in zapret-info-ip) ### Источник для обновления списка блокировок (zapret-info, rublacklist, antifilter, fz, ruantiblock) export BLLIST_SOURCE="zapret-info" - ### Режим обхода блокировок: ip, fqdn + ### Режим обхода блокировок: ip, fqdn, fqdn-only export BLLIST_MODE="ip" ;; zapret-info-fqdn) export BLLIST_SOURCE="zapret-info" export BLLIST_MODE="fqdn" ;; + zapret-info-fqdn-only) + export BLLIST_SOURCE="zapret-info" + export BLLIST_MODE="fqdn-only" + ;; rublacklist-ip) export BLLIST_SOURCE="rublacklist" export BLLIST_MODE="ip" @@ -36,10 +43,22 @@ case "$BLLIST_PRESET" in export BLLIST_SOURCE="rublacklist" export BLLIST_MODE="fqdn" ;; + rublacklist-fqdn-only) + export BLLIST_SOURCE="rublacklist" + export BLLIST_MODE="fqdn-only" + ;; antifilter-ip) export BLLIST_SOURCE="antifilter" export BLLIST_MODE="ip" ;; + antifilter-fqdn) + export BLLIST_SOURCE="antifilter" + export BLLIST_MODE="fqdn" + ;; + antifilter-fqdn-only) + export BLLIST_SOURCE="antifilter" + export BLLIST_MODE="fqdn-only" + ;; fz-ip) export BLLIST_SOURCE="fz" export BLLIST_MODE="ip" @@ -48,6 +67,10 @@ case "$BLLIST_PRESET" in export BLLIST_SOURCE="fz" export BLLIST_MODE="fqdn" ;; + fz-fqdn-only) + export BLLIST_SOURCE="fz" + export BLLIST_MODE="fqdn-only" + ;; ruantiblock-ip) export BLLIST_SOURCE="ruantiblock" export BLLIST_MODE="ip"