v1.5. New options: USER_ENTRIES_REMOTE, ENABLE_TMP_DOWNLOADS. Fixes & improvements.

This commit is contained in:
gSpot
2024-04-07 17:07:12 +03:00
parent 9474cbc729
commit edb43ea74c
17 changed files with 433 additions and 118 deletions
+3 -3
View File
@@ -9,9 +9,9 @@ LUA_MODULE=0
LUCI_APP=1
OWRT_VERSION="current"
RUAB_VERSION="1.4-3"
RUAB_MOD_LUA_VERSION="1.4-3"
RUAB_LUCI_APP_VERSION="1.4-2"
RUAB_VERSION="1.5-0"
RUAB_MOD_LUA_VERSION="1.5-0"
RUAB_LUCI_APP_VERSION="1.5-0"
BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master"
PKG_DIR="/tmp"
+1
View File
@@ -12,6 +12,7 @@ HTDOCS_RUAB="${HTDOCS_VIEW}/ruantiblock"
CRONTAB_FILE="/etc/crontabs/root"
DATA_DIR="/tmp/ruantiblock"
DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/02-ruantiblock.dnsmasq"
DNSMASQ_DATA_FILE_TMP="${DNSMASQ_DATA_FILE}.tmp"
DNSMASQ_DATA_FILE_BYPASS="/tmp/dnsmasq.d/01-ruantiblock_bypass.dnsmasq"
SCRIPTS_DIR="/usr/share/ruantiblock"
MODULES_DIR="/usr/libexec/ruantiblock"
+1 -1
View File
@@ -4,7 +4,7 @@
include $(TOPDIR)/rules.mk
PKG_VERSION:=1.4-2
PKG_VERSION:=1.5-0
LUCI_TITLE:=LuCI support for ruantiblock
LUCI_DEPENDS:=+ruantiblock
LUCI_PKGARCH:=all
@@ -219,6 +219,7 @@ return view.extend({
} catch(e) {};
let update_status = null,
user_entries = null,
rules = null,
dnsmasq = null,
dnsmasqBypass = null;
@@ -265,6 +266,21 @@ return view.extend({
);
};
if(data.user_entries && data.user_entries.length > 0) {
user_entries = E('table', { 'class': 'table' });
for(let i of data.user_entries) {
user_entries.append(
E('tr', { 'class': 'tr' }, [
E('td', { 'class': 'td left', 'style': 'min-width:33%' },
i.id),
E('td', { 'class': 'td left',
'id' : 'user_entries_' + i },
`CIDR: ${i.cidr}, IP: ${i.ip}, FQDN: ${i.fqdn}`),
])
);
};
};
let nft_data = this.formatNftJson(data);
if(nft_data.rules) {
@@ -346,8 +362,17 @@ return view.extend({
),
];
if(user_entries) {
layout.splice(3, 0,
E('div', { 'class': 'cbi-section fade-in' }, [
E('h3', {}, _('User entries')),
E('div', { 'class': 'cbi-section-node' }, user_entries),
])
);
}
if(dnsmasqBypass) {
layout.splice(4, 0,
layout.splice(5, 0,
E('div', { 'class': 'cbi-section fade-in' },
E('div', { 'class': 'cbi-section-node' }, dnsmasqBypass)
)
@@ -355,7 +380,7 @@ return view.extend({
};
if(dnsmasq) {
layout.splice(5, 0,
layout.splice(6, 0,
E('div', { 'class': 'cbi-section fade-in' },
E('div', { 'class': 'cbi-section-node' }, dnsmasq)
)
@@ -25,6 +25,11 @@ return view.extend({
+ ` ${_('One of the following:')}\n - ${_('valid IP address')}\n - ${_('valid address#port')}\n`;
},
validateUrl: function(section, value) {
return (/^$|^https?:\/\/[\w.-]+(:[0-9]{2,5})?[\w\/~.&?+=-]*$/.test(value)) ? true : _('Expecting:')
+ ` ${_('valid URL')}\n`;
},
load: function() {
return Promise.all([
L.resolveDefault(fs.exec(tools.execPath, [ 'raw-status' ]), 1),
@@ -287,6 +292,13 @@ return view.extend({
o.default = 0;
o.depends({ bllist_preset: '', '!reverse': true });
// 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;
// ADD_USER_ENTRIES
o = s.taboption('blacklist_tab', form.Flag, 'add_user_entries',
_('Enable user entries'), _('Add user entries to the blacklist when updating'));
@@ -301,6 +313,11 @@ return view.extend({
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';
// USER_ENTRIES_REMOTE
o = s.taboption('blacklist_tab', form.DynamicList, 'user_entries_remote',
_('URLs of remote user entries file'));
o.validate = this.validateUrl;
// USER_ENTRIES_DNS
o = s.taboption('blacklist_tab', form.Value, 'user_entries_dns',
_("DNS server that is used for the user's FQDN entries"), '<code>ipaddress[#port]</code>');
+16
View File
@@ -381,6 +381,9 @@ msgstr "Ruantiblock"
msgid "Run at startup"
msgstr "Запуск при старте системы"
msgid "Safe blacklist update"
msgstr "Безопасное обновление блэклиста"
msgid "Save"
msgstr "Сохранить"
@@ -426,6 +429,13 @@ msgstr "Суммировать '/24' подсети"
msgid "Summarize IP ranges"
msgstr "Суммировать IP диапазоны"
msgid ""
"If update fails, the old blacklist configuration will be retained. "
"Temporary files are used, when updating the blacklist (increases memory consumption)."
msgstr ""
"Если обновление завершилось с ошибками, будет сохранена старая конфигурация блэклиста. "
"При обновлении используются временные файлы (увеличивается потребление памяти)."
msgid ""
"The number of IP addresses in the subnet, upon reaching which the entire "
"'/24' subnet is added to the list"
@@ -521,6 +531,9 @@ msgstr "Обновлять блэклист после запуска систе
msgid "Updating"
msgstr "Обновление"
msgid "URLs of remote user entries file"
msgstr "URL удалённых файлов записей пользователя"
msgid "Use optional DNS resolver"
msgstr "Использовать альтернативный DNS резолвер"
@@ -577,3 +590,6 @@ msgstr "верный IP-адрес"
msgid "valid address#port"
msgstr "верный IP-адрес#порт"
msgid "valid URL"
msgstr "верный URL"
@@ -353,6 +353,9 @@ msgstr ""
msgid "Run at startup"
msgstr ""
msgid "Safe blacklist update"
msgstr ""
msgid "Save"
msgstr ""
@@ -396,6 +399,11 @@ msgstr ""
msgid "Summarize IP ranges"
msgstr ""
msgid ""
"If update fails, the old blacklist configuration will be retained. "
"Temporary files are used, when updating the blacklist (increases memory consumption)."
msgstr ""
msgid ""
"The number of IP addresses in the subnet, upon reaching which the entire "
"'/24' subnet is added to the list"
@@ -486,6 +494,9 @@ msgstr ""
msgid "Updating"
msgstr ""
msgid "URLs of remote user entries file"
""
msgid "Use optional DNS resolver"
msgstr ""
msgid "User entries"
@@ -541,3 +552,6 @@ msgstr ""
msgid "valid address#port"
msgstr ""
msgid "valid URL"
msgstr ""
+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock-mod-lua
PKG_VERSION:=1.4
PKG_RELEASE:=3
PKG_VERSION:=1.5
PKG_RELEASE:=0
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
include $(INCLUDE_DIR)/package.mk
@@ -97,6 +97,7 @@ local Config = Class(nil, {
http_send_headers = {
["User-Agent"] = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0",
},
connect_timeout = nil,
})
Config.wget_user_agent = (Config.http_send_headers["User-Agent"]) and ' -U "' .. Config.http_send_headers["User-Agent"] .. '"' or ''
@@ -263,6 +264,7 @@ function BlackListParser:new(t)
instance.fqdn_table = {}
instance.iconv_handler = iconv and iconv.open(instance.encoding, instance.site_encoding) or nil
instance.buff = ""
instance.http_codes = {}
return instance
end
@@ -382,9 +384,19 @@ function BlackListParser:get_http_data(url)
local ret_val, ret_code, ret_headers
local http_module = url:match("^https") and https or http
if http_module then
local http_sink = ltn12.sink.chain(self:chunk_buffer(), self:parser_func())
ret_val, ret_code, ret_headers = http_module.request{url = url, sink = http_sink, headers = self.http_send_headers}
if not ret_val or ret_code ~= 200 then
if self.connect_timeout ~= nil then
http_module.TIMEOUT = self.connect_timeout
end
ret_val, ret_code, ret_headers = http_module.request{url = url, method="HEAD", headers = self.http_send_headers}
if ret_val and ret_code == 200 then
local http_sink = ltn12.sink.chain(self:chunk_buffer(), self:parser_func())
ret_val, ret_code, ret_headers = http_module.request{url = url, sink = http_sink, headers = self.http_send_headers}
self.http_codes[ret_code] = true
if not ret_val or ret_code ~= 200 then
ret_val = nil
print(string.format("Connection error! (%s) URL: %s", ret_code, url))
end
else
ret_val = nil
print(string.format("Connection error! (%s) URL: %s", ret_code, url))
end
@@ -419,9 +431,16 @@ function BlackListParser:run()
return_code = 2
end
else
return_code = 1
return_code = 2
end
for i in pairs(self.http_codes) do
if i ~= 200 then
return_code = 2
break
end
end
self.buff = ""
self.http_codes = {}
return return_code
end
@@ -961,11 +980,16 @@ local Ra = Class(BlackListParser, {
function Ra:download_config(url, file)
local ret_val = false
self.current_file_handler = assert(io.open(file, "w"), "Could not open file")
self.current_file = file
self.current_file_handler = nil
if self:download_files(url) then
ret_val = true
end
self.current_file_handler:close()
if self.current_file_handler then
self.current_file_handler:close()
end
self.current_file_handler = nil
self.current_file = nil
return ret_val
end
@@ -978,7 +1002,12 @@ end
function Ra:parser_func()
return function(chunk)
if chunk and chunk ~= "" then
self.current_file_handler:write(chunk)
if not self.current_file_handler and self.current_file then
self.current_file_handler = assert(io.open(self.current_file, "w"), "Could not open file")
end
if self.current_file_handler then
self.current_file_handler:write(chunk)
end
end
return true
end
@@ -993,6 +1022,13 @@ function Ra:run()
end
end
end
for i in pairs(self.http_codes) do
if i ~= 200 then
return_code = 2
break
end
end
self.http_codes = {}
return return_code
end
+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock-mod-py
PKG_VERSION:=1.4
PKG_RELEASE:=3
PKG_VERSION:=1.5
PKG_RELEASE:=0
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
include $(INCLUDE_DIR)/package.mk
@@ -158,8 +158,7 @@ class BlackListParser(Config):
self.ip_pattern = re.compile(r"(([0-9]{1,3}[.]){3})[0-9]{1,3}")
self.cidr_pattern = re.compile(r"([0-9]{1,3}[.]){3}[0-9]{1,3}/[0-9]{1,2}")
self.fqdn_pattern = re.compile(
r"([а-яёa-z0-9_.*-]*?)([а-яёa-z0-9_-]+[.][а-яёa-z0-9-]+)",
re.U)
r"([а-яёa-z0-9_.*-]*?)([а-яёa-z0-9_-]+[.][а-яёa-z0-9-]+)", re.U)
self.www_pattern = re.compile(r"^www[0-9]?[.]")
self.cyr_pattern = re.compile(r"[а-яё]", re.U)
self.cidr_set = set()
@@ -183,6 +182,7 @@ class BlackListParser(Config):
self.default_site_encoding = "utf-8"
self.site_encoding = self.default_site_encoding
self.rest = bytes()
self.http_codes = set()
@staticmethod
def _compile_filter_patterns(filters_seq):
@@ -233,6 +233,7 @@ class BlackListParser(Config):
timeout=self.connect_timeout
) as conn_params:
conn_object, http_code, _ = conn_params
self.http_codes.add(http_code)
if http_code == 200:
while True:
chunk = conn_object.read(self.data_chunk)
@@ -350,7 +351,12 @@ class BlackListParser(Config):
ret_value = 0
else:
ret_value = 2
for i in self.http_codes:
if i != 200:
ret_value = 2
break
self.rest = bytes()
self.http_codes = set()
return ret_value
@@ -722,23 +728,34 @@ class RaFQDN(BlackListParser):
self.url_ipset = self.RA_FQDN_IPSET_URL
self.url_dnsmasq = self.RA_FQDN_DMASK_URL
self.url_stat = self.RA_FQDN_STAT_URL
self.current_file_handler = None
def parser_func(self):
for chunk in self._download_data(self.url[0]):
if chunk:
self.current_file_handler.write(chunk)
def download_config(self, url, cfg_file):
self.url = url
with open(cfg_file, "wb", buffering=-1) as self.current_file_handler:
self.parser_func()
file_handler = None
for chunk in self._download_data(self.url[0]):
if chunk:
if not file_handler:
try:
file_handler = open(cfg_file, "wb", buffering=-1)
except Exception:
break
if file_handler:
file_handler.write(chunk)
if file_handler:
file_handler.close()
file_handler = None
def run(self):
ret_value = 0
self.download_config(self.url_ipset, self.IP_DATA_FILE)
self.download_config(self.url_dnsmasq, self.DNSMASQ_DATA_FILE)
self.download_config(self.url_stat, self.UPDATE_STATUS_FILE)
return 0
for i in self.http_codes:
if i != 200:
ret_value = 2
break
self.http_codes = set()
return ret_value
class RaIp(RaFQDN):
+4 -3
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock
PKG_VERSION:=1.4
PKG_RELEASE:=3
PKG_VERSION:=1.5
PKG_RELEASE:=0
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
include $(INCLUDE_DIR)/package.mk
@@ -78,9 +78,10 @@ FILE_INIT_SCRIPT="/etc/init.d/ruantiblock"
FILE_MAIN_SCRIPT="/usr/bin/ruantiblock"
CRONTAB_FILE="/etc/crontabs/root"
DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/02-ruantiblock.dnsmasq"
DNSMASQ_DATA_FILE_TMP="${DNSMASQ_DATA_FILE}.tmp"
DNSMASQ_DATA_FILE_BYPASS="/tmp/dnsmasq.d/01-ruantiblock_bypass.dnsmasq"
rm -f $$DNSMASQ_DATA_FILE $$DNSMASQ_DATA_FILE_BYPASS
rm -f $$DNSMASQ_DATA_FILE $$DNSMASQ_DATA_FILE_TMP $$DNSMASQ_DATA_FILE_BYPASS
test -e "$$FILE_MAIN_SCRIPT" && $$FILE_MAIN_SCRIPT destroy
test -e "$$FILE_INIT_SCRIPT" && $$FILE_INIT_SCRIPT disable
+5 -4
View File
@@ -2,11 +2,11 @@
config main 'config'
option proxy_mode '1'
option proxy_local_clients '1'
option enable_logging '1'
option update_at_startup '1'
option nftset_clear_sets '1'
option allowed_hosts_mode '0'
option bypass_mode '0'
option enable_fproxy '0'
option enable_bllist_proxy '0'
option if_vpn 'tun0'
option vpn_route_check '0'
option tor_trans_port '9040'
@@ -14,8 +14,10 @@ config main 'config'
option t_proxy_port_tcp '1100'
option t_proxy_port_udp '1100'
option t_proxy_allow_udp '0'
option bypass_mode '0'
option enable_bllist_proxy '0'
option enable_tmp_downloads '0'
option add_user_entries '0'
option enable_logging '1'
option bllist_min_entries '3000'
option bllist_ip_limit '0'
option bllist_summarize_ip '1'
@@ -43,4 +45,3 @@ config main 'config'
option bllist_enable_idn '0'
option bllist_alt_nslookup '0'
option bllist_alt_dns_addr '8.8.8.8'
option update_at_startup '1'
@@ -80,6 +80,12 @@ ADD_USER_ENTRIES=0
USER_ENTRIES_DNS=""
### Файл пользовательских записей
USER_ENTRIES_FILE="/etc/ruantiblock/user_entries"
### URL удаленных файлов записей пользователя, через пробел (прим.: http://server.lan/files/user_entries_1 http://server.lan/files/user_entries_2)
USER_ENTRIES_REMOTE=""
### Кол-во попыток скачивания удаленного файла записей пользователя (в случае неудачи)
USER_ENTRIES_REMOTE_DOWNLOAD_ATTEMPTS=3
### Таймаут между попытками скачивания
USER_ENTRIES_REMOTE_DOWNLOAD_TIMEOUT=60
### Режим списка записей, исключаемых из обхода блокировок (0 - выкл, 1 - вкл)
BYPASS_MODE=0
### DNS-сервер для исключаемых записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет
@@ -92,10 +98,12 @@ ENABLE_FPROXY=0
FPROXY_LIST=""
### Список приватных сетей для режима полного прокси, через пробел
FPROXY_PRIVATE_NETS="192.168.0.0/16 172.16.0.0/12 10.0.0.0/8"
### Режим безопасного обновления блэклиста. Скачивание во временный файл и затем замена основного. Увеличивает потребление памяти (0 - выкл, 1 - вкл)
ENABLE_TMP_DOWNLOADS=0
### Скачивать блэклисты через прокси
ENABLE_BLLIST_PROXY=0
### Список хостов источников блэклиста
BLLIST_HOSTS="reestr.rublacklist.net raw.githubusercontent.com antifilter.download"
BLLIST_HOSTS="reestr.rublacklist.net raw.githubusercontent.com app.assembla.com antifilter.download"
### Кол-во попыток обновления блэклиста (в случае неудачи)
MODULE_RUN_ATTEMPTS=3
### Таймаут между попытками обновления
@@ -150,8 +158,8 @@ BLLIST_ALT_DNS_ADDR="8.8.8.8"
RBL_ALL_URL="https://reestr.rublacklist.net/api/v3/snapshot/"
RBL_IP_URL="https://reestr.rublacklist.net/api/v3/ips/"
RBL_DPI_URL="https://reestr.rublacklist.net/api/v3/dpi/"
ZI_ALL_URL="https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv"
#ZI_ALL_URL="https://app.assembla.com/spaces/z-i/git/source/master/dump.csv?_format=raw"
#ZI_ALL_URL="https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv"
ZI_ALL_URL="https://app.assembla.com/spaces/z-i/git/source/master/dump.csv?_format=raw"
AF_IP_URL="https://antifilter.download/list/allyouneed.lst"
AF_FQDN_URL="https://antifilter.download/list/domains.lst"
FZ_URL="https://raw.githubusercontent.com/fz139/vigruzki/main/dump.xml.00 https://raw.githubusercontent.com/fz139/vigruzki/main/dump.xml.01 https://raw.githubusercontent.com/fz139/vigruzki/main/dump.xml.02"
+230 -75
View File
@@ -97,6 +97,12 @@ export ADD_USER_ENTRIES=0
export USER_ENTRIES_DNS=""
### Файл пользовательских записей
export USER_ENTRIES_FILE="${CONFIG_DIR}/user_entries"
### URL удаленных файлов записей пользователя, через пробел (прим.: http://server.lan/files/user_entries_1 http://server.lan/files/user_entries_2)
export USER_ENTRIES_REMOTE=""
### Кол-во попыток скачивания удаленного файла записей пользователя (в случае неудачи)
export USER_ENTRIES_REMOTE_DOWNLOAD_ATTEMPTS=3
### Таймаут между попытками скачивания
export USER_ENTRIES_REMOTE_DOWNLOAD_TIMEOUT=60
### Режим списка IP адресов исключаемых из обхода блокировок (0 - выкл, 1 - вкл)
export BYPASS_MODE=0
### DNS-сервер для исключаемых записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет
@@ -109,10 +115,12 @@ export ENABLE_FPROXY=0
export FPROXY_LIST=""
### Список приватных сетей для режима полного прокси, через пробел
export FPROXY_PRIVATE_NETS="192.168.0.0/16 172.16.0.0/12 10.0.0.0/8"
### Режим безопасного обновления блэклиста. Скачивание во временный файл и затем замена основного. Увеличивает потребление памяти (0 - выкл, 1 - вкл)
export ENABLE_TMP_DOWNLOADS=0
### Скачивать блэклисты через прокси
export ENABLE_BLLIST_PROXY=0
### Список хостов источников блэклиста
export BLLIST_HOSTS="reestr.rublacklist.net raw.githubusercontent.com antifilter.download"
export BLLIST_HOSTS="reestr.rublacklist.net raw.githubusercontent.com app.assembla.com antifilter.download"
### Кол-во попыток обновления блэклиста (в случае неудачи)
export MODULE_RUN_ATTEMPTS=3
### Таймаут между попытками обновления
@@ -167,7 +175,8 @@ export BLLIST_ALT_DNS_ADDR="8.8.8.8"
export RBL_ALL_URL="https://reestr.rublacklist.net/api/v3/snapshot/"
export RBL_IP_URL="https://reestr.rublacklist.net/api/v3/ips/"
export RBL_DPI_URL="https://reestr.rublacklist.net/api/v3/dpi/"
export ZI_ALL_URL="https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv"
#export ZI_ALL_URL="https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv"
export ZI_ALL_URL="https://app.assembla.com/spaces/z-i/git/source/master/dump.csv?_format=raw"
export AF_IP_URL="https://antifilter.download/list/allyouneed.lst"
export AF_FQDN_URL="https://antifilter.download/list/domains.lst"
export FZ_URL="https://raw.githubusercontent.com/fz139/vigruzki/main/dump.xml.00 https://raw.githubusercontent.com/fz139/vigruzki/main/dump.xml.01 https://raw.githubusercontent.com/fz139/vigruzki/main/dump.xml.02"
@@ -251,12 +260,17 @@ export NFTSET_CIDR_CFG="set ${NFTSET_CIDR} {type ${NFTSET_CIDR_TYPE};size ${NFTS
export NFTSET_IP_CFG="set ${NFTSET_IP} {type ${NFTSET_IP_TYPE};size ${NFTSET_MAXELEM_IP};policy ${NFTSET_POLICY_IP};flags dynamic;"
export NFTSET_BYPASS_IP_CFG="set ${NFTSET_BYPASS_IP} {type ${NFTSET_BYPASS_IP_TYPE};size ${NFTSET_MAXELEM_BYPASS_IP};policy ${NFTSET_POLICY_CIDR};flags interval;auto-merge;"
export UPDATE_STATUS_FILE="${DATA_DIR}/update_status"
export USER_ENTRIES_STATUS_FILE="${DATA_DIR}/user_entries_status"
U_PID_FILE="/var/run/${NAME}_update.pid"
START_PID_FILE="/var/run/${NAME}_start.pid"
TOKEN_FILE="/var/run/${NAME}.token"
export HTML_OUTPUT="${HTML_DIR}/${NAME}.html"
NFT_FUNCTIONS="${SCRIPTS_DIR}/nft_functions"
INFO_OUTPUT_FUNCTION="${SCRIPTS_DIR}/info_output"
export IP_DATA_FILE_TMP="${IP_DATA_FILE}.tmp"
export DNSMASQ_DATA_FILE_TMP="${DNSMASQ_DATA_FILE}.tmp"
export UPDATE_STATUS_FILE_TMP="${UPDATE_STATUS_FILE}.tmp"
export USER_ENTRIES_STATUS_FILE_TMP="${USER_ENTRIES_STATUS_FILE}.tmp"
######################### External functions ###########################
@@ -310,26 +324,73 @@ MakeLogRecord() {
Download() {
$WGET_CMD $WGET_PARAMS "$1" "$2"
if [ $? -ne 0 ]; then
echo "Blacklist downloading failed! Connection error (${2})" >&2
MakeLogRecord "err" "Blacklist downloading failed! Connection error (${2})"
echo " Downloading failed! Connection error (${2})" >&2
MakeLogRecord "err" "Downloading failed! Connection error (${2})"
return 1
fi
}
DownloadRuabBlacklist() {
local _ip_data_file _dnsmasq_data_file _update_status_file _return_code=0
if [ "$ENABLE_TMP_DOWNLOADS" = "1" ]; then
_ip_data_file="$IP_DATA_FILE_TMP"
_dnsmasq_data_file="$DNSMASQ_DATA_FILE_TMP"
_update_status_file="$UPDATE_STATUS_FILE_TMP"
rm -f "$_ip_data_file" "$_dnsmasq_data_file" "$_update_status_file"
else
_ip_data_file="$IP_DATA_FILE"
_dnsmasq_data_file="$DNSMASQ_DATA_FILE"
_update_status_file="$UPDATE_STATUS_FILE"
fi
case "$1" in
"ip")
Download "$IP_DATA_FILE" "$RA_IP_IPSET_URL" && Download "$DNSMASQ_DATA_FILE" "$RA_IP_DMASK_URL" && Download "$UPDATE_STATUS_FILE" "$RA_IP_STAT_URL"
Download "$_ip_data_file" "$RA_IP_IPSET_URL"
if [ $? -ne 0 ]; then
_return_code=1
else
Download "$_dnsmasq_data_file" "$RA_IP_DMASK_URL"
if [ $? -ne 0 ]; then
_return_code=1
else
Download "$_update_status_file" "$RA_IP_STAT_URL"
if [ $? -ne 0 ]; then
_return_code=1
fi
fi
fi
;;
"fqdn")
Download "$DNSMASQ_DATA_FILE" "$RA_FQDN_DMASK_URL" && Download "$IP_DATA_FILE" "$RA_FQDN_IPSET_URL" && Download "$UPDATE_STATUS_FILE" "$RA_FQDN_STAT_URL"
Download "$_dnsmasq_data_file" "$RA_FQDN_DMASK_URL"
if [ $? -ne 0 ]; then
_return_code=1
else
Download "$_ip_data_file" "$RA_FQDN_IPSET_URL"
if [ $? -ne 0 ]; then
_return_code=1
else
Download "$_update_status_file" "$RA_FQDN_STAT_URL"
if [ $? -ne 0 ]; then
_return_code=1
fi
fi
fi
;;
*)
echo "Blacklist configuration error (${1})" >&2
echo " Blacklist configuration error (${1})" >&2
MakeLogRecord "err" "Blacklist configuration error (${1})"
exit 1
;;
esac
if [ "$ENABLE_TMP_DOWNLOADS" = "1" ]; then
if [ $_return_code -eq 0 ]; then
mv -f "$_ip_data_file" "$IP_DATA_FILE"
mv -f "$_dnsmasq_data_file" "$DNSMASQ_DATA_FILE"
mv -f "$_update_status_file" "$UPDATE_STATUS_FILE"
else
rm -f "$_ip_data_file" "$_dnsmasq_data_file" "$_update_status_file"
fi
fi
return $_return_code
}
RestartDnsmasq() {
@@ -437,6 +498,7 @@ ClearDataFiles() {
printf "" > "$DNSMASQ_DATA_FILE_BYPASS"
printf "" > "$IP_DATA_FILE"
printf "0 0 0" > "$UPDATE_STATUS_FILE"
printf "" > "$USER_ENTRIES_STATUS_FILE"
fi
}
@@ -453,69 +515,156 @@ PreStartCheck() {
[ -e "$DNSMASQ_DATA_FILE_BYPASS" ] || printf "" > "$DNSMASQ_DATA_FILE_BYPASS"
}
ParseUserEntries() {
$AWK_CMD -v IP_DATA_FILE="$1" -v DNSMASQ_DATA_FILE="$2" -v USER_ENTRIES_STATUS_FILE="$3" -v ID="$4" 'BEGIN {
null = "";
ip_array[0] = null;
cidr_array[0] = null;
fqdn_array[0] = null;
}
function writeIpList(array, _str) {
_str = "";
for(i in array) {
_str = _str i ",";
};
return _str;
};
function writeDNSData(val, dns) {
if(length(dns) == 0 && length(ENVIRON["USER_ENTRIES_DNS"]) > 0) {
dns = ENVIRON["USER_ENTRIES_DNS"];
};
if(length(dns) > 0) {
printf "server=/%s/%s\n", val, dns >> DNSMASQ_DATA_FILE;
};
printf "nftset=/%s/%s#%s\n", val, ENVIRON["NFT_TABLE_DNSMASQ"], ENVIRON["NFTSET_DNSMASQ"] >> DNSMASQ_DATA_FILE;
};
function writeFqdnEntries() {
delete fqdn_array[0];
for(i in fqdn_array) {
split(fqdn_array[i], a, " ");
writeDNSData(a[1], a[2]);
};
};
($0 !~ /^([\040\011]*$|#)/) {
if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}$/) {
ip_array[$0] = null;
}
else if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}[\057][0-9]{1,2}$/) {
cidr_array[$0] = null;
}
else if($0 ~ /^[a-z0-9.\052-]+[.]([a-z]{2,}|xn--[a-z0-9]+)([ ][0-9]{1,3}([.][0-9]{1,3}){3}([#][0-9]{2,5})?)?$/) {
fqdn_array[length(fqdn_array)] = $1 " " $2;
};
}
END {
ret_code = 0;
if($0 ~ /[0-9]+/) {
ret_code = $0;
};
delete cidr_array[0];
delete ip_array[0];
if(ret_code == 0 && (length(cidr_array) > 0 || length(ip_array) > 0)) {
printf "table %s {\n%s", ENVIRON["NFT_TABLE"], ENVIRON["NFTSET_CIDR_CFG"] >> IP_DATA_FILE;
if(length(cidr_array) > 0) {
printf "elements={%s};", writeIpList(cidr_array) >> IP_DATA_FILE;
};
printf "}\n%s", ENVIRON["NFTSET_IP_CFG"] >> IP_DATA_FILE;
if(length(ip_array) > 0) {
printf "elements={%s};", writeIpList(ip_array) >> IP_DATA_FILE;
};
printf "}\n}\n" >> IP_DATA_FILE;
};
writeFqdnEntries();
if(ret_code == 0) {
printf "%s %s %s %s\n", length(cidr_array), length(ip_array), length(fqdn_array), ID >> USER_ENTRIES_STATUS_FILE;
};
exit ret_code;
}' -
}
AddUserEntries() {
local _url _return_code=0 _attempt=1 _ip_data_file _dnsmasq_data_file _user_entries_status_file _str _update_string
if [ "$ADD_USER_ENTRIES" = "1" ]; then
if [ -f "$USER_ENTRIES_FILE" ]; then
$AWK_CMD 'BEGIN {
null = "";
ip_array[0] = null;
cidr_array[0] = null;
fqdn_array[0] = null;
}
function writeIpList(array, _str) {
_str = "";
for(i in array) {
_str = _str i ",";
};
return _str;
};
function writeDNSData(val, dns) {
if(length(dns) == 0 && length(ENVIRON["USER_ENTRIES_DNS"]) > 0) {
dns = ENVIRON["USER_ENTRIES_DNS"];
};
if(length(dns) > 0) {
printf "server=/%s/%s\n", val, dns >> ENVIRON["DNSMASQ_DATA_FILE"];
};
printf "nftset=/%s/%s#%s\n", val, ENVIRON["NFT_TABLE_DNSMASQ"], ENVIRON["NFTSET_DNSMASQ"] >> ENVIRON["DNSMASQ_DATA_FILE"];
};
function writeFqdnEntries() {
delete fqdn_array[0];
for(i in fqdn_array) {
split(fqdn_array[i], a, " ");
writeDNSData(a[1], a[2]);
};
};
($0 !~ /^([\040\011]*$|#)/) {
if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}$/) {
ip_array[$0] = null;
}
else if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}[\057][0-9]{1,2}$/) {
cidr_array[$0] = null;
}
else if($0 ~ /^[a-z0-9.\052-]+[.]([a-z]{2,}|xn--[a-z0-9]+)([ ][0-9]{1,3}([.][0-9]{1,3}){3}([#][0-9]{2,5})?)?$/) {
fqdn_array[length(fqdn_array)] = $1 " " $2;
};
}
END {
printf "table %s {\n%s", ENVIRON["NFT_TABLE"], ENVIRON["NFTSET_CIDR_CFG"] >> ENVIRON["IP_DATA_FILE"];
delete cidr_array[0];
if(length(cidr_array) > 0) {
printf "elements={%s};", writeIpList(cidr_array) >> ENVIRON["IP_DATA_FILE"];
};
printf "}\n%s", ENVIRON["NFTSET_IP_CFG"] >> ENVIRON["IP_DATA_FILE"];
delete ip_array[0];
if(length(ip_array) > 0) {
printf "elements={%s};", writeIpList(ip_array) >> ENVIRON["IP_DATA_FILE"];
};
printf "}\n}\n" >> ENVIRON["IP_DATA_FILE"];
writeFqdnEntries();
}' "$USER_ENTRIES_FILE"
if [ "$ENABLE_TMP_DOWNLOADS" = "1" ]; then
_ip_data_file="$IP_DATA_FILE_TMP"
_dnsmasq_data_file="$DNSMASQ_DATA_FILE_TMP"
_user_entries_status_file="$USER_ENTRIES_STATUS_FILE_TMP"
rm -f "$_ip_data_file" "$_dnsmasq_data_file" "$_user_entries_status_file"
else
_ip_data_file="$IP_DATA_FILE"
_dnsmasq_data_file="$DNSMASQ_DATA_FILE"
_user_entries_status_file="$USER_ENTRIES_STATUS_FILE"
fi
if [ "$1" = "flush" ]; then
if [ "$ENABLE_TMP_DOWNLOADS" != "1" ]; then
ClearDataFiles
fi
printf "flush set %s %s\nflush set %s %s\n" "$NFT_TABLE" "$NFTSET_CIDR" "$NFT_TABLE" "$NFTSET_IP" >> "$_ip_data_file"
else
printf "" > "$USER_ENTRIES_STATUS_FILE"
fi
if [ -f "$USER_ENTRIES_FILE" ]; then
{ cat "$USER_ENTRIES_FILE"; echo 0; } | ParseUserEntries "$_ip_data_file" "$_dnsmasq_data_file" "$_user_entries_status_file" "local"
fi
if [ -n "$USER_ENTRIES_REMOTE" ]; then
for _url in $USER_ENTRIES_REMOTE
do
_attempt=1
while :
do
if [ "$ENABLE_BLLIST_PROXY" = "1" ]; then
UpdateBllistProxySet
fi
{ Download - "$_url"; echo $?; } | ParseUserEntries "$_ip_data_file" "$_dnsmasq_data_file" "$_user_entries_status_file" "$_url"
if [ $? -eq 0 ]; then
break
else
_return_code=1
### STDOUT
echo " User entries download attempt ${_attempt}: failed [${_url}]" >&2
MakeLogRecord "err" "User entries download attempt ${_attempt}: failed [${_url}]"
_attempt=$(($_attempt + 1))
[ $_attempt -gt $USER_ENTRIES_REMOTE_DOWNLOAD_ATTEMPTS ] && break
sleep $USER_ENTRIES_REMOTE_DOWNLOAD_TIMEOUT
fi
done
done
if [ "$ENABLE_BLLIST_PROXY" = "1" ]; then
FlushNftSets "$NFTSET_BLLIST_PROXY"
fi
fi
if [ "$ENABLE_TMP_DOWNLOADS" = "1" ]; then
if [ $_return_code -eq 0 ]; then
if [ "$1" = "flush" ]; then
ClearDataFiles
fi
cat "$_ip_data_file" >> "$IP_DATA_FILE"
cat "$_dnsmasq_data_file" >> "$DNSMASQ_DATA_FILE"
mv -f "$_user_entries_status_file" "$USER_ENTRIES_STATUS_FILE"
fi
rm -f "$_ip_data_file" "$_dnsmasq_data_file" "$_user_entries_status_file"
fi
while read _str
do
_update_string=`printf "$_str" | $AWK_CMD '{
if(NF == 4) {
printf "User entries (%s): CIDR: %s, IP: %s, FQDN: %s", $4, $1, $2, $3;
};
}'`
if [ -n "$_update_string" ]; then
### STDOUT
echo " ${_update_string}"
MakeLogRecord "notice" "${_update_string}"
fi
done < "$USER_ENTRIES_STATUS_FILE"
else
printf "" > "$USER_ENTRIES_STATUS_FILE"
fi
}
AddBypassEntries() {
printf "" > "$DNSMASQ_DATA_FILE_BYPASS"
[ -d "$DATA_DIR" ] && printf "" > "$DNSMASQ_DATA_FILE_BYPASS"
FlushNftSets "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN"
if [ "$BYPASS_MODE" = "1" ]; then
if [ -f "$BYPASS_ENTRIES_FILE" ]; then
@@ -599,8 +748,6 @@ GetDataFiles() {
FlushNftSets "$NFTSET_BLLIST_PROXY"
fi
if [ $_return_code -eq 0 ]; then
AddUserEntries
AddBypassEntries
_update_string=`$AWK_CMD '{
printf "Received entries: %s\n", (NF < 3) ? "No data" : "CIDR: "$1", IP: "$2", FQDN: "$3;
exit;
@@ -609,11 +756,12 @@ GetDataFiles() {
echo " ${_update_string}"
MakeLogRecord "notice" "${_update_string}"
printf " `date +%d.%m.%Y-%H:%M`\n" >> "$UPDATE_STATUS_FILE"
AddUserEntries
AddBypassEntries
fi
elif [ -z "$BLLIST_PRESET" -a -z "$BLLIST_MODULE" ]; then
ClearDataFiles
ADD_USER_ENTRIES=1
AddUserEntries
AddUserEntries flush
AddBypassEntries
_return_code=0
else
@@ -654,8 +802,6 @@ Update() {
MakeLogRecord "notice" "${1}..."
if [ "$NFTSET_CLEAR_SETS" = "1" ]; then
FlushNftSets "$NFTSET_CIDR" "$NFTSET_IP" "$NFTSET_DNSMASQ"
elif [ -z "$BLLIST_PRESET" -a -z "$BLLIST_MODULE" ]; then
FlushNftSets "$NFTSET_IP" "$NFTSET_CIDR"
fi
GetDataFiles
case $? in
@@ -753,7 +899,7 @@ Reload() {
}
Status() {
local _update_status _vpn_error
local _update_status _user_entries_status _vpn_error
if [ -f "$UPDATE_STATUS_FILE" ]; then
_update_status=`$AWK_CMD '{
update_string=(NF < 4) ? "No data" : $4" (CIDR: "$1" | IP: "$2" | FQDN: "$3")";
@@ -762,10 +908,19 @@ Status() {
else
_update_status="Last blacklist update: No data"
fi
if [ -f "$USER_ENTRIES_STATUS_FILE" ]; then
_user_entries_status=`$AWK_CMD '{
if(NF == 4) {
printf " User entries (%s): CIDR: %s | IP: %s | FQDN: %s\n", $4, $1, $2, $3;
};
}' "$USER_ENTRIES_STATUS_FILE"`
fi
if [ "$PROXY_MODE" = "2" ] && ! NftVpnRouteStatus; then
_vpn_error="\033[1;31mVPN ROUTING ERROR! (NEED THE RESTART)\033[m"
fi
NftListBllistChain 2> /dev/null | $AWK_CMD -v UPDATE_STATUS="$_update_status" -v VPN_ERROR="$_vpn_error" '
NftListBllistChain 2> /dev/null | $AWK_CMD -v UPDATE_STATUS="$_update_status" -v USER_ENTRIES_STATUS="$_user_entries_status" -v VPN_ERROR="$_vpn_error" '
BEGIN {
rules_str = "";
nftset = "";
@@ -785,14 +940,14 @@ Status() {
printf "\n \033[1m" ENVIRON["NAME"] " status\033[m: \033[1mDisabled\033[m\n\n";
exit 2;
};
printf "\n \033[1m" ENVIRON["NAME"] " status\033[m: \033[1;32mEnabled\033[m\n\n PROXY_MODE: " ENVIRON["PROXY_MODE"] "\n PROXY_LOCAL_CLIENTS: " ENVIRON["PROXY_LOCAL_CLIENTS"] "\n BLLIST_PRESET: " ENVIRON["BLLIST_PRESET"] "\n BLLIST_MODULE: " ENVIRON["BLLIST_MODULE"] "\n";
printf "\n "UPDATE_STATUS"\n";
if(length(USER_ENTRIES_STATUS) > 0) {
printf "\n"USER_ENTRIES_STATUS"\n";
};
if(length(VPN_ERROR) > 0) {
printf "\n "VPN_ERROR"\n";
};
printf "\n \033[4mNftables rules\033[m:\n\n";
printf rules_str;
}'
@@ -809,7 +964,7 @@ StatusOutput() {
### Blacklist source and mode
case "$BLLIST_PRESET" in
zapret-info-ip)
### Источник для обновления списка блокировок (zapret-info, rublacklist, antifilter, ruantiblock)
### Источник для обновления списка блокировок (zapret-info, rublacklist, antifilter, fz, ruantiblock)
export BLLIST_SOURCE="zapret-info"
### Режим обхода блокировок: ip, fqdn
export BLLIST_MODE="ip"
@@ -1,5 +1,6 @@
UCI_SECTION="ruantiblock.config"
UCI_VARS="proxy_mode proxy_local_clients nftset_clear_sets allowed_hosts_mode allowed_hosts_list bypass_mode bypass_entries_dns enable_fproxy fproxy_list enable_bllist_proxy if_vpn vpn_gw_ip vpn_route_check tor_trans_port onion_dns_addr t_proxy_port_tcp t_proxy_port_udp t_proxy_allow_udp add_user_entries user_entries_dns enable_logging bllist_min_entries bllist_module bllist_preset bllist_ip_limit bllist_gr_excluded_nets bllist_summarize_ip bllist_summarize_cidr bllist_ip_filter bllist_ip_filter_type bllist_sd_limit bllist_gr_excluded_sld bllist_fqdn_filter bllist_fqdn_filter_type bllist_enable_idn bllist_alt_nslookup bllist_alt_dns_addr update_at_startup"
UCI_VARS="proxy_mode proxy_local_clients nftset_clear_sets allowed_hosts_mode allowed_hosts_list bypass_mode bypass_entries_dns enable_fproxy fproxy_list enable_bllist_proxy if_vpn vpn_gw_ip vpn_route_check tor_trans_port onion_dns_addr t_proxy_port_tcp t_proxy_port_udp t_proxy_allow_udp add_user_entries user_entries_dns user_entries_remote enable_logging bllist_min_entries bllist_module bllist_preset bllist_ip_limit bllist_gr_excluded_nets bllist_summarize_ip bllist_summarize_cidr bllist_ip_filter bllist_ip_filter_type bllist_sd_limit bllist_gr_excluded_sld bllist_fqdn_filter bllist_fqdn_filter_type bllist_enable_idn bllist_alt_nslookup bllist_alt_dns_addr update_at_startup enable_tmp_downloads"
UCI_CMD=`which uci`
if [ $? -ne 0 ]; then
echo " Error! UCI doesn't exists" >&2
@@ -2,15 +2,38 @@ Info() {
local _update_status
if [ -f "$UPDATE_STATUS_FILE" ]; then
_update_status=`$AWK_CMD '{
if(NF < 4)
if(NF < 4) {
printf "{\"status\":false}";
else
} else {
printf "{\"status\":true,\"date\":\""$4"\",\"cidr\":\""$1"\",\"ip\":\""$2"\",\"fqdn\":\""$3"\"}";
};
}' "$UPDATE_STATUS_FILE"`
else
_update_status="{\"status\":false}"
fi
NftListBllistChainJson 2> /dev/null | $AWK_CMD -v UPDATE_STATUS="$_update_status" '
if [ -f "$USER_ENTRIES_STATUS_FILE" ]; then
_user_entries_status=`$AWK_CMD '
BEGIN {
items = 0;
printf "[";
}
{
if(NF == 4) {
gsub("/", "\134\134/", $4);
if(items >= 1) {
printf ",";
};
printf "{\"id\":\""$4"\",\"cidr\":\""$1"\",\"ip\":\""$2"\",\"fqdn\":\""$3"\"}";
items++;
};
}
END {
printf "]";
}' "$USER_ENTRIES_STATUS_FILE"`
else
_user_entries_status="[]"
fi
NftListBllistChainJson 2> /dev/null | $AWK_CMD -v UPDATE_STATUS="$_update_status" -v USER_ENTRIES_STATUS="$_user_entries_status" '
BEGIN {
rules_str = "";
}
@@ -22,7 +45,7 @@ Info() {
printf "{\"status\": \"disabled\"}";
exit 1;
} else {
printf "{\"status\":\"enabled\",\"last_blacklist_update\":%s,\"rules\":%s", UPDATE_STATUS, rules_str;
printf "{\"status\":\"enabled\",\"last_blacklist_update\":%s,\"user_entries\":%s,\"rules\":%s", UPDATE_STATUS, USER_ENTRIES_STATUS, rules_str;
exit 0;
};
}'