diff --git a/luci-app-ruantiblock/Makefile b/luci-app-ruantiblock/Makefile index dc9a7db..a4f76fc 100644 --- a/luci-app-ruantiblock/Makefile +++ b/luci-app-ruantiblock/Makefile @@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk -PKG_VERSION:=1.2-1 +PKG_VERSION:=1.2-2 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 5d9c030..6062244 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 @@ -47,6 +47,7 @@ return view.extend({ if(data.rules.nftables && data.rules.nftables.length > 1) { for(let i of data.rules.nftables) { if(!i.rule) continue; + let set, bytes; i.rule.expr.forEach(e => { if(e.match && e.match.left && e.match.left.payload) { @@ -75,7 +76,12 @@ return view.extend({ return sArray; }; - output.dnsmasq = parseDnsmasqData('dnsmasq'); + if(data.dnsmasq) { + output.dnsmasq = parseDnsmasqData('dnsmasq'); + }; + if(data.dnsmasq_bypass) { + output.dnsmasq_bypass = parseDnsmasqData('dnsmasq_bypass'); + }; }; return output; }, @@ -177,8 +183,16 @@ return view.extend({ }; let rdTableWrapper = document.getElementById('rdTableWrapper'); - rdTableWrapper.innerHTML = ''; - rdTableWrapper.append(this.makeDnsmasqTable(nft_data.dnsmasq)); + if(rdTableWrapper) { + rdTableWrapper.innerHTML = ''; + rdTableWrapper.append(this.makeDnsmasqTable(nft_data.dnsmasq)); + }; + + let rdbTableWrapper = document.getElementById('rdbTableWrapper'); + if(rdbTableWrapper) { + rdbTableWrapper.innerHTML = ''; + rdbTableWrapper.append(this.makeDnsmasqTable(nft_data.dnsmasq_bypass)); + }; } else { if(poll.active()) { @@ -207,7 +221,9 @@ return view.extend({ let update_status = null, rules = null, - dnsmasq = null; + dnsmasq = null, + dnsmasqBypass = null; + if(data) { if(data.status === 'enabled') { update_status = E('table', { 'class': 'table' }); @@ -270,7 +286,9 @@ return view.extend({ E('td',{ 'class' : 'td left', 'data-title': _('Match-set'), - }, set + ((set.length == 1) ? (' (' + set.replace(/^c/, 'CIDR').replace(/^i/, 'IP').replace(/^d/, 'dnsmasq') + ')') : '')), + }, set + ((set.length >= 1) ? ( + ' (' + set.replace(/^c/, 'CIDR').replace(/^i/, 'IP').replace(/^d/, 'dnsmasq').replace(/^bi/, 'bypass IP').replace(/^bd/, 'bypass dnsmasq') + ')' + ) : '')), E('td', { 'class' : 'td left', 'id' : 'rules.' + set, @@ -298,12 +316,25 @@ return view.extend({ ]); }; + if(nft_data.dnsmasq_bypass) { + let rdbTableWrapper = E('div', { + 'id' : 'rdbTableWrapper', + 'style': 'width:100%' + }, this.makeDnsmasqTable(nft_data.dnsmasq_bypass)); + + dnsmasqBypass = E([ + E('h3', {}, _('Dnsmasq bypass')), + rdbTableWrapper, + ]); + }; + poll.add(L.bind(this.pollInfo, this), this.pollInterval); } else { update_status = E('em', {}, _('Status') + ' : ' + _('disabled')); }; }; - return E([ + + let layout = [ E('h2', { 'class': 'fade-in' }, _('Ruantiblock') + ' - ' + _('Statistics') ), @@ -314,10 +345,25 @@ return view.extend({ E('div', { 'class': 'cbi-section fade-in' }, E('div', { 'class': 'cbi-section-node' }, rules) ), - E('div', { 'class': 'cbi-section fade-in' }, - E('div', { 'class': 'cbi-section-node' }, dnsmasq) - ), - ]); + ]; + + if(dnsmasqBypass) { + layout.splice(4, 0, + E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, dnsmasqBypass) + ) + ); + }; + + if(dnsmasq) { + layout.splice(5, 0, + E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, dnsmasq) + ) + ); + }; + + return E(layout); }, handleSave : null, diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/settings.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/settings.js index 36416b5..73705f7 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/settings.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/settings.js @@ -90,6 +90,13 @@ return view.extend({ '
#comment
domain.net
sub.domain.com 8.8.8.8
sub.domain.com 8.8.8.8#53
74.125.131.19
74.125.0.0/16
' ); + let bypass_entries_edit = new tools.fileEditDialog( + tools.bypassEntriesFile, + _('Exclusion list'), + _('One entry (IP, CIDR or FQDN) per line. In the FQDN records, you can specify the DNS server for resolving this domain (separated by a space). You can also comment on lines (# is the first character of a line).
Examples:') + + '
#comment
domain.net
sub.domain.com 8.8.8.8
sub.domain.com 8.8.8.8#53
74.125.131.19
74.125.0.0/16
' + ); + let torrc_edit = new tools.fileEditDialog( tools.torrcFile, _('Tor configuration file'), @@ -249,19 +256,45 @@ return view.extend({ bllist_module.value('', _('disabled')); bllist_module.depends({ bllist_preset: new RegExp('^($|' + tools.appName + ')'), '!reverse': true }); - // BYPASS_IP_MODE - o = s.taboption('blacklist_tab', form.Flag, 'bypass_ip_mode', - _('Enable IP exclusion list'), _("List of IP addresses that are excluded from block bypass (always available directly)")); + Object.entries(this.parsers).forEach( + e => bllist_module.value(e[1], e[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")); + o.rmempty = false; + o.default = 0; + o.depends({ bllist_preset: '', '!reverse': true }); + + // USER_ENTRIES edit dialog + o = s.taboption('blacklist_tab', form.Button, '_user_entries_btn', + _('User entries')); + o.onclick = () => user_entries_edit.show(); + o.inputtitle = _('Edit'); + o.inputstyle = 'edit btn'; + + // USER_ENTRIES_DNS + o = s.taboption('blacklist_tab', form.Value, 'user_entries_dns', + _("DNS server that is used for the user's FQDN entries"), 'ipaddress[#port]'); + o.validate = this.validateIpPort; + + // BYPASS_MODE + o = s.taboption('blacklist_tab', form.Flag, 'bypass_mode', + _('Enable exclusion list'), _("List of hosts that are excluded from block bypass (always available directly)")); o.rmempty = false; o.default = 0; - // BYPASS_IP_LIST - o = s.taboption('blacklist_tab', form.DynamicList, 'bypass_ip_list', - _('IP exclusion list')); - o.datatype = "ip4addr"; + // BYPASS_ENTRIES edit dialog + o = s.taboption('blacklist_tab', form.Button, '_bypass_entries_btn', + _('Exclusion list')); + o.onclick = () => bypass_entries_edit.show(); + o.inputtitle = _('Edit'); + o.inputstyle = 'edit btn'; - Object.entries(this.parsers).forEach( - e => bllist_module.value(e[1], e[0])); + // 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"), 'ipaddress[#port]'); + o.validate = this.validateIpPort; if(availableParsers) { bllist_preset.description += '
( * - ' + _('requires installed blacklist module') + ' )'; @@ -374,30 +407,6 @@ return view.extend({ }; - - /* User entries tab */ - - s.tab('user_entries_tab', _('User entries')); - - // ADD_USER_ENTRIES - o = s.taboption('user_entries_tab', form.Flag, 'add_user_entries', - _('Enable'), _("Add user entries to the blacklist when updating")); - o.rmempty = false; - o.default = 0; - o.depends({ bllist_preset: '', '!reverse': true }); - - // USER_ENTRIES_DNS - o = s.taboption('user_entries_tab', form.Value, 'user_entries_dns', - _("DNS server that is used for FQDN entries"), 'ipaddress[#port]'); - o.validate = this.validateIpPort; - - // USER_ENTRIES edit dialog - o = s.taboption('user_entries_tab', form.Button, '_user_entries_btn', - _('User entries')); - o.onclick = () => user_entries_edit.show(); - o.inputtitle = _('Edit'); - o.inputstyle = 'edit btn'; - let map_promise = m.render(); map_promise.then(node => node.classList.add('fade-in')); return map_promise; 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 bca5159..1a8f2c7 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 @@ -40,6 +40,7 @@ return baseclass.extend({ parsersDir : '/usr/libexec/ruantiblock', torrcFile : '/etc/tor/torrc', userEntriesFile : '/etc/ruantiblock/user_entries', + bypassEntriesFile: '/etc/ruantiblock/bypass_entries', fqdnFilterFile : '/etc/ruantiblock/fqdn_filter', ipFilterFile : '/etc/ruantiblock/ip_filter', crontabFile : '/etc/crontabs/root', diff --git a/luci-app-ruantiblock/po/ru/ruantiblock.po b/luci-app-ruantiblock/po/ru/ruantiblock.po index b6fafe3..d6b918f 100644 --- a/luci-app-ruantiblock/po/ru/ruantiblock.po +++ b/luci-app-ruantiblock/po/ru/ruantiblock.po @@ -86,8 +86,11 @@ msgstr "Критическая ситуация" msgid "Current schedule" msgstr "Текущее расписание" -msgid "DNS server that is used for FQDN entries" -msgstr "DNS сервер для FQDN записей" +msgid "DNS server that is used for the user's FQDN entries" +msgstr "DNS сервер для FQDN записей пользователя" + +msgid "DNS server that is used for the FQDN entries of exclusion list" +msgstr "DNS сервер для FQDN записей списка исключений" msgid "Day" msgstr "День" @@ -119,12 +122,15 @@ msgstr "Включить" msgid "Enable FQDN filter" msgstr "Включить FQDN фильтр" -msgid "Enable IP exclusion list" -msgstr "Включить список исключений IP адресов" - msgid "Enable IP filter" msgstr "Включить IP фильтр" +msgid "Enable exclusion list" +msgstr "Включить список исключений" + +msgid "Enable user entries" +msgstr "Включить записи пользователя" + msgid "Enabled" msgstr "Включено" @@ -134,6 +140,9 @@ msgstr "Записи" msgid "Error" msgstr "Ошибка" +msgid "Exclusion list" +msgstr "Список исключений" + msgid "Expecting:" msgstr "Ожидается:" @@ -170,9 +179,6 @@ msgstr "IP-адрес" msgid "IP addresses of hosts" msgstr "IP-адреса хостов" -msgid "IP exclusion list" -msgstr "Список исключенных IP адресов" - msgid "IP filter" msgstr "Фильтр IP" @@ -209,8 +215,8 @@ msgstr "Последние записи" msgid "Level" msgstr "Уровень" -msgid "List of IP addresses that are excluded from block bypass (always available directly)" -msgstr "Список IP адресов, которые исключаются из обхода блокировок (всегда доступны напрямую)" +msgid "List of hosts that are excluded from block bypass (always available directly)" +msgstr "Список хостов, которые исключаются из обхода блокировок (всегда доступны напрямую)" msgid "Loading" msgstr "Загрузка" diff --git a/luci-app-ruantiblock/po/templates/ruantiblock.pot b/luci-app-ruantiblock/po/templates/ruantiblock.pot index 5c1b5f4..fe3ec38 100644 --- a/luci-app-ruantiblock/po/templates/ruantiblock.pot +++ b/luci-app-ruantiblock/po/templates/ruantiblock.pot @@ -71,7 +71,10 @@ msgstr "" msgid "Current schedule" msgstr "" -msgid "DNS server that is used for FQDN entries" +msgid "DNS server that is used for the user's FQDN entries" +msgstr "" + +msgid "DNS server that is used for the FQDN entries of exclusion list" msgstr "" msgid "Day" @@ -102,10 +105,13 @@ msgstr "" msgid "Enable FQDN filter" msgstr "" -msgid "Enable IP exclusion list" +msgid "Enable IP filter" msgstr "" -msgid "Enable IP filter" +msgid "Enable exclusion list" +msgstr "" + +msgid "Enable user entries" msgstr "" msgid "Enabled" @@ -117,6 +123,9 @@ msgstr "" msgid "Error" msgstr "" +msgid "Exclusion list" +msgstr "" + msgid "Expecting:" msgstr "" @@ -153,9 +162,6 @@ msgstr "" msgid "IP addresses of hosts" msgstr "" -msgid "IP exclusion list" -msgstr "" - msgid "IP filter" msgstr "" @@ -189,7 +195,7 @@ msgstr "" msgid "Level" msgstr "" -msgid "List of IP addresses that are excluded from block bypass (always available directly)" +msgid "List of hosts that are excluded from block bypass (always available directly)" msgstr "" msgid "Loading" diff --git a/luci-app-ruantiblock/root/usr/share/rpcd/acl.d/luci-app-ruantiblock.json b/luci-app-ruantiblock/root/usr/share/rpcd/acl.d/luci-app-ruantiblock.json index c9dcb06..9dd3814 100644 --- a/luci-app-ruantiblock/root/usr/share/rpcd/acl.d/luci-app-ruantiblock.json +++ b/luci-app-ruantiblock/root/usr/share/rpcd/acl.d/luci-app-ruantiblock.json @@ -8,6 +8,7 @@ "/etc/ruantiblock/fqdn_filter": [ "read" ], "/etc/ruantiblock/ip_filter": [ "read" ], "/etc/ruantiblock/user_entries": [ "read" ], + "/etc/ruantiblock/bypass_entries": [ "read" ], "/var/run/ruantiblock.token": [ "read" ], "/etc/tor/torrc": [ "read" ], "/etc/crontabs/root": [ "read" ], @@ -25,6 +26,7 @@ "/etc/ruantiblock/fqdn_filter": [ "write" ], "/etc/ruantiblock/ip_filter": [ "write" ], "/etc/ruantiblock/user_entries": [ "write" ], + "/etc/ruantiblock/bypass_entries": [ "write" ], "/etc/tor/torrc": [ "write" ], "/etc/crontabs/root": [ "write" ] }, diff --git a/ruantiblock/Makefile b/ruantiblock/Makefile index 261d839..81e4551 100644 --- a/ruantiblock/Makefile +++ b/ruantiblock/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ruantiblock PKG_VERSION:=1.2 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_MAINTAINER:=gSpot include $(INCLUDE_DIR)/package.mk @@ -29,6 +29,7 @@ define Package/$(PKG_NAME)/conffiles /etc/ruantiblock/fqdn_filter /etc/ruantiblock/ip_filter /etc/ruantiblock/user_entries +/etc/ruantiblock/bypass_entries endef define Build/Configure @@ -49,6 +50,7 @@ define Package/$(PKG_NAME)/install $(INSTALL_DATA) ./files/etc/ruantiblock/fqdn_filter $(1)/etc/ruantiblock/fqdn_filter $(INSTALL_DATA) ./files/etc/ruantiblock/ip_filter $(1)/etc/ruantiblock/ip_filter $(INSTALL_DATA) ./files/etc/ruantiblock/user_entries $(1)/etc/ruantiblock/user_entries + $(INSTALL_DATA) ./files/etc/ruantiblock/bypass_entries $(1)/etc/ruantiblock/bypass_entries $(INSTALL_DIR) $(1)/usr/share/ruantiblock $(INSTALL_DATA) ./files/usr/share/ruantiblock/config_script $(1)/usr/share/ruantiblock/config_script $(INSTALL_DATA) ./files/usr/share/ruantiblock/info_output $(1)/usr/share/ruantiblock/info_output @@ -73,9 +75,10 @@ define Package/$(PKG_NAME)/prerm FILE_INIT_SCRIPT="/etc/init.d/ruantiblock" FILE_MAIN_SCRIPT="/usr/bin/ruantiblock" CRONTAB_FILE="/etc/crontabs/root" -DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/ruantiblock.dnsmasq" +DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/02-ruantiblock.dnsmasq" +DNSMASQ_DATA_FILE_BYPASS="/tmp/dnsmasq.d/01-ruantiblock_bypass.dnsmasq" -rm -f $$DNSMASQ_DATA_FILE +rm -f $$DNSMASQ_DATA_FILE $$DNSMASQ_DATA_FILE_BYPASS test -e "$$FILE_MAIN_SCRIPT" && $$FILE_MAIN_SCRIPT destroy test -e "$$FILE_INIT_SCRIPT" && $$FILE_INIT_SCRIPT disable diff --git a/ruantiblock/files/etc/config/ruantiblock b/ruantiblock/files/etc/config/ruantiblock index 80db80f..535fefd 100644 --- a/ruantiblock/files/etc/config/ruantiblock +++ b/ruantiblock/files/etc/config/ruantiblock @@ -4,7 +4,7 @@ config main 'config' option proxy_local_clients '1' option nftset_clear_sets '1' option allowed_hosts_mode '0' - option bypass_ip_mode '0' + option bypass_mode '0' option if_vpn 'tun0' option tor_trans_port '9040' option tor_allow_udp '0' diff --git a/ruantiblock/files/etc/ruantiblock/bypass_entries b/ruantiblock/files/etc/ruantiblock/bypass_entries new file mode 100644 index 0000000..e69de29 diff --git a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf index 39eaca0..4fd21e9 100644 --- a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf +++ b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf @@ -6,7 +6,8 @@ DATA_DIR="/tmp/ruantiblock" ### Директория модулей MODULES_DIR="/usr/libexec/ruantiblock" ### Дополнительный конфиг dnsmasq с FQDN записями блэклиста -DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/ruantiblock.dnsmasq" +DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/02-ruantiblock.dnsmasq" +DNSMASQ_DATA_FILE_BYPASS="/tmp/dnsmasq.d/01-ruantiblock_bypass.dnsmasq" ### Команда для перезапуска dnsmasq DNSMASQ_RESTART_CMD="/etc/init.d/dnsmasq restart" ### Директория для html-страницы статуса (не используется в OpenWrt) @@ -22,10 +23,6 @@ NFTSET_CLEAR_SETS=0 ALLOWED_HOSTS_MODE=0 ### Список IP адресов хостов для фильтра, через пробел (прим.: 192.168.0.10 192.168.0.15) ALLOWED_HOSTS_LIST="" -### Режим списка IP адресов исключаемых из обхода блокировок (0 - выкл, 1 - вкл) -BYPASS_IP_MODE=0 -### Список IP адресов, которые исключаются из обхода блокировок, через пробел (прим.: 52.49.102.199 52.49.102.200) -BYPASS_IP_LIST="" ### VPN интерфейс для правил маршрутизации IF_VPN="tun0" ### Порт прозрачного прокси Tor (параметр TransPort в torrc) @@ -34,7 +31,7 @@ TOR_TRANS_PORT=9040 TOR_ALLOW_UDP=0 ### DNS-сервер для резолвинга в домене .onion (Tor) ONION_DNS_ADDR="127.0.0.1#9053" -### --set-mark для отбора пакетов в VPN туннель +### метка для отбора пакетов в VPN туннель VPN_PKTS_MARK=8 ### Приоритет правила отбора пакетов при маршрутизации в VPN-интерфейс VPN_RULE_PRIO=1000 @@ -44,25 +41,16 @@ T_PROXY_PORT_TCP=1100 T_PROXY_PORT_UDP=1100 ### Отправлять в прозрачный прокси UDP-трафик (0 - выкл, 1 - вкл) T_PROXY_ALLOW_UDP=0 -### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - выкл, 1 - вкл) -### В $DATA_DIR можно создать текстовый файл user_entries с записями IP, CIDR или FQDN (одна на строку). Эти записи будут добавлены в список блокировок -### В записях FQDN можно задать DNS-сервер для разрешения данного домена, через пробел (прим.: domain.com 8.8.8.8) -### Можно комментировать строки (#) -ADD_USER_ENTRIES=0 -### DNS-сервер для пользовательских записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет -USER_ENTRIES_DNS="" -### Файл пользовательских записей -USER_ENTRIES_FILE="/etc/ruantiblock/user_entries" ### Запись событий в syslog (0 - выкл, 1 - вкл) ENABLE_LOGGING=1 ### Html-страница с инфо о текущем статусе (0 - выкл, 1 - вкл) (не используется в OpenWrt) ENABLE_HTML_INFO=0 -### метка для отбора пакетов в VPN туннель -VPN_PKTS_MARK=8 ### Максимальное кол-во элементов списка nftables #NFTSET_MAXELEM_CIDR=65535 NFTSET_MAXELEM_IP=1000000 NFTSET_MAXELEM_DNSMASQ=65535 +NFTSET_MAXELEM_BYPASS_IP=65535 +NFTSET_MAXELEM_BYPASS_FQDN=65535 ### Политика отбора элементов в сетах nftables. "performance" - производительность и большее потребление RAM. "memory" - хуже производительность и меньше потребление RAM NFTSET_POLICY_CIDR="memory" NFTSET_POLICY_IP="memory" @@ -79,6 +67,21 @@ NFT_PRIO_NAT_LOCAL="filter - 10" NFT_PRIO_ROUTE="mangle + 10" ### Приоритет правила отбора пакетов nftables для трафика локальных клиентов в VPN-конфигурации NFT_PRIO_ROUTE_LOCAL="mangle + 10" +### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - выкл, 1 - вкл) +### В $DATA_DIR можно создать текстовый файл user_entries с записями IP, CIDR или FQDN (одна на строку). Эти записи будут добавлены в список блокировок +### В записях FQDN можно задать DNS-сервер для разрешения данного домена, через пробел (прим.: domain.com 8.8.8.8) +### Можно комментировать строки (#) +ADD_USER_ENTRIES=0 +### DNS-сервер для пользовательских записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет +USER_ENTRIES_DNS="" +### Файл пользовательских записей +USER_ENTRIES_FILE="/etc/ruantiblock/user_entries" +### Режим списка записей, исключаемых из обхода блокировок (0 - выкл, 1 - вкл) +BYPASS_MODE=0 +### DNS-сервер для исключаемых записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет +BYPASS_ENTRIES_DNS="" +### Файл исключаемых записей +BYPASS_ENTRIES_FILE="/etc/ruantiblock/bypass_entries" ### Кол-во попыток обновления блэклиста (в случае неудачи) MODULE_RUN_ATTEMPTS=3 ### Таймаут между попытками обновления diff --git a/ruantiblock/files/usr/bin/ruantiblock b/ruantiblock/files/usr/bin/ruantiblock index 8db14a1..951f7bc 100755 --- a/ruantiblock/files/usr/bin/ruantiblock +++ b/ruantiblock/files/usr/bin/ruantiblock @@ -19,7 +19,8 @@ SCRIPTS_DIR="/usr/share/${NAME}" export DATA_DIR="${CONFIG_DIR}/var" export MODULES_DIR="/usr/libexec/${NAME}" ### Дополнительный конфиг dnsmasq с FQDN записями блэклиста -export DNSMASQ_DATA_FILE="/var/dnsmasq.d/${NAME}.dnsmasq" +export DNSMASQ_DATA_FILE="/var/dnsmasq.d/02-${NAME}.dnsmasq" +export DNSMASQ_DATA_FILE_BYPASS="/var/dnsmasq.d/01-${NAME}_bypass.dnsmasq" ### Команда для перезапуска dnsmasq export DNSMASQ_RESTART_CMD="/etc/init.d/dnsmasq restart" ### Директория для html-страницы статуса (не используется в OpenWrt) @@ -37,10 +38,6 @@ export NFTSET_CLEAR_SETS=0 export ALLOWED_HOSTS_MODE=0 ### Список IP адресов хостов для фильтра, через пробел (прим.: 192.168.0.10 192.168.0.15) export ALLOWED_HOSTS_LIST="" -### Режим списка IP адресов исключаемых из обхода блокировок (0 - выкл, 1 - вкл) -export BYPASS_IP_MODE=0 -### Список IP адресов, которые исключаются из обхода блокировок, через пробел (прим.: 52.49.102.199 52.49.102.200) -export BYPASS_IP_LIST="" ### VPN интерфейс для правил маршрутизации export IF_VPN="tun0" ### Порт прозрачного прокси Tor (параметр TransPort в torrc) @@ -49,7 +46,7 @@ export TOR_TRANS_PORT=9040 export TOR_ALLOW_UDP=0 ### DNS-сервер для резолвинга в домене .onion (Tor) export ONION_DNS_ADDR="127.0.0.1#9053" -### --set-mark для отбора пакетов в VPN туннель +### метка для отбора пакетов в VPN туннель export VPN_PKTS_MARK=8 ### Приоритет правила отбора пакетов при маршрутизации в VPN-интерфейс export VPN_RULE_PRIO=1000 @@ -59,15 +56,6 @@ export T_PROXY_PORT_TCP=1100 export T_PROXY_PORT_UDP=1100 ### Отправлять в прозрачный прокси UDP-трафик (0 - выкл, 1 - вкл) export T_PROXY_ALLOW_UDP=0 -### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - выкл, 1 - вкл) -### В $DATA_DIR можно создать текстовый файл user_entries с записями IP, CIDR или FQDN (одна на строку). Эти записи будут добавлены в список блокировок -### В записях FQDN можно задать DNS-сервер для разрешения данного домена, через пробел (прим.: domain.com 8.8.8.8) -### Можно комментировать строки (#) -export ADD_USER_ENTRIES=0 -### DNS-сервер для пользовательских записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет -export USER_ENTRIES_DNS="" -### Файл пользовательских записей -export USER_ENTRIES_FILE="${CONFIG_DIR}/user_entries" ### Запись событий в syslog (0 - выкл, 1 - вкл) export ENABLE_LOGGING=1 ### Html-страница с инфо о текущем статусе (0 - выкл, 1 - вкл) (не используется в OpenWrt) @@ -76,6 +64,8 @@ export ENABLE_HTML_INFO=0 export NFTSET_MAXELEM_CIDR=65535 export NFTSET_MAXELEM_IP=1000000 export NFTSET_MAXELEM_DNSMASQ=65535 +export NFTSET_MAXELEM_BYPASS_IP=65535 +export NFTSET_MAXELEM_BYPASS_FQDN=65535 ### Политика отбора элементов в сетах nftables. "performance" - производительность и большее потребление RAM. "memory" - хуже производительность и меньше потребление RAM export NFTSET_POLICY_CIDR="memory" export NFTSET_POLICY_IP="memory" @@ -92,6 +82,21 @@ export NFT_PRIO_NAT_LOCAL="filter - 10" export NFT_PRIO_ROUTE="mangle + 10" ### Приоритет правила отбора пакетов nftables для трафика локальных клиентов в VPN-конфигурации export NFT_PRIO_ROUTE_LOCAL="mangle + 10" +### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - выкл, 1 - вкл) +### В $DATA_DIR можно создать текстовый файл user_entries с записями IP, CIDR или FQDN (одна на строку). Эти записи будут добавлены в список блокировок +### В записях FQDN можно задать DNS-сервер для разрешения данного домена, через пробел (прим.: domain.com 8.8.8.8) +### Можно комментировать строки (#) +export ADD_USER_ENTRIES=0 +### DNS-сервер для пользовательских записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет +export USER_ENTRIES_DNS="" +### Файл пользовательских записей +export USER_ENTRIES_FILE="${CONFIG_DIR}/user_entries" +### Режим списка IP адресов исключаемых из обхода блокировок (0 - выкл, 1 - вкл) +export BYPASS_MODE=0 +### DNS-сервер для исключаемых записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет +export BYPASS_ENTRIES_DNS="" +### Файл исключаемых записей +export BYPASS_ENTRIES_FILE="${CONFIG_DIR}/bypass_entries" ### Кол-во попыток обновления блэклиста (в случае неудачи) export MODULE_RUN_ATTEMPTS=3 ### Таймаут между попытками обновления @@ -194,18 +199,21 @@ export IP_DATA_FILE="${DATA_DIR}/${NAME}.ip" export NFT_TABLE="ip r" export NFT_TABLE_DNSMASQ="4#ip#r" export NFTSET_ALLOWED_HOSTS="allowed_ip" -export NFTSET_BYPASS_IP="bypass_ip" +export NFTSET_BYPASS_IP="bi" +export NFTSET_BYPASS_FQDN="bd" export NFTSET_ONION="onion" export NFTSET_CIDR="c" export NFTSET_IP="i" export NFTSET_DNSMASQ="d" export NFTSET_ALLOWED_HOSTS_TYPE="ipv4_addr" export NFTSET_BYPASS_IP_TYPE="ipv4_addr" +export NFTSET_BYPASS_FQDN_TYPE="ipv4_addr" export NFTSET_CIDR_TYPE="ipv4_addr" export NFTSET_IP_TYPE="ipv4_addr" export NFTSET_DNSMASQ_TYPE="ipv4_addr" export NFTSET_CIDR_CFG="set ${NFTSET_CIDR} {type ${NFTSET_CIDR_TYPE};size ${NFTSET_MAXELEM_CIDR};policy ${NFTSET_POLICY_CIDR};flags interval;auto-merge;" 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" U_PID_FILE="/var/run/${NAME}_update.pid" START_PID_FILE="/var/run/${NAME}_start.pid" @@ -236,7 +244,7 @@ cat << EOF reload : Renew nftables configuration update : Update blacklist force-update : Force update blacklist - data-files : Create ${IP_DATA_FILE} & ${DNSMASQ_DATA_FILE} (without network functions) + data-files : Create ${IP_DATA_FILE}, ${DNSMASQ_DATA_FILE}, ${DNSMASQ_DATA_FILE_BYPASS} (without network functions) status : Status & some info raw-status : Return code: 0 - enabled, 1 - error, 2 - disabled, 3 - starting, 4 - updating html-info : Return the html-info output @@ -311,11 +319,8 @@ AddNftSets() { if [ -n "$_allowed_hosts" ]; then $NFT_CMD add element $NFT_TABLE "$NFTSET_ALLOWED_HOSTS" { "$_allowed_hosts" } fi - $NFT_CMD add set $NFT_TABLE "$NFTSET_BYPASS_IP" { type "$NFTSET_BYPASS_IP_TYPE"\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; } - _bypass_ips=`printf "$BYPASS_IP_LIST" | $AWK_CMD '{gsub(/[ ]+/, ",", $0); printf $0;}'` - if [ -n "$_bypass_ips" ]; then - $NFT_CMD add element $NFT_TABLE "$NFTSET_BYPASS_IP" { "$_bypass_ips" } - fi + $NFT_CMD add set $NFT_TABLE "$NFTSET_BYPASS_IP" { type "$NFTSET_BYPASS_IP_TYPE"\; size $NFTSET_MAXELEM_BYPASS_IP\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; } + $NFT_CMD add set $NFT_TABLE "$NFTSET_BYPASS_FQDN" { type "$NFTSET_BYPASS_FQDN_TYPE"\; size $NFTSET_MAXELEM_BYPASS_FQDN\; policy "$NFTSET_POLICY_DNSMASQ"\; flags dynamic,timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; } } UpdateBllistSets() { @@ -353,7 +358,7 @@ SetNetConfig() { DropNetConfig() { DeleteNftRules - FlushNftSets "$NFTSET_ALLOWED_HOSTS" "$NFTSET_BYPASS_IP" "$NFTSET_CIDR" "$NFTSET_IP" "$NFTSET_DNSMASQ" "$NFTSET_ONION" + FlushNftSets "$NFTSET_ALLOWED_HOSTS" "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN" "$NFTSET_CIDR" "$NFTSET_IP" "$NFTSET_DNSMASQ" "$NFTSET_ONION" } DestroyNetConfig() { @@ -364,6 +369,7 @@ DestroyNetConfig() { ClearDataFiles() { if [ -d "$DATA_DIR" ]; then printf "" > "$DNSMASQ_DATA_FILE" + printf "" > "$DNSMASQ_DATA_FILE_BYPASS" printf "" > "$IP_DATA_FILE" printf "0 0 0" > "$UPDATE_STATUS_FILE" fi @@ -378,66 +384,121 @@ PreStartCheck() { [ -d "$DATA_DIR" ] || mkdir -p "$DATA_DIR" [ "$ENABLE_HTML_INFO" = "1" -a ! -d "$HTML_DIR" ] && mkdir -p "$HTML_DIR" ### Костыль для старта dnsmasq - [ -e "$DNSMASQ_DATA_FILE" ] || printf "\n" > "$DNSMASQ_DATA_FILE" + [ -e "$DNSMASQ_DATA_FILE" ] || printf "" > "$DNSMASQ_DATA_FILE" + [ -e "$DNSMASQ_DATA_FILE_BYPASS" ] || printf "" > "$DNSMASQ_DATA_FILE_BYPASS" } AddUserEntries() { 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; + 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; } - 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; - }; + else if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}[\057][0-9]{1,2}$/) { + cidr_array[$0] = null; } - 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" + 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" + fi + fi +} + +AddBypassEntries() { + printf "" > "$DNSMASQ_DATA_FILE_BYPASS" + FlushNftSets "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN" + if [ "$BYPASS_MODE" = "1" ]; then + if [ -f "$BYPASS_ENTRIES_FILE" ]; then + $AWK_CMD 'BEGIN { + null = ""; + ip_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["BYPASS_ENTRIES_DNS"]) > 0) { + dns = ENVIRON["BYPASS_ENTRIES_DNS"]; + }; + if(length(dns) > 0) { + printf "server=/%s/%s\n", val, dns >> ENVIRON["DNSMASQ_DATA_FILE_BYPASS"]; + }; + printf "nftset=/%s/%s#%s\n", val, ENVIRON["NFT_TABLE_DNSMASQ"], ENVIRON["NFTSET_BYPASS_FQDN"] >> ENVIRON["DNSMASQ_DATA_FILE_BYPASS"]; + }; + 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}([\057][0-9]{1,2})?$/) { + ip_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_BYPASS_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(); + }' "$BYPASS_ENTRIES_FILE" fi fi } @@ -467,6 +528,7 @@ GetDataFiles() { sleep $MODULE_RUN_TIMEOUT done AddUserEntries + AddBypassEntries if [ $_return_code -eq 0 ]; then _update_string=`$AWK_CMD '{ printf "Received entries: %s\n", (NF < 3) ? "No data" : "CIDR: "$1", IP: "$2", FQDN: "$3; @@ -481,6 +543,7 @@ GetDataFiles() { ClearDataFiles ADD_USER_ENTRIES=1 AddUserEntries + AddBypassEntries _return_code=0 else _return_code=2 @@ -488,7 +551,7 @@ GetDataFiles() { fi if [ $_return_code -eq 0 ]; then if [ "$PROXY_MODE" = "2" -o "$PROXY_MODE" = "3" ]; then - printf "\n" >> "$DNSMASQ_DATA_FILE" + printf "" >> "$DNSMASQ_DATA_FILE" else ### Запись для .onion в $DNSMASQ_DATA_FILE printf "server=/onion/%s\nnftset=/onion/%s#%s\n" "$ONION_DNS_ADDR" "$NFT_TABLE_DNSMASQ" "$NFTSET_ONION" >> "$DNSMASQ_DATA_FILE" diff --git a/ruantiblock/files/usr/share/ruantiblock/config_script b/ruantiblock/files/usr/share/ruantiblock/config_script index 4c79e80..adf8208 100644 --- a/ruantiblock/files/usr/share/ruantiblock/config_script +++ b/ruantiblock/files/usr/share/ruantiblock/config_script @@ -1,6 +1,6 @@ AWK_CMD="awk" UCI_SECTION="ruantiblock.config" -UCI_VARS="proxy_mode proxy_local_clients nftset_clear_sets allowed_hosts_mode allowed_hosts_list bypass_ip_mode bypass_ip_list if_vpn tor_trans_port tor_allow_udp 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 if_vpn tor_trans_port tor_allow_udp 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" eval `uci show "$UCI_SECTION" | $AWK_CMD -F "=" -v UCI_VARS="$UCI_VARS" ' BEGIN { diff --git a/ruantiblock/files/usr/share/ruantiblock/info_output b/ruantiblock/files/usr/share/ruantiblock/info_output index 7ce7d5a..5bfe4b8 100644 --- a/ruantiblock/files/usr/share/ruantiblock/info_output +++ b/ruantiblock/files/usr/share/ruantiblock/info_output @@ -29,6 +29,10 @@ Info() { if [ $? -eq 0 ]; then printf ",\"dnsmasq\":" $NFT_CMD -j list set $NFT_TABLE "$NFTSET_DNSMASQ" 2> /dev/null + if [ "$BYPASS_MODE" = "1" ]; then + printf ",\"dnsmasq_bypass\":" + $NFT_CMD -j list set $NFT_TABLE "$NFTSET_BYPASS_FQDN" 2> /dev/null + fi printf "}" fi } diff --git a/ruantiblock/files/usr/share/ruantiblock/nft_functions b/ruantiblock/files/usr/share/ruantiblock/nft_functions index e735aa1..20b852f 100644 --- a/ruantiblock/files/usr/share/ruantiblock/nft_functions +++ b/ruantiblock/files/usr/share/ruantiblock/nft_functions @@ -26,12 +26,6 @@ case "$ALLOWED_HOSTS_MODE" in ;; esac -if [ "$BYPASS_IP_MODE" = "1" ]; then - NFT_BYPASS_IP_EXPR="ip daddr @${NFTSET_BYPASS_IP} counter accept" -else - NFT_BYPASS_IP_EXPR="continue" -fi - if [ "$NFTSET_DNSMASQ_TIMEOUT_UPDATE" = "1" ]; then NFT_DNSMASQ_RULE_TARGET="$NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN" else @@ -72,7 +66,7 @@ NftVpnRouteStatus() { } NftMainAdd() { - local _nft_sets="${NFTSET_CIDR} ${NFTSET_IP}" _set + local _set $NFT_CMD add chain $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN" { $LOCAL_CLIENTS_CHAIN_TYPE } $NFT_CMD add chain $NFT_TABLE "$NFT_ACTION_CHAIN" $NFT_CMD add chain $NFT_TABLE "$NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN" @@ -95,8 +89,13 @@ NftMainAdd() { fi NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip daddr "@${NFTSET_ONION}" counter goto "$NFT_ACTION_CHAIN" fi - NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" $NFT_BYPASS_IP_EXPR - for _set in $_nft_sets + if [ "$BYPASS_MODE" = "1" ]; then + for _set in "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN" + do + NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip daddr "@${_set}" counter accept + done + fi + for _set in "$NFTSET_CIDR" "$NFTSET_IP" do NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip daddr "@${_set}" counter goto "$NFT_ACTION_CHAIN" done diff --git a/screenshots/02.jpg b/screenshots/02.jpg index d08f636..3534ec0 100644 Binary files a/screenshots/02.jpg and b/screenshots/02.jpg differ diff --git a/screenshots/04.jpg b/screenshots/04.jpg index 1f0d3d2..d7e2bc6 100644 Binary files a/screenshots/04.jpg and b/screenshots/04.jpg differ