diff --git a/luci-app-ruantiblock/Makefile b/luci-app-ruantiblock/Makefile
index 056d374..5955996 100644
--- a/luci-app-ruantiblock/Makefile
+++ b/luci-app-ruantiblock/Makefile
@@ -4,7 +4,7 @@
include $(TOPDIR)/rules.mk
-PKG_VERSION:=0.9.7-0
+PKG_VERSION:=1.0-0
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 484a419..4ad8ce8 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
@@ -5,7 +5,18 @@
'require view';
'require view.ruantiblock.tools as tools';
+document.head.append(E('style', {'type': 'text/css'},
+`
+.log-entries-count {
+ margin: 0 0 5px 5px;
+ font-weight: bold;
+ opacity: 0.7;
+}
+`));
+
return view.extend({
+ pollInterval : L.env.pollinterval,
+
secToTimeString: function(value) {
let string = '';
if(/^\d+$/.test(value)) {
@@ -31,11 +42,52 @@ return view.extend({
return string;
},
+ formatNftJson: function(data) {
+ let output = { 'rules': [] };
+ 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) {
+ set = e.match.right.replace('@', '');
+ }
+ else if(e.counter) {
+ bytes = e.counter.bytes;
+ };
+ });
+ output.rules.push([ set, bytes ]);
+
+ };
+
+ function parseDnsmasqData(set) {
+ let sArray = [];
+ if(data[set].nftables && data[set].nftables.length > 1) {
+ data[set].nftables.forEach(e => {
+ if(e.set && e.set.elem) {
+ e.set.elem.forEach(i => {
+ if(i.elem) {
+ sArray.push([ i.elem.val, i.elem.expires ]);
+ };
+ });
+ };
+ });
+ };
+ return sArray;
+ };
+
+ output.dnsmasq = parseDnsmasqData('dnsmasq');
+ output.dnsmasq_u = parseDnsmasqData('dnsmasq_u');
+ };
+ return output;
+ },
+
makeDnsmasqTable: function(ipDataArray) {
let lines = `
| ${_('No entries available...')} |
`;
let ipTable = E('table', { 'id': 'ipTable', 'class': 'table' });
- if(ipDataArray.length > 1) {
+ if(ipDataArray.length > 0) {
lines = [];
ipDataArray.forEach((e, i) => {
if(e) {
@@ -57,18 +109,23 @@ return view.extend({
try {
ipTable.insertAdjacentHTML('beforeend', lines);
- } catch(err) {
- if(err.name === 'SyntaxError') {
+ } catch(e) {
+ if(e.name === 'SyntaxError') {
ui.addNotification(null,
- E('p', {}, _('HTML/XML error') + ': ' + err.message), 'error');
+ E('p', {}, _('HTML/XML error') + ': ' + e.message), 'error');
};
- throw err;
+ throw e;
};
- return ipTable;
+ return E([
+ E('div', { 'class': 'log-entries-count' },
+ `${_('Entries')}: ${ipDataArray.length}`
+ ),
+ ipTable,
+ ]);
},
- infoPoll: function() {
+ pollInfo: function() {
return fs.exec_direct(tools.execPath, [ 'html-info' ], 'json').catch(e => {
ui.addNotification(null, E('p', _('Unable to execute or read contents')
+ ': %s [ %s ]'.format(e.message, tools.execPath)
@@ -81,7 +138,7 @@ return view.extend({
try {
data = JSON.parse(data);
- } catch(err) {};
+ } catch(e) {};
if(data.status === 'enabled') {
let date = document.getElementById('last_blacklist_update.date');
@@ -111,34 +168,27 @@ return view.extend({
};
};
- if(data.iptables) {
- for(let [k, v] of Object.entries(data.iptables)) {
- if(k === '_dummy') continue;
+ let nft_data = this.formatNftJson(data);
- let elem = document.getElementById('iptables.' + k);
+ if(nft_data.rules.length > 0) {
+ for(let [set, bytes] of nft_data.rules) {
+ let elem = document.getElementById('rules.' + set);
if(elem) {
- elem.textContent = v;
+ elem.textContent = bytes;
};
};
};
- if(data.ipset) {
- for(let [k, v] of Object.entries(data.ipset)) {
- if(k === '_dummy') continue;
-
- let elem0 = document.getElementById('ipset.' + k + '.' + '0');
- let elem1 = document.getElementById('ipset.' + k + '.' + '1');
- if(elem0 && elem1) {
- elem0.textContent = v[0];
- elem1.textContent = v[1];
- };
- };
- };
-
- if(data.dnsmasq) {
+ if(nft_data.dnsmasq.length > 0) {
let rdTableWrapper = document.getElementById('rdTableWrapper');
rdTableWrapper.innerHTML = '';
- rdTableWrapper.append(this.makeDnsmasqTable(data.dnsmasq));
+ rdTableWrapper.append(this.makeDnsmasqTable(nft_data.dnsmasq));
+ };
+
+ if(nft_data.dnsmasq_u.length > 0) {
+ let rduTableWrapper = document.getElementById('rduTableWrapper');
+ rduTableWrapper.innerHTML = '';
+ rduTableWrapper.append(this.makeDnsmasqTable(nft_data.dnsmasq_u));
};
} else {
if(poll.active()) {
@@ -163,12 +213,12 @@ return view.extend({
try {
data = JSON.parse(data);
- } catch(err) {};
+ } catch(e) {};
let update_status = null,
- iptables = null,
- ipset = null,
- dnsmasq = null;
+ rules = null,
+ dnsmasq = null,
+ dnsmasq_u = null;
if(data) {
if(data.status === 'enabled') {
update_status = E('table', { 'class': 'table' });
@@ -211,8 +261,10 @@ return view.extend({
);
};
- if(data.iptables) {
- let table_iptables = E('table', { 'class': 'table' }, [
+ let nft_data = this.formatNftJson(data);
+
+ if(nft_data.rules) {
+ let table_rules = E('table', { 'class': 'table' }, [
E('tr', { 'class': 'tr table-titles' }, [
E('th', { 'class': 'th left', 'style': 'min-width:33%' },
_('Match-set')),
@@ -220,76 +272,33 @@ return view.extend({
]),
]);
- for(let [k, v] of Object.entries(data.iptables)) {
- if(k === '_dummy') continue;
-
- table_iptables.append(
+ for(let [set, bytes] of nft_data.rules) {
+ table_rules.append(
E('tr', { 'class': 'tr' }, [
- E('td', {
+ E('td',{
'class' : 'td left',
'data-title': _('Match-set'),
- }, k),
+ }, set + ' (' + set.replace(/^c/, 'CIDR').replace(/^i/, 'IP').replace(/^d/, 'dnsmasq').replace(/u$/, '-user') + ')'),
E('td', {
'class' : 'td left',
- 'id' : 'iptables.' + k,
+ 'id' : 'rules.' + set,
'data-title': _('Bytes'),
- }, v),
+ }, bytes),
])
);
};
- iptables = E([
- E('h3', {}, _('Iptables rules')),
- table_iptables,
+ rules = E([
+ E('h3', {}, _('Nftables rules')),
+ table_rules,
]);
};
- if(data.ipset) {
- let table_ipset = E('table', { 'class': 'table' },
- E('tr', { 'class': 'tr table-titles' }, [
- E('th', { 'class': 'th left', 'style': 'min-width:33%' },
- _('Name')),
- E('th', { 'class': 'th left' },
- _('Size in memory')),
- E('th', { 'class': 'th left' },
- _('Number of entries')),
- ])
- );
-
- for(let [k, v] of Object.entries(data.ipset)) {
- if(k === '_dummy') continue;
-
- table_ipset.append(
- E('tr', { 'class': 'tr' }, [
- E('td', {
- 'class': 'td left',
- 'data-title': _('Name'),
- }, k),
- E('td', {
- 'class' : 'td left',
- 'id' : 'ipset.' + k + '.' + '0',
- 'data-title': _('Size in memory'),
- }, v[0]),
- E('td', {
- 'class' : 'td left',
- 'id' : 'ipset.' + k + '.' + '1',
- 'data-title': _('Number of entries'),
- }, v[1]),
- ])
- );
- };
-
- ipset = E([
- E('h3', {}, _('Ipset')),
- table_ipset,
- ]);
- };
-
- if(data.dnsmasq) {
+ if(nft_data.dnsmasq) {
let rdTableWrapper = E('div', {
'id' : 'rdTableWrapper',
'style': 'width:100%'
- }, this.makeDnsmasqTable(data.dnsmasq));
+ }, this.makeDnsmasqTable(nft_data.dnsmasq));
dnsmasq = E([
E('h3', {}, _('Dnsmasq')),
@@ -297,7 +306,19 @@ return view.extend({
]);
};
- poll.add(L.bind(this.infoPoll, this));
+ if(nft_data.dnsmasq_u) {
+ let rduTableWrapper = E('div', {
+ 'id' : 'rduTableWrapper',
+ 'style': 'width:100%'
+ }, this.makeDnsmasqTable(nft_data.dnsmasq_u));
+
+ dnsmasq_u = E([
+ E('h3', {}, _('Dnsmasq') + ' - ' + _('User entries')),
+ rduTableWrapper,
+ ]);
+ };
+
+ poll.add(L.bind(this.pollInfo, this), this.pollInterval);
} else {
update_status = E('em', {}, _('Status') + ' : ' + _('disabled'));
};
@@ -311,15 +332,14 @@ return view.extend({
E('div', { 'class': 'cbi-section-node' }, update_status)
),
E('div', { 'class': 'cbi-section fade-in' },
- E('div', { 'class': 'cbi-section-node' }, iptables)
- ),
- E('div', { 'class': 'cbi-section fade-in' },
- E('div', { 'class': 'cbi-section-node' }, ipset)
+ E('div', { 'class': 'cbi-section-node' }, rules)
),
E('div', { 'class': 'cbi-section fade-in' },
E('div', { 'class': 'cbi-section-node' }, dnsmasq)
),
-
+ E('div', { 'class': 'cbi-section fade-in' },
+ E('div', { 'class': 'cbi-section-node' }, dnsmasq_u)
+ ),
]);
},
diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js
index dd58547..3cf34bb 100644
--- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js
+++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js
@@ -284,7 +284,7 @@ return view.extend({
btn_destroy.onclick = L.bind(this.dialogDestroy, this);
layout_append(btn_destroy, _('Shutdown'),
- _('Complete service shutdown, as well as deleting ipsets and blacklist data'));
+ _('Complete service shutdown, as well as deleting nftsets and blacklist data'));
this.setAppStatus(status_array, [
status_string,
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 fc415d2..39f05db 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
@@ -8,11 +8,11 @@
'require view.ruantiblock.tools as tools';
return view.extend({
- parsers: {},
+ parsers : {},
- appStatusCode : null,
+ appStatusCode: null,
- depends: function(elem, key, array, empty=true) {
+ depends : function(elem, key, array, empty=true) {
if(empty && array.length === 0) {
elem.depends(key, '_dummy');
} else {
@@ -111,18 +111,17 @@ return view.extend({
s.anonymous = true;
s.addremove = false;
+
/* Main settings tab */
s.tab('main_settings', _('Main settings'));
// PROXY_MODE
- if(this.appStatusCode == 1 || this.appStatusCode == 2) {
- o = s.taboption('main_settings', form.ListValue, 'proxy_mode',
- _('Proxy mode'));
- o.value('1', 'Tor');
- o.value('2', 'VPN');
- o.value('3', _('Transparent proxy'));
- };
+ o = s.taboption('main_settings', form.ListValue, 'proxy_mode',
+ _('Proxy mode'));
+ o.value('1', 'Tor');
+ o.value('2', 'VPN');
+ o.value('3', _('Transparent proxy'));
// PROXY_LOCAL_CLIENTS
let proxy_local_clients = s.taboption('main_settings', form.Flag, 'proxy_local_clients',
@@ -140,9 +139,9 @@ return view.extend({
o.description = _('Update blacklist after system startup');
o.rmempty = false;
- // IPSET_CLEAR_SETS
- o = s.taboption('main_settings', form.Flag, 'ipset_clear_sets',
- _('Clean up ipsets before updating blacklist'));
+ // NFTSET_CLEAR_SETS
+ o = s.taboption('main_settings', form.Flag, 'nftset_clear_sets',
+ _('Clean up nftsets before updating blacklist'));
o.description = _('Reduces RAM consumption during update');
o.rmempty = false;
@@ -160,70 +159,68 @@ return view.extend({
o.datatype = "ip4addr";
- if(this.appStatusCode == 1 || this.appStatusCode == 2) {
- /* Tor tab */
+ /* Tor tab */
- s.tab('tor_settings', _('Tor mode'));
+ s.tab('tor_settings', _('Tor mode'));
- // TOR_TRANS_PORT
- o = s.taboption('tor_settings', form.Value, 'tor_trans_port',
- _('Transparent proxy port'));
- o.rmempty = false;
- o.datatype = "port";
+ // TOR_TRANS_PORT
+ o = s.taboption('tor_settings', form.Value, 'tor_trans_port',
+ _('Transparent proxy port'));
+ o.rmempty = false;
+ o.datatype = "port";
- //TOR_ALLOW_UDP
- o = s.taboption('tor_settings', form.Flag, 'tor_allow_udp',
- _("Send UDP traffic to Tor"));
- o.rmempty = false;
+ //TOR_ALLOW_UDP
+ o = s.taboption('tor_settings', form.Flag, 'tor_allow_udp',
+ _("Send UDP traffic to Tor"));
+ o.rmempty = false;
- // ONION_DNS_ADDR
- o = s.taboption('tor_settings', form.Value, 'onion_dns_addr',
- _("Optional DNS resolver for '.onion' zone"), 'ipaddress#port');
- o.rmempty = false;
- o.validate = this.validateIpPort;
+ // ONION_DNS_ADDR
+ o = s.taboption('tor_settings', form.Value, 'onion_dns_addr',
+ _("Optional DNS resolver for '.onion' zone"), 'ipaddress#port');
+ o.rmempty = false;
+ o.validate = this.validateIpPort;
- // Torrc edit dialog
- o = s.taboption('tor_settings', form.Button, '_torrc_btn',
- _('Tor configuration file'));
- o.onclick = () => torrc_edit.show();
- o.inputtitle = _('Edit');
- o.inputstyle = 'edit btn';
+ // Torrc edit dialog
+ o = s.taboption('tor_settings', form.Button, '_torrc_btn',
+ _('Tor configuration file'));
+ o.onclick = () => torrc_edit.show();
+ o.inputtitle = _('Edit');
+ o.inputstyle = 'edit btn';
- /* VPN tab */
+ /* VPN tab */
- s.tab('vpn_settings', _('VPN mode'));
+ s.tab('vpn_settings', _('VPN mode'));
- // IF_VPN
- o = s.taboption('vpn_settings', widgets.DeviceSelect, 'if_vpn',
- _('VPN interface'));
- o.multiple = false;
- o.noaliases = true;
- o.rmempty = false;
- o.default = 'tun0';
+ // IF_VPN
+ o = s.taboption('vpn_settings', widgets.DeviceSelect, 'if_vpn',
+ _('VPN interface'));
+ o.multiple = false;
+ o.noaliases = true;
+ o.rmempty = false;
+ o.default = 'tun0';
- /* Proxy tab */
+ /* Proxy tab */
- s.tab('proxy_settings', _('Transparent proxy mode'));
+ s.tab('proxy_settings', _('Transparent proxy mode'));
- // T_PROXY_PORT_TCP
- o = s.taboption('proxy_settings', form.Value, 't_proxy_port_tcp',
- _('Transparent proxy TCP port'));
- o.rmempty = false;
- o.datatype = "port";
+ // T_PROXY_PORT_TCP
+ o = s.taboption('proxy_settings', form.Value, 't_proxy_port_tcp',
+ _('Transparent proxy TCP port'));
+ o.rmempty = false;
+ o.datatype = "port";
- //T_PROXY_ALLOW_UDP
- o = s.taboption('proxy_settings', form.Flag, 't_proxy_allow_udp',
- _("Send UDP traffic to transparent proxy"));
- o.rmempty = false;
+ //T_PROXY_ALLOW_UDP
+ o = s.taboption('proxy_settings', form.Flag, 't_proxy_allow_udp',
+ _("Send UDP traffic to transparent proxy"));
+ o.rmempty = false;
- // T_PROXY_PORT_UDP
- o = s.taboption('proxy_settings', form.Value, 't_proxy_port_udp',
- _('Transparent proxy UDP port'));
- o.rmempty = false;
- o.datatype = "port";
- };
+ // T_PROXY_PORT_UDP
+ o = s.taboption('proxy_settings', form.Value, 't_proxy_port_udp',
+ _('Transparent proxy UDP port'));
+ o.rmempty = false;
+ o.datatype = "port";
/* Blacklist module tab */
diff --git a/luci-app-ruantiblock/po/ru/ruantiblock.po b/luci-app-ruantiblock/po/ru/ruantiblock.po
index 1b70841..6ff7777 100644
--- a/luci-app-ruantiblock/po/ru/ruantiblock.po
+++ b/luci-app-ruantiblock/po/ru/ruantiblock.po
@@ -64,15 +64,15 @@ msgstr "Отмена"
msgid "Changes have been saved."
msgstr "Изменения сохранены."
-msgid "Clean up ipsets before updating blacklist"
-msgstr "Очищать ipset'ы перед обновлением блэклиста"
+msgid "Clean up nftsets before updating blacklist"
+msgstr "Очищать nft-сеты перед обновлением блэклиста"
msgid "Command failed"
msgstr "Команда не выполнена"
msgid ""
-"Complete service shutdown, as well as deleting ipsets and blacklist data"
-msgstr "Полное выключение службы, а также удаление ipset'ов и данных блэклиста"
+"Complete service shutdown, as well as deleting nftsets and blacklist data"
+msgstr "Полное выключение службы, а также удаление nft-сетов и данных блэклиста"
msgid "Contents have been saved."
msgstr "Содержимое сохранено."
@@ -191,11 +191,8 @@ msgstr "Интервал"
msgid "Invalid regular expression"
msgstr "Неправильное регулярное выражение"
-msgid "Ipset"
-msgstr "Ipset"
-
-msgid "Iptables rules"
-msgstr "Правила iptables"
+msgid "Nftables rules"
+msgstr "Правила nftables"
msgid "Last blacklist update"
msgstr "Последнее обновление блэклиста"
diff --git a/luci-app-ruantiblock/po/templates/ruantiblock.pot b/luci-app-ruantiblock/po/templates/ruantiblock.pot
index 2dccd18..5f77d68 100644
--- a/luci-app-ruantiblock/po/templates/ruantiblock.pot
+++ b/luci-app-ruantiblock/po/templates/ruantiblock.pot
@@ -49,14 +49,14 @@ msgstr ""
msgid "Changes have been saved."
msgstr ""
-msgid "Clean up ipsets before updating blacklist"
+msgid "Clean up nftsets before updating blacklist"
msgstr ""
msgid "Command failed"
msgstr ""
msgid ""
-"Complete service shutdown, as well as deleting ipsets and blacklist data"
+"Complete service shutdown, as well as deleting nftsets and blacklist data"
msgstr ""
msgid "Contents have been saved."
@@ -171,10 +171,7 @@ msgstr ""
msgid "Invalid regular expression"
msgstr ""
-msgid "Ipset"
-msgstr ""
-
-msgid "Iptables rules"
+msgid "Nftables rules"
msgstr ""
msgid "Last blacklist update"
diff --git a/ruantiblock-mod-lua/Makefile b/ruantiblock-mod-lua/Makefile
index 376f96a..9ea52d9 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:=0.9.7
+PKG_VERSION:=1.0
PKG_RELEASE:=0
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 c8b7d4b..5b76e7c 100755
--- a/ruantiblock-mod-lua/files/usr/libexec/ruantiblock/ruab_parser.lua
+++ b/ruantiblock-mod-lua/files/usr/libexec/ruantiblock/ruab_parser.lua
@@ -53,10 +53,11 @@ local Config = Class(nil, {
["BLLIST_GR_EXCLUDED_NETS"] = true,
["BLLIST_MIN_ENTRIES"] = true,
["BLLIST_STRIP_WWW"] = true,
- ["DATA_DIR"] = true,
- ["IPSET_DNSMASQ"] = true,
- ["IPSET_IP_TMP"] = true,
- ["IPSET_CIDR_TMP"] = true,
+ ["NFT_TABLE"] = true,
+ ["NFT_TABLE_DNSMASQ"] = true,
+ ["NFTSET_CIDR_CFG"] = true,
+ ["NFTSET_IP_CFG"] = true,
+ ["NFTSET_DNSMASQ"] = true,
["DNSMASQ_DATA_FILE"] = true,
["IP_DATA_FILE"] = true,
["UPDATE_STATUS_FILE"] = true,
@@ -65,10 +66,10 @@ local Config = Class(nil, {
["ZI_ALL_URL"] = true,
["AF_IP_URL"] = true,
["AF_FQDN_URL"] = true,
- ["RA_IP_IPSET_URL"] = true,
+ ["RA_IP_NFTSET_URL"] = true,
["RA_IP_DMASK_URL"] = true,
["RA_IP_STAT_URL"] = true,
- ["RA_FQDN_IPSET_URL"] = true,
+ ["RA_FQDN_NFTSET_URL"] = true,
["RA_FQDN_DMASK_URL"] = true,
["RA_FQDN_STAT_URL"] = true,
["RBL_ENCODING"] = true,
@@ -228,16 +229,16 @@ function BlackListParser:new(t)
instance.records_separator = instance["records_separator"] or self.records_separator
instance.ips_separator = instance["ips_separator"] or self.ips_separator
instance.site_encoding = instance["site_encoding"] or self.site_encoding
- instance.ip_records_count = 0
- instance.ip_count = 0
instance.ip_subnet_table = {}
instance.cidr_count = 0
- instance.fqdn_table = {}
+ instance.ip_records_count = 0
+ instance.ip_count = 0
instance.fqdn_count = 0
instance.sld_table = {}
instance.fqdn_records_count = 0
- instance.ip_table = {}
instance.cidr_table = {}
+ instance.ip_table = {}
+ instance.fqdn_table = {}
instance.iconv_handler = iconv and iconv.open(instance.encoding, instance.site_encoding) or nil
return instance
end
@@ -387,19 +388,34 @@ function BlackListParser:group_cidr_ranges()
end
function BlackListParser:write_ipset_config()
- local file_handler = assert(io.open(self.IP_DATA_FILE, "w"), "Could not open ipset config")
+ local file_handler = assert(io.open(self.IP_DATA_FILE, "w"), "Could not open nftset config")
+ file_handler:write(
+ string.format("table %s {\n%s", self.NFT_TABLE, self.NFTSET_IP_CFG)
+ )
local i = 0
- for ipaddr in pairs(self.ip_table) do
- file_handler:write(string.format("add %s %s\n", self.IPSET_IP_TMP, ipaddr))
- i = i + 1
+ if next(self.ip_table) then
+ file_handler:write("elements={")
+ for ipaddr in pairs(self.ip_table) do
+ file_handler:write(string.format("%s,", ipaddr))
+ i = i + 1
+ end
+ file_handler:write("};")
end
+ file_handler:write(
+ string.format("}\n%s", self.NFTSET_CIDR_CFG)
+ )
self.ip_records_count = i
local c = 0
- for cidr in pairs(self.cidr_table) do
- file_handler:write(string.format("add %s %s\n", self.IPSET_CIDR_TMP, cidr))
- c = c + 1
+ if next(self.cidr_table) then
+ file_handler:write("elements={")
+ for cidr in pairs(self.cidr_table) do
+ file_handler:write(string.format("%s,", cidr))
+ c = c + 1
+ end
+ file_handler:write("};")
end
self.cidr_count = c
+ file_handler:write("}\n}\n")
file_handler:close()
end
@@ -409,7 +425,7 @@ function BlackListParser:write_dnsmasq_config()
if self.BLLIST_ALT_NSLOOKUP then
file_handler:write(string.format("server=/%s/%s\n", fqdn, self.BLLIST_ALT_DNS_ADDR))
end
- file_handler:write(string.format("ipset=/%s/%s\n", fqdn, self.IPSET_DNSMASQ))
+ file_handler:write(string.format("nftset=/%s/%s#%s\n", fqdn, self.NFT_TABLE_DNSMASQ, self.NFTSET_DNSMASQ))
end
file_handler:close()
end
@@ -465,7 +481,7 @@ end
function BlackListParser:run()
local return_code = 0
if self:get_http_data(self.url) then
- if (self.fqdn_count + self.ip_count + self.cidr_count) >= self.BLLIST_MIN_ENTRIES then
+ if (self.fqdn_count + self.ip_count + self.cidr_count) > self.BLLIST_MIN_ENTRIES then
self:optimize_fqdn_table()
self:optimize_ip_table()
if self.BLLIST_SUMMARIZE_IP then
@@ -593,6 +609,7 @@ 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_handler:setvbuf("no")
if self:get_http_data(url) then
ret_val = true
end
diff --git a/ruantiblock-mod-py/Makefile b/ruantiblock-mod-py/Makefile
index 338ce48..57ad9ec 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:=0.9.7
+PKG_VERSION:=1.0
PKG_RELEASE:=0
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 b818762..fc1dc44 100755
--- a/ruantiblock-mod-py/files/usr/libexec/ruantiblock/ruab_parser.py
+++ b/ruantiblock-mod-py/files/usr/libexec/ruantiblock/ruab_parser.py
@@ -37,10 +37,11 @@ class Config:
"BLLIST_GR_EXCLUDED_NETS",
"BLLIST_MIN_ENTRIES",
"BLLIST_STRIP_WWW",
- "DATA_DIR",
- "IPSET_DNSMASQ",
- "IPSET_IP_TMP",
- "IPSET_CIDR_TMP",
+ "NFT_TABLE",
+ "NFT_TABLE_DNSMASQ",
+ "NFTSET_CIDR_CFG",
+ "NFTSET_IP_CFG",
+ "NFTSET_DNSMASQ",
"DNSMASQ_DATA_FILE",
"IP_DATA_FILE",
"UPDATE_STATUS_FILE",
@@ -49,10 +50,10 @@ class Config:
"ZI_ALL_URL",
"AF_IP_URL",
"AF_FQDN_URL",
- "RA_IP_IPSET_URL",
+ "RA_IP_NFTSET_URL",
"RA_IP_DMASK_URL",
"RA_IP_STAT_URL",
- "RA_FQDN_IPSET_URL",
+ "RA_FQDN_NFTSET_URL",
"RA_FQDN_DMASK_URL",
"RA_FQDN_STAT_URL",
"RBL_ENCODING",
@@ -131,18 +132,18 @@ class FieldValueError(ParserError):
class BlackListParser(Config):
def __init__(self):
- self.ip_pattern = re.compile("(([0-9]{1,3}[.]){3})[0-9]{1,3}")
- self.cidr_pattern = re.compile("([0-9]{1,3}[.]){3}[0-9]{1,3}/[0-9]{1,2}")
+ 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(
- "([а-яёa-z0-9_.*-]*?)([а-яёa-z0-9_-]+[.][а-яёa-z0-9-]+)",
+ r"([а-яёa-z0-9_.*-]*?)([а-яёa-z0-9_-]+[.][а-яёa-z0-9-]+)",
re.U)
- self.www_pattern = re.compile("^www[0-9]?[.]")
- self.cyr_pattern = re.compile("[а-яё]", re.U)
- self.fqdn_set = {}
- self.sld_dict = {}
+ self.www_pattern = re.compile(r"^www[0-9]?[.]")
+ self.cyr_pattern = re.compile(r"[а-яё]", re.U)
+ self.cidr_set = set()
self.ip_set = {}
self.ip_subnet_dict = {}
- self.cidr_set = set()
+ self.fqdn_set = {}
+ self.sld_dict = {}
self.cidr_count = 0
self.ip_count = 0
self.output_fqdn_count = 0
@@ -256,7 +257,7 @@ class BlackListParser(Config):
subnet = self._get_subnet(i)
if subnet in self.BLLIST_GR_EXCLUDED_NETS or (
not self.BLLIST_IP_LIMIT or (
- subnet not in self.ip_subnet_dict or self.ip_subnet_dict[subnet] <= self.BLLIST_IP_LIMIT
+ subnet not in self.ip_subnet_dict or self.ip_subnet_dict[subnet] < self.BLLIST_IP_LIMIT
)
):
self.ip_set[i] = subnet
@@ -496,18 +497,31 @@ class WriteConfigFiles(Config):
def write_ipset_config(self, ip_set, cidr_set):
with open(self.IP_DATA_FILE, "wt", buffering=self.write_buffer) as file_handler:
- for i in ip_set:
- file_handler.write(f"add {self.IPSET_IP_TMP} {i}\n")
- for i in cidr_set:
- file_handler.write(f"add {self.IPSET_CIDR_TMP} {i}\n")
+ file_handler.write(
+ "table {} {{\n{}".format(self.NFT_TABLE, self.NFTSET_IP_CFG)
+ )
+ if len(ip_set) > 0:
+ file_handler.write("elements={")
+ for i in ip_set:
+ file_handler.write(f"{i},")
+ file_handler.write("};")
+ file_handler.write(
+ "}}\n{}".format(self.NFTSET_CIDR_CFG)
+ )
+ if len(cidr_set) > 0:
+ file_handler.write("elements={")
+ for i in cidr_set:
+ file_handler.write(f"{i},")
+ file_handler.write("};")
+ file_handler.write("}\n}\n")
def write_dnsmasq_config(self, fqdn_set):
with open(self.DNSMASQ_DATA_FILE, "wt", buffering=self.write_buffer) as file_handler:
for fqdn in fqdn_set:
file_handler.write(
- f"server=/{fqdn}/{self.BLLIST_ALT_DNS_ADDR}\nipset=/{fqdn}/{self.IPSET_DNSMASQ}\n"
+ f"server=/{fqdn}/{self.BLLIST_ALT_DNS_ADDR}\nnftset=/{fqdn}/{self.NFT_TABLE_DNSMASQ}#{self.NFTSET_DNSMASQ}\n"
if self.BLLIST_ALT_NSLOOKUP else
- f"ipset=/{fqdn}/{self.IPSET_DNSMASQ}\n")
+ f"nftset=/{fqdn}/{self.NFT_TABLE_DNSMASQ}#{self.NFTSET_DNSMASQ}\n")
def write_update_status_file(self, ip_count, cidr_count, output_fqdn_count):
with open(self.UPDATE_STATUS_FILE, "wt") as file_handler:
diff --git a/ruantiblock/Makefile b/ruantiblock/Makefile
index df606ae..72e6dce 100644
--- a/ruantiblock/Makefile
+++ b/ruantiblock/Makefile
@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ruantiblock
-PKG_VERSION:=0.9.7
+PKG_VERSION:=1.0
PKG_RELEASE:=0
PKG_MAINTAINER:=gSpot
@@ -17,7 +17,7 @@ define Package/$(PKG_NAME)
TITLE:=Ruantiblock
URL:=https://github.com/gSpotx2f/ruantiblock_openwrt
PKGARCH:=all
- DEPENDS:=+wget +ipset +kmod-ipt-ipset +dnsmasq-full
+ DEPENDS:=+wget +dnsmasq-full
endef
define Package/$(PKG_NAME)/description
@@ -45,7 +45,7 @@ define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/ruantiblock/scripts
$(INSTALL_DATA) ./files/etc/ruantiblock/scripts/config_script $(1)/etc/ruantiblock/scripts/config_script
$(INSTALL_DATA) ./files/etc/ruantiblock/scripts/info_output $(1)/etc/ruantiblock/scripts/info_output
- $(INSTALL_DATA) ./files/etc/ruantiblock/scripts/ipt_functions $(1)/etc/ruantiblock/scripts/ipt_functions
+ $(INSTALL_DATA) ./files/etc/ruantiblock/scripts/nft_functions $(1)/etc/ruantiblock/scripts/nft_functions
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) ./files/usr/bin/ruantiblock $(1)/usr/bin/ruantiblock
endef
diff --git a/ruantiblock/files/etc/config/ruantiblock b/ruantiblock/files/etc/config/ruantiblock
index e86c3b2..bc48fb5 100644
--- a/ruantiblock/files/etc/config/ruantiblock
+++ b/ruantiblock/files/etc/config/ruantiblock
@@ -2,7 +2,7 @@
config main 'config'
option proxy_mode '1'
option proxy_local_clients '1'
- option ipset_clear_sets '1'
+ option nftset_clear_sets '1'
option allowed_hosts_mode '0'
option if_vpn 'tun0'
option tor_trans_port '9040'
diff --git a/ruantiblock/files/etc/init.d/ruantiblock b/ruantiblock/files/etc/init.d/ruantiblock
index 7ace15f..e54a79d 100755
--- a/ruantiblock/files/etc/init.d/ruantiblock
+++ b/ruantiblock/files/etc/init.d/ruantiblock
@@ -1,6 +1,6 @@
#!/bin/sh /etc/rc.common
-START=96
+START=99
STOP=01
APP_NAME="ruantiblock"
diff --git a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf
index 99e865e..6d08463 100644
--- a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf
+++ b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf
@@ -1,7 +1,7 @@
### Настройки ruantiblock ###
-### Директория данных (генерируемые конфиги dnsmasq, ipset и пр.)
+### Директория данных (генерируемые конфиги dnsmasq, nftset и пр.)
DATA_DIR="/tmp/ruantiblock"
### Директория модулей
MODULES_DIR="/usr/libexec/ruantiblock"
@@ -12,12 +12,12 @@ DNSMASQ_RESTART_CMD="/etc/init.d/dnsmasq restart"
### Директория для html-страницы статуса (не используется в OpenWrt)
HTML_DIR="/www"
-### Режим обработки пакетов в правилах iptables (1 - Tor, 2 - VPN, 3 - Прозрачный прокси)
+### Режим обработки пакетов в правилах nftables (1 - Tor, 2 - VPN, 3 - Прозрачный прокси)
PROXY_MODE=1
-### Применять правила проксификации для трафика локальных сервисов роутера (0 - off, 1 - on)
+### Применять правила проксификации для трафика локальных сервисов роутера (0 - выкл, 1 - вкл)
PROXY_LOCAL_CLIENTS=1
-### Удаление записей из основных сетов перед началом заполнения временных сетов при обновлении (для освобождения оперативной памяти перед заполнением сетов) (0 - off, 1 - on)
-IPSET_CLEAR_SETS=0
+### Удаление записей сетов перед началом обновления (для освобождения оперативной памяти перед обновлением сетов) (0 - выкл, 1 - вкл)
+NFTSET_CLEAR_SETS=0
### Режим фильтра хостов которым разрешено обходить блокировки (0 - выкл., 1 - только адреса из списка, 2 - любые адреса кроме присутствующих в списке)
ALLOWED_HOSTS_MODE=0
### Список IP адресов хостов для фильтра, через пробел (прим.: 192.168.0.10 192.168.0.15)
@@ -26,7 +26,7 @@ ALLOWED_HOSTS_LIST=""
IF_VPN="tun0"
### Порт прозрачного прокси Tor (параметр TransPort в torrc)
TOR_TRANS_PORT=9040
-### Отправлять в Tor UDP-трафик (0 - off, 1 - on)
+### Отправлять в Tor UDP-трафик (0 - вкл, 1 - выкл)
TOR_ALLOW_UDP=0
### DNS-сервер для резолвинга в домене .onion (Tor)
ONION_DNS_ADDR="127.0.0.1#9053"
@@ -36,9 +36,9 @@ VPN_PKTS_MARK=8
T_PROXY_PORT_TCP=1100
### UDP порт прокси в режиме прозрачного прокси
T_PROXY_PORT_UDP=1100
-### Отправлять в прозрачный прокси UDP-трафик (0 - off, 1 - on)
+### Отправлять в прозрачный прокси UDP-трафик (0 - вкл, 1 - выкл)
T_PROXY_ALLOW_UDP=0
-### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - off, 1 - on)
+### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - выкл, 1 - вкл)
### В $DATA_DIR можно создать текстовый файл user_entries с записями IP, CIDR или FQDN (одна на строку). Эти записи будут добавлены в список блокировок
### В записях FQDN можно задать DNS-сервер для разрешения данного домена, через пробел (прим.: domain.com 8.8.8.8)
### Можно комментировать строки (#)
@@ -47,14 +47,22 @@ ADD_USER_ENTRIES=0
USER_ENTRIES_DNS=""
### Файл пользовательских записей
USER_ENTRIES_FILE="/etc/ruantiblock/user_entries"
-### Запись событий в syslog (0 - off, 1 - on)
+### Запись событий в syslog (0 - выкл, 1 - вкл)
ENABLE_LOGGING=1
-### Html-страница с инфо о текущем статусе (0 - off, 1 - on) (не используется в OpenWrt)
+### Html-страница с инфо о текущем статусе (0 - выкл, 1 - вкл) (не используется в OpenWrt)
ENABLE_HTML_INFO=0
-### Максимальное кол-во элементов списка ipset
-IPSET_MAXELEM=2000000
-### Таймаут для записей в сете $IPSET_DNSMASQ
-IPSET_DNSMASQ_TIMEOUT=3600
+### метка для отбора пакетов в VPN туннель
+VPN_PKTS_MARK=8
+### Максимальное кол-во элементов списка nftables
+#NFTSET_MAXELEM_CIDR=65535
+NFTSET_MAXELEM_IP=1000000
+NFTSET_MAXELEM_DNSMASQ=65535
+### Политика отбора элементов в сетах nftables. "performance" - производительность и большее потребление RAM. "memory" - хуже производительность и меньше потребление RAM
+NFTSET_POLICY_CIDR="memory"
+NFTSET_POLICY_IP="memory"
+NFTSET_POLICY_DNSMASQ="performance"
+### Таймаут для записей в сете $NFTSET_DNSMASQ
+NFTSET_DNSMASQ_TIMEOUT="1h"
### Кол-во попыток обновления блэклиста (в случае неудачи)
MODULE_RUN_ATTEMPTS=3
### Таймаут между попытками обновления
@@ -66,11 +74,11 @@ BLLIST_MODULE=""
### Настройки модулей-парсеров ###
-### Режим обхода блокировок: ruantiblock-ip, ruantiblock-fqdn, zapret-info-ip, zapret-info-fqdn, rublacklist-ip, rublacklist-fqdn, antifilter-ip
+### Режим обхода блокировок: ruantiblock-fqdn, ruantiblock-ip, zapret-info-fqdn, zapret-info-ip, rublacklist-fqdn, rublacklist-ip, antifilter-ip
BLLIST_PRESET=""
### В случае если из источника получено менее указанного кол-ва записей, то обновления списков не происходит
BLLIST_MIN_ENTRIES=3000
-### Лимит ip адресов. При достижении, в конфиг ipset будет добавлена вся подсеть /24 вместо множества ip-адресов пренадлежащих этой сети (0 - off)
+### Лимит ip адресов. При достижении, в конфиг ipset будет добавлена вся подсеть /24 вместо множества ip-адресов пренадлежащих этой сети (0 - выкл)
BLLIST_IP_LIMIT=0
### Подсети класса C (/24). IP адреса из этих подсетей не группируются при оптимизации (записи д.б. в виде: 68.183.221. 149.154.162. и пр.). Прим.: "68.183.221. 149.154.162."
BLLIST_GR_EXCLUDED_NETS=""
@@ -78,29 +86,29 @@ BLLIST_GR_EXCLUDED_NETS=""
BLLIST_SUMMARIZE_IP=0
### Группировать идущие подряд подсети /24 в диапазоны CIDR
BLLIST_SUMMARIZE_CIDR=0
-### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига ipset (0 - off, 1 - on)
+### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига ipset (0 - выкл, 1 - вкл)
BLLIST_IP_FILTER=0
### Тип фильтра IP (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
BLLIST_IP_FILTER_TYPE=0
### Файл с шаблонами ip для опции BLLIST_IP_FILTER (каждый шаблон в отдельной строке. # в первом символе строки - комментирует строку)
BLLIST_IP_FILTER_FILE="/etc/ruantiblock/ip_filter"
-### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - off)
+### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - выкл)
BLLIST_SD_LIMIT=16
### SLD не подлежащие группировке при оптимизации (через пробел)
BLLIST_GR_EXCLUDED_SLD="livejournal.com facebook.com vk.com blog.jp msk.ru net.ru org.ru net.ua com.ua org.ua co.uk amazonaws.com"
### Не группировать SLD попадающие под выражения (через пробел) ("[.][a-z]{2,3}[.][a-z]{2}$")
BLLIST_GR_EXCLUDED_MASKS=""
-### Фильтрация записей блэклиста по шаблонам из файла ENTRIES_FILTER_FILE. Записи (FQDN) попадающие под шаблоны исключаются из кофига dnsmasq (0 - off, 1 - on)
+### Фильтрация записей блэклиста по шаблонам из файла ENTRIES_FILTER_FILE. Записи (FQDN) попадающие под шаблоны исключаются из кофига dnsmasq (0 - выкл, 1 - вкл)
BLLIST_FQDN_FILTER=0
### Тип фильтра FQDN (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
BLLIST_FQDN_FILTER_TYPE=0
### Файл с шаблонами FQDN для опции BLLIST_FQDN_FILTER (каждый шаблон в отдельной строке. # в первом символе строки - комментирует строку)
BLLIST_FQDN_FILTER_FILE="/etc/ruantiblock/fqdn_filter"
-### Обрезка www[0-9]. в FQDN (0 - off, 1 - on)
+### Обрезка www[0-9]. в FQDN (0 - выкл, 1 - вкл)
BLLIST_STRIP_WWW=1
-### Преобразование кириллических доменов в punycode (0 - off, 1 - on)
+### Преобразование кириллических доменов в punycode (0 - выкл, 1 - вкл)
BLLIST_ENABLE_IDN=0
-### Перенаправлять DNS-запросы на альтернативный DNS-сервер для заблокированных FQDN (0 - off, 1 - on)
+### Перенаправлять DNS-запросы на альтернативный DNS-сервер для заблокированных FQDN (0 - выкл, 1 - вкл)
BLLIST_ALT_NSLOOKUP=0
### Альтернативный DNS-сервер
BLLIST_ALT_DNS_ADDR="8.8.8.8"
@@ -112,12 +120,12 @@ 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"
-RA_IP_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/ip/ruantiblock.ip"
-RA_IP_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/ip/ruantiblock.dnsmasq"
-RA_IP_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/ip/update_status"
-RA_FQDN_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/fqdn/ruantiblock.ip"
-RA_FQDN_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/fqdn/ruantiblock.dnsmasq"
-RA_FQDN_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/fqdn/update_status"
+RA_IP_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/ip/ruantiblock.ip"
+RA_IP_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/ip/ruantiblock.dnsmasq"
+RA_IP_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/ip/update_status"
+RA_FQDN_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/fqdn/ruantiblock.ip"
+RA_FQDN_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/fqdn/ruantiblock.dnsmasq"
+RA_FQDN_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/fqdn/update_status"
RBL_ENCODING=""
ZI_ENCODING="CP1251"
AF_ENCODING=""
diff --git a/ruantiblock/files/etc/ruantiblock/scripts/config_script b/ruantiblock/files/etc/ruantiblock/scripts/config_script
index 53bff54..77a6dfa 100644
--- a/ruantiblock/files/etc/ruantiblock/scripts/config_script
+++ b/ruantiblock/files/etc/ruantiblock/scripts/config_script
@@ -1,6 +1,6 @@
AWK_CMD="awk"
UCI_SECTION="ruantiblock.config"
-UCI_VARS="proxy_mode proxy_local_clients ipset_clear_sets allowed_hosts_mode allowed_hosts_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 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/etc/ruantiblock/scripts/info_output b/ruantiblock/files/etc/ruantiblock/scripts/info_output
index b1a5d46..8d55a0f 100644
--- a/ruantiblock/files/etc/ruantiblock/scripts/info_output
+++ b/ruantiblock/files/etc/ruantiblock/scripts/info_output
@@ -1,66 +1,36 @@
Info() {
- local _set
- if CheckStatus; then
- printf "{\"status\":\"enabled\",\"last_blacklist_update\":{"
- if [ -f "$UPDATE_STATUS_FILE" ]; then
- $AWK_CMD '{
- if(NF < 4)
- print "\"status\":false";
- else
- print "\"status\":true,\"date\":\""$4"\",\"cidr\":\""$1"\",\"ip\":\""$2"\",\"fqdn\":\""$3"\"";
- }' "$UPDATE_STATUS_FILE"
- else
- printf "\"status\":false"
- fi
- printf "},"
- IptListBllistChain | $AWK_CMD '
+ local _update_status
+ if [ -f "$UPDATE_STATUS_FILE" ]; then
+ _update_status=`$AWK_CMD '{
+ if(NF < 4)
+ printf "{\"status\":false}";
+ 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" '
BEGIN {
- printf "\"iptables\":{"
+ rules_str = "";
}
{
- if(NR > 2)
- printf "\""(($10 == "!") ? $12 : $11)"\":\""$2"\",";
+ rules_str = rules_str $0;
}
END {
- printf "\"_dummy\":false},";
+ if(NR == 0) {
+ printf "{\"status\": \"disabled\"}";
+ exit 1;
+ } else {
+ printf "{\"status\":\"enabled\",\"last_blacklist_update\":%s,\"rules\":%s", UPDATE_STATUS, rules_str;
+ exit 0;
+ };
}'
- printf "\"ipset\":{";
- for _set in "$IPSET_ALLOWED_HOSTS" "$IPSET_ONION" "$IPSET_CIDR_TMP" "$IPSET_CIDR" "$IPSET_IP_TMP" "$IPSET_IP"
- do
- $IPSET_CMD list "$_set" -terse | $AWK_CMD -F ": " '
- {
- if($1 ~ /^Name/) {
- printf "\""$2"\":[";
- }
- else if($1 ~ /^Size in memory/) {
- printf "\""$2"\",";
- }
- else if($1 ~ /^Number of entries/) {
- printf "\""$2"\"],";
- };
- }'
- done
- $IPSET_CMD list "$IPSET_DNSMASQ" | $AWK_CMD -F ": " '
- {
- if($1 ~ /^Name/) {
- printf "\""$2"\":[";
- }
- else if($1 ~ /^Size in memory/) {
- printf "\""$2"\",";
- }
- else if($1 ~ /^Number of entries/) {
- printf "\""$2"\"]},\"dnsmasq\":[";
- }
- else if($0 ~ /^[0-9]/) {
- split($0, a, " ");
- printf "[\"" a[1] "\",\"" a[3] "\"],";
- };
- }
- END {
- printf "false],";
- }'
- printf "\"_dummy\":false}"
- else
- printf "{\"status\": \"disabled\"}"
+ if [ $? -eq 0 ]; then
+ printf ",\"dnsmasq\":"
+ $NFT_CMD -j list set $NFT_TABLE "$NFTSET_DNSMASQ" 2> /dev/null
+ printf ",\"dnsmasq_u\":"
+ $NFT_CMD -j list set $NFT_TABLE "$NFTSET_DNSMASQ_USER" 2> /dev/null
+ printf "}"
fi
}
diff --git a/ruantiblock/files/etc/ruantiblock/scripts/ipt_functions b/ruantiblock/files/etc/ruantiblock/scripts/ipt_functions
deleted file mode 100644
index 102d4e0..0000000
--- a/ruantiblock/files/etc/ruantiblock/scripts/ipt_functions
+++ /dev/null
@@ -1,128 +0,0 @@
-
-IP_CMD="ip"
-IPT_CMD=`which iptables-legacy`
-if [ $? -ne 0 ]; then
- IPT_CMD=`which iptables`
- if [ $? -ne 0 ]; then
- echo " Error! Iptables doesn't exists" >&2
- exit 1
- fi
-fi
-
-IPT_ALLOWED_HOSTS_CHAIN="${NAME}_allowed_hosts"
-IPT_BLLIST_CHAIN="${NAME}_blacklist"
-IPT_ACTION_CHAIN="${NAME}_action"
-IPT_FIRST_CHAIN="PREROUTING"
-VPN_ROUTE_TABLE_ID=99
-
-case "$ALLOWED_HOSTS_MODE" in
- "1")
- IPT_ALLOWED_HOSTS_RULE="-m set --match-set ${IPSET_ALLOWED_HOSTS} src -j ${IPT_BLLIST_CHAIN}"
- ;;
- "2")
- IPT_ALLOWED_HOSTS_RULE="-m set ! --match-set ${IPSET_ALLOWED_HOSTS} src -j ${IPT_BLLIST_CHAIN}"
- ;;
- *)
- IPT_ALLOWED_HOSTS_RULE="-j ${IPT_BLLIST_CHAIN}"
- ;;
-esac
-
-if [ "$PROXY_MODE" = "2" ]; then
- IPT_TABLE="mangle"
-else
- IPT_TABLE="nat"
-fi
-
-IptCmdWrapper() {
- local _i=0 _attempts=10 _return_code=1
- while [ $_i -lt $_attempts ]
- do
- if $*; then
- _return_code=$?
- break
- fi
- _i=`expr $_i + 1`
- done
- return $_return_code
-}
-
-IptVpnRouteAdd() {
- VPN_IP=`$IP_CMD addr list dev $IF_VPN 2> /dev/null | $AWK_CMD '/inet/{sub("/[0-9]{1,2}$", "", $2); print $2; exit}'`
- if [ -n "$VPN_IP" ]; then
- echo 0 > /proc/sys/net/ipv4/conf/$IF_VPN/rp_filter
- IptVpnRouteDel 2> /dev/null
- $IP_CMD rule add fwmark $VPN_PKTS_MARK table $VPN_ROUTE_TABLE_ID priority 1000
- $IP_CMD route add default via $VPN_IP table $VPN_ROUTE_TABLE_ID
- fi
-}
-
-IptVpnRouteDel() {
- $IP_CMD route flush table $VPN_ROUTE_TABLE_ID
- $IP_CMD rule del table $VPN_ROUTE_TABLE_ID
-}
-
-IptVpnRouteStatus() {
- [ -n "`$IP_CMD route show table $VPN_ROUTE_TABLE_ID 2> /dev/null`" ] && return 0
- return 1
-}
-
-IptMainAdd() {
- local _set
- $IPT_CMD -t "$IPT_TABLE" -N "$IPT_ACTION_CHAIN"
- $IPT_CMD -t "$IPT_TABLE" -N "$IPT_BLLIST_CHAIN"
- $IPT_CMD -t "$IPT_TABLE" -N "$IPT_ALLOWED_HOSTS_CHAIN"
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ALLOWED_HOSTS_CHAIN" $IPT_ALLOWED_HOSTS_RULE
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -I "$IPT_FIRST_CHAIN" 1 -j "$IPT_ALLOWED_HOSTS_CHAIN"
-
- if [ "$PROXY_MODE" = "2" ]; then
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -j MARK --set-mark $VPN_PKTS_MARK
- IPT_IPSETS="${IPSET_CIDR} ${IPSET_IP} ${IPSET_DNSMASQ}"
- elif [ "$PROXY_MODE" = "3" ]; then
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -p tcp -j REDIRECT --to-ports ${T_PROXY_PORT_TCP}
- if [ "$T_PROXY_ALLOW_UDP" = "1" ]; then
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -p udp -j REDIRECT --to-ports ${T_PROXY_PORT_UDP}
- fi
- IPT_IPSETS="${IPSET_CIDR} ${IPSET_IP} ${IPSET_DNSMASQ}"
- else
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -p tcp -j REDIRECT --to-ports ${TOR_TRANS_PORT}
- if [ "$TOR_ALLOW_UDP" = "1" ]; then
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -p udp -j REDIRECT --to-ports ${TOR_TRANS_PORT}
- fi
- IPT_IPSETS="${IPSET_ONION} ${IPSET_CIDR} ${IPSET_IP} ${IPSET_DNSMASQ}"
- fi
-
- for _set in $IPT_IPSETS
- do
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_BLLIST_CHAIN" -m set --match-set "$_set" dst -j "$IPT_ACTION_CHAIN"
- done
- if [ "$PROXY_MODE" = "2" ]; then
- IptVpnRouteAdd
- fi
-}
-
-IptMainDel() {
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -D "$IPT_FIRST_CHAIN" -j "$IPT_ALLOWED_HOSTS_CHAIN"
- $IPT_CMD -t "$IPT_TABLE" -F "$IPT_ALLOWED_HOSTS_CHAIN"
- $IPT_CMD -t "$IPT_TABLE" -X "$IPT_ALLOWED_HOSTS_CHAIN"
- $IPT_CMD -t "$IPT_TABLE" -F "$IPT_BLLIST_CHAIN"
- $IPT_CMD -t "$IPT_TABLE" -X "$IPT_BLLIST_CHAIN"
- $IPT_CMD -t "$IPT_TABLE" -F "$IPT_ACTION_CHAIN"
- $IPT_CMD -t "$IPT_TABLE" -X "$IPT_ACTION_CHAIN"
- if [ "$PROXY_MODE" = "2" ]; then
- IptVpnRouteDel 2> /dev/null
- fi
-}
-
-IPT_OUTPUT_FIRST_RULE="-j ${IPT_BLLIST_CHAIN}"
-
-IptLocalClientsAdd() {
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -I OUTPUT 1 $IPT_OUTPUT_FIRST_RULE
-}
-
-IptLocalClientsDel() {
- IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -D OUTPUT $IPT_OUTPUT_FIRST_RULE
-}
-
-IptListBllistChain() {
- $IPT_CMD -t "$IPT_TABLE" -v -L "$IPT_BLLIST_CHAIN"
-}
diff --git a/ruantiblock/files/etc/ruantiblock/scripts/nft_functions b/ruantiblock/files/etc/ruantiblock/scripts/nft_functions
new file mode 100644
index 0000000..e3ac59b
--- /dev/null
+++ b/ruantiblock/files/etc/ruantiblock/scripts/nft_functions
@@ -0,0 +1,118 @@
+IP_CMD="ip"
+NFT_ALLOWED_HOSTS_CHAIN="allowed_hosts"
+NFT_BLLIST_CHAIN="blacklist"
+NFT_ACTION_CHAIN="action"
+NFT_LOCAL_CLIENTS_CHAIN="local_clients"
+VPN_ROUTE_TABLE_ID=99
+
+if [ "$PROXY_MODE" = "2" ]; then
+ MAIN_CHAIN_TYPE="type filter hook prerouting priority -160; policy accept;"
+ LOCAL_CLIENTS_CHAIN_TYPE="type route hook output priority -160; policy accept;"
+else
+ MAIN_CHAIN_TYPE="type nat hook prerouting priority -110; policy accept;"
+ LOCAL_CLIENTS_CHAIN_TYPE="type nat hook output priority -110; policy accept;"
+fi
+
+case "$ALLOWED_HOSTS_MODE" in
+ "1")
+ IPT_ALLOWED_HOSTS_RULE="ip saddr @${NFTSET_ALLOWED_HOSTS} jump ${NFT_BLLIST_CHAIN}"
+ ;;
+ "2")
+ IPT_ALLOWED_HOSTS_RULE="ip saddr != @${NFTSET_ALLOWED_HOSTS} jump ${NFT_BLLIST_CHAIN}"
+ ;;
+ *)
+ IPT_ALLOWED_HOSTS_RULE="jump ${NFT_BLLIST_CHAIN}"
+ ;;
+esac
+
+NftCmdWrapper() {
+ local _i=0 _attempts=10 _return_code=1
+ while [ $_i -lt $_attempts ]
+ do
+ if $*; then
+ _return_code=$?
+ break
+ fi
+ _i=`expr $_i + 1`
+ done
+ return $_return_code
+}
+
+IptVpnRouteDel() {
+ $IP_CMD route flush table $VPN_ROUTE_TABLE_ID
+ $IP_CMD rule del table $VPN_ROUTE_TABLE_ID
+}
+
+IptVpnRouteAdd() {
+ VPN_IP=`$IP_CMD addr list dev $IF_VPN 2> /dev/null | $AWK_CMD '/inet/{sub("/[0-9]{1,2}$", "", $2); print $2; exit}'`
+ if [ -n "$VPN_IP" ]; then
+ echo 0 > /proc/sys/net/ipv4/conf/$IF_VPN/rp_filter
+ IptVpnRouteDel 2> /dev/null
+ $IP_CMD rule add fwmark $VPN_PKTS_MARK table $VPN_ROUTE_TABLE_ID priority 1000
+ $IP_CMD route add default via $VPN_IP table $VPN_ROUTE_TABLE_ID
+ fi
+}
+
+NftVpnRouteStatus() {
+ [ -n "`$IP_CMD route show table $VPN_ROUTE_TABLE_ID 2> /dev/null`" ] && return 0
+ return 1
+}
+
+NftMainAdd() {
+ local _nft_sets="${NFTSET_CIDR} ${NFTSET_CIDR_USER} ${NFTSET_IP} ${NFTSET_IP_USER} ${NFTSET_DNSMASQ} ${NFTSET_DNSMASQ_USER}" _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_BLLIST_CHAIN"
+ $NFT_CMD add chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" { $MAIN_CHAIN_TYPE }
+ NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" $IPT_ALLOWED_HOSTS_RULE
+ if [ "$PROXY_MODE" = "2" ]; then
+ NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" mark set $VPN_PKTS_MARK
+ elif [ "$PROXY_MODE" = "3" ]; then
+ NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" tcp dport { 0-65535 } redirect to $T_PROXY_PORT_TCP
+ if [ "$T_PROXY_ALLOW_UDP" = "1" ]; then
+ NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" udp dport { 0-65535 } redirect to $T_PROXY_PORT_UDP
+ fi
+ else
+ NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" tcp dport { 0-65535 } redirect to $TOR_TRANS_PORT
+ if [ "$TOR_ALLOW_UDP" = "1" ]; then
+ NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" udp dport { 0-65535 } redirect to $TOR_TRANS_PORT
+ fi
+ _nft_sets="${NFTSET_ONION} ${_nft_sets}"
+ fi
+ for _set in $_nft_sets
+ do
+ NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip daddr "@${_set}" counter goto "$NFT_ACTION_CHAIN"
+ done
+ if [ "$PROXY_MODE" = "2" ]; then
+ IptVpnRouteAdd
+ fi
+}
+
+NftMainDelete() {
+ $NFT_CMD flush chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN"
+ $NFT_CMD delete chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN"
+ $NFT_CMD flush chain $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN"
+ $NFT_CMD delete chain $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN"
+ $NFT_CMD flush chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
+ $NFT_CMD delete chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
+ $NFT_CMD flush chain $NFT_TABLE "$NFT_ACTION_CHAIN"
+ $NFT_CMD delete chain $NFT_TABLE "$NFT_ACTION_CHAIN"
+ IptVpnRouteDel 2> /dev/null
+}
+
+NftLocalClientsAdd() {
+ NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN" jump "$NFT_BLLIST_CHAIN"
+}
+
+NftListBllistChain() {
+ $NFT_CMD -t list chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
+}
+
+NftListBllistChainJson() {
+ $NFT_CMD -t -j list chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
+}
+
+NftReturnStatus() {
+ $NFT_CMD -c add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" continue &> /dev/null
+ return $?
+}
diff --git a/ruantiblock/files/usr/bin/ruantiblock b/ruantiblock/files/usr/bin/ruantiblock
old mode 100755
new mode 100644
index 629b2d5..e1d9add
--- a/ruantiblock/files/usr/bin/ruantiblock
+++ b/ruantiblock/files/usr/bin/ruantiblock
@@ -15,7 +15,7 @@ export LANGUAGE="en"
CONFIG_DIR="/etc/${NAME}"
CONFIG_FILE="${CONFIG_DIR}/${NAME}.conf"
-export DATA_DIR="/var/${NAME}"
+export DATA_DIR="${CONFIG_DIR}/var"
export MODULES_DIR="/usr/libexec/${NAME}"
### Дополнительный конфиг dnsmasq с FQDN записями блэклиста
export DNSMASQ_DATA_FILE="/var/dnsmasq.d/${NAME}.dnsmasq"
@@ -26,12 +26,12 @@ export HTML_DIR="/www"
########################## Default Settings ############################
-### Режим обработки пакетов в правилах iptables (1 - Tor, 2 - VPN, 3 - Прозрачный прокси)
+### Режим обработки пакетов в правилах nftables (1 - Tor, 2 - VPN, 3 - Прозрачный прокси)
export PROXY_MODE=1
-### Применять правила проксификации для трафика локальных сервисов роутера (0 - off, 1 - on)
+### Применять правила проксификации для трафика локальных сервисов роутера (0 - выкл, 1 - вкл)
export PROXY_LOCAL_CLIENTS=1
-### Удаление записей из основных сетов перед началом заполнения временных сетов при обновлении (для освобождения оперативной памяти перед заполнением сетов) (0 - off, 1 - on)
-export IPSET_CLEAR_SETS=0
+### Удаление записей сетов перед началом обновления (для освобождения оперативной памяти перед обновлением сетов) (0 - выкл, 1 - вкл)
+export NFTSET_CLEAR_SETS=0
### Режим фильтра хостов которым разрешено обходить блокировки (0 - выкл., 1 - только адреса из списка, 2 - любые адреса кроме присутствующих в списке)
export ALLOWED_HOSTS_MODE=0
### Список IP адресов хостов для фильтра, через пробел (прим.: 192.168.0.10 192.168.0.15)
@@ -40,7 +40,7 @@ export ALLOWED_HOSTS_LIST=""
export IF_VPN="tun0"
### Порт прозрачного прокси Tor (параметр TransPort в torrc)
export TOR_TRANS_PORT=9040
-### Отправлять в Tor UDP-трафик (0 - off, 1 - on)
+### Отправлять в Tor UDP-трафик (0 - выкл, 1 - вкл)
export TOR_ALLOW_UDP=0
### DNS-сервер для резолвинга в домене .onion (Tor)
export ONION_DNS_ADDR="127.0.0.1#9053"
@@ -50,9 +50,9 @@ export VPN_PKTS_MARK=8
export T_PROXY_PORT_TCP=1100
### UDP порт прокси в режиме прозрачного прокси
export T_PROXY_PORT_UDP=1100
-### Отправлять в прозрачный прокси UDP-трафик (0 - off, 1 - on)
+### Отправлять в прозрачный прокси UDP-трафик (0 - выкл, 1 - вкл)
export T_PROXY_ALLOW_UDP=0
-### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - off, 1 - on)
+### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - выкл, 1 - вкл)
### В $DATA_DIR можно создать текстовый файл user_entries с записями IP, CIDR или FQDN (одна на строку). Эти записи будут добавлены в список блокировок
### В записях FQDN можно задать DNS-сервер для разрешения данного домена, через пробел (прим.: domain.com 8.8.8.8)
### Можно комментировать строки (#)
@@ -61,14 +61,20 @@ export ADD_USER_ENTRIES=0
export USER_ENTRIES_DNS=""
### Файл пользовательских записей
export USER_ENTRIES_FILE="${CONFIG_DIR}/user_entries"
-### Запись событий в syslog (0 - off, 1 - on)
+### Запись событий в syslog (0 - выкл, 1 - вкл)
export ENABLE_LOGGING=1
-### Html-страница с инфо о текущем статусе (0 - off, 1 - on) (не используется в OpenWrt)
+### Html-страница с инфо о текущем статусе (0 - выкл, 1 - вкл) (не используется в OpenWrt)
export ENABLE_HTML_INFO=0
-### Максимальное кол-во элементов списка ipset
-export IPSET_MAXELEM=2000000
-### Таймаут для записей в сете $IPSET_DNSMASQ
-export IPSET_DNSMASQ_TIMEOUT=3600
+### Максимальное кол-во элементов списка nftables
+export NFTSET_MAXELEM_CIDR=65535
+export NFTSET_MAXELEM_IP=1000000
+export NFTSET_MAXELEM_DNSMASQ=65535
+### Политика отбора элементов в сетах nftables. "performance" - производительность и большее потребление RAM. "memory" - хуже производительность и меньше потребление RAM
+export NFTSET_POLICY_CIDR="memory"
+export NFTSET_POLICY_IP="memory"
+export NFTSET_POLICY_DNSMASQ="performance"
+### Таймаут для записей в сете $NFTSET_DNSMASQ
+export NFTSET_DNSMASQ_TIMEOUT="1h"
### Кол-во попыток обновления блэклиста (в случае неудачи)
export MODULE_RUN_ATTEMPTS=3
### Таймаут между попытками обновления
@@ -84,7 +90,7 @@ export BLLIST_MODULE=""
export BLLIST_PRESET=""
### В случае если из источника получено менее указанного кол-ва записей, то обновления списков не происходит
export BLLIST_MIN_ENTRIES=3000
-### Лимит IP адресов. При достижении, в конфиг ipset будет добавлена вся подсеть /24 вместо множества IP адресов пренадлежащих этой сети (0 - off)
+### Лимит IP адресов. При достижении, в конфиг ipset будет добавлена вся подсеть /24 вместо множества IP адресов пренадлежащих этой сети (0 - выкл)
export BLLIST_IP_LIMIT=0
### Подсети класса C (/24). IP адреса из этих подсетей не группируются при оптимизации (записи д.б. в виде: 68.183.221. 149.154.162. и пр.). Прим.: "68.183.221. 149.154.162."
export BLLIST_GR_EXCLUDED_NETS=""
@@ -92,29 +98,29 @@ export BLLIST_GR_EXCLUDED_NETS=""
export BLLIST_SUMMARIZE_IP=0
### Группировать идущие подряд подсети /24 в диапазоны CIDR
export BLLIST_SUMMARIZE_CIDR=0
-### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига ipset (0 - off, 1 - on)
+### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига ipset (0 - выкл, 1 - вкл)
export BLLIST_IP_FILTER=0
### Тип фильтра IP (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
export BLLIST_IP_FILTER_TYPE=0
### Файл с шаблонами IP для опции BLLIST_IP_FILTER (каждый шаблон в отдельной строке. # в первом символе строки - комментирует строку)
export BLLIST_IP_FILTER_FILE="${CONFIG_DIR}/ip_filter"
-### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - off)
+### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - выкл)
export BLLIST_SD_LIMIT=16
### SLD не подлежащие группировке при оптимизации (через пробел)
export BLLIST_GR_EXCLUDED_SLD="livejournal.com facebook.com vk.com blog.jp msk.ru net.ru org.ru net.ua com.ua org.ua co.uk amazonaws.com"
### Не группировать SLD попадающие под выражения (через пробел) ("[.][a-z]{2,3}[.][a-z]{2}$")
export BLLIST_GR_EXCLUDED_MASKS=""
-### Фильтрация записей блэклиста по шаблонам из файла ENTRIES_FILTER_FILE. Записи (FQDN) попадающие под шаблоны исключаются из кофига dnsmasq (0 - off, 1 - on)
+### Фильтрация записей блэклиста по шаблонам из файла ENTRIES_FILTER_FILE. Записи (FQDN) попадающие под шаблоны исключаются из кофига dnsmasq (0 - выкл, 1 - вкл)
export BLLIST_FQDN_FILTER=0
### Тип фильтра FQDN (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
export BLLIST_FQDN_FILTER_TYPE=0
### Файл с шаблонами FQDN для опции BLLIST_FQDN_FILTER (каждый шаблон в отдельной строке. # в первом символе строки - комментирует строку)
export BLLIST_FQDN_FILTER_FILE="${CONFIG_DIR}/fqdn_filter"
-### Обрезка www[0-9]. в FQDN (0 - off, 1 - on)
+### Обрезка www[0-9]. в FQDN (0 - выкл, 1 - вкл)
export BLLIST_STRIP_WWW=1
-### Преобразование кириллических доменов в punycode (0 - off, 1 - on)
+### Преобразование кириллических доменов в punycode (0 - выкл, 1 - вкл)
export BLLIST_ENABLE_IDN=0
-### Перенаправлять DNS-запросы на альтернативный DNS-сервер для заблокированных FQDN (0 - off, 1 - on)
+### Перенаправлять DNS-запросы на альтернативный DNS-сервер для заблокированных FQDN (0 - выкл, 1 - вкл)
export BLLIST_ALT_NSLOOKUP=0
### Альтернативный DNS-сервер
export BLLIST_ALT_DNS_ADDR="8.8.8.8"
@@ -125,12 +131,12 @@ export RBL_IP_URL="https://reestr.rublacklist.net/api/v3/ips/"
export ZI_ALL_URL="https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv"
export AF_IP_URL="https://antifilter.download/list/allyouneed.lst"
export AF_FQDN_URL="https://antifilter.download/list/domains.lst"
-export RA_IP_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/ip/ruantiblock.ip"
-export RA_IP_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/ip/ruantiblock.dnsmasq"
-export RA_IP_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/ip/update_status"
-export RA_FQDN_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/fqdn/ruantiblock.ip"
-export RA_FQDN_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/fqdn/ruantiblock.dnsmasq"
-export RA_FQDN_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/fqdn/update_status"
+export RA_IP_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/ip/ruantiblock.ip"
+export RA_IP_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/ip/ruantiblock.dnsmasq"
+export RA_IP_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/ip/update_status"
+export RA_FQDN_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/fqdn/ruantiblock.ip"
+export RA_FQDN_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/fqdn/ruantiblock.dnsmasq"
+export RA_FQDN_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/fqdn/update_status"
export RBL_ENCODING=""
export ZI_ENCODING="CP1251"
export AF_ENCODING=""
@@ -141,18 +147,19 @@ export RA_ENCODING=""
### External config
[ -f "$CONFIG_FILE" ] && . "$CONFIG_FILE"
-CONFIG_SCRIPT="${CONFIG_DIR}/scripts/config_script"
-START_SCRIPT="${CONFIG_DIR}/scripts/start_script"
-STOP_SCRIPT="${CONFIG_DIR}/scripts/stop_script"
+SCRIPTS_DIR="${CONFIG_DIR}/scripts"
+CONFIG_SCRIPT="${SCRIPTS_DIR}/config_script"
+START_SCRIPT="${SCRIPTS_DIR}/start_script"
+STOP_SCRIPT="${SCRIPTS_DIR}/stop_script"
### Config script
[ -f "$CONFIG_SCRIPT" ] && . "$CONFIG_SCRIPT"
### Utilities
AWK_CMD="awk"
-IPSET_CMD=`which ipset`
+NFT_CMD=`which nft`
if [ $? -ne 0 ]; then
- echo " Error! Ipset doesn't exists" >&2
+ echo " Error! Nftables doesn't exists" >&2
exit 1
fi
LOGGER_CMD=`which logger`
@@ -168,24 +175,33 @@ if [ $? -ne 0 ]; then
fi
WGET_PARAMS="--no-check-certificate -q -O"
export IP_DATA_FILE="${DATA_DIR}/${NAME}.ip"
-export IPSET_ALLOWED_HOSTS="r_allowed_ip"
-export IPSET_ONION="r_onion"
-export IPSET_CIDR="rc"
-export IPSET_CIDR_TMP="${IPSET_CIDR}t"
-export IPSET_IP="ri"
-export IPSET_IP_TMP="${IPSET_IP}t"
-export IPSET_DNSMASQ="rd"
+export NFT_TABLE="ip r"
+export NFT_TABLE_DNSMASQ="4#ip#r"
+export NFTSET_ALLOWED_HOSTS="allowed_ip"
+export NFTSET_ONION="onion"
+export NFTSET_CIDR="c"
+export NFTSET_IP="i"
+export NFTSET_DNSMASQ="d"
+export NFTSET_CIDR_USER="cu"
+export NFTSET_IP_USER="iu"
+export NFTSET_DNSMASQ_USER="du"
+export NFTSET_ALLOWED_HOSTS_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};"
export UPDATE_STATUS_FILE="${DATA_DIR}/update_status"
-UPDATE_PID_FILE="/var/run/${NAME}_update.pid"
+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"
-IPT_FUNCTIONS="${CONFIG_DIR}/scripts/ipt_functions"
-INFO_OUTPUT_FUNCTION="${CONFIG_DIR}/scripts/info_output"
+NFT_FUNCTIONS="${SCRIPTS_DIR}/nft_functions"
+INFO_OUTPUT_FUNCTION="${SCRIPTS_DIR}/info_output"
######################### External functions ###########################
-. "$IPT_FUNCTIONS"
+. "$NFT_FUNCTIONS"
if [ -f "$INFO_OUTPUT_FUNCTION" ]; then
. "$INFO_OUTPUT_FUNCTION"
else
@@ -196,13 +212,13 @@ fi
Help() {
cat << EOF
- Usage: `basename $0` start|force-start|stop|destroy|restart|update|force-update|data-files|status|raw-status|html-info|help
+ Usage: `basename $0` start|force-start|stop|destroy|restart|reload|update|force-update|data-files|status|raw-status|html-info|help
start : Start
force-start : Removing the pid-file before running
stop : Stop
- destroy : Stop + destroy ipsets and clear all data files
+ destroy : Stop + remove nft table and clear all data files
restart : Restart
- reload : Renew iptables configuration
+ reload : Renew nftables configuration
update : Update blacklist
force-update : Force update blacklist
data-files : Create ${IP_DATA_FILE} & ${DNSMASQ_DATA_FILE} (without network functions)
@@ -216,10 +232,12 @@ cat << EOF
`basename $0` stop
`basename $0` destroy
`basename $0` restart
+ `basename $0` reload
`basename $0` update
`basename $0` force-update
`basename $0` data-files
`basename $0` status
+ `basename $0` raw-status
`basename $0` html-info
EOF
}
@@ -259,86 +277,68 @@ DnsmasqRestart() {
eval `echo "$DNSMASQ_RESTART_CMD"`
}
-IsIpsetExists() {
- $IPSET_CMD list "$1" -terse &> /dev/null
- return $?
-}
-
-FlushIpSets() {
+FlushNftSets() {
local _set
for _set in "$@"
do
- IsIpsetExists "$_set" && $IPSET_CMD flush "$_set"
+ $NFT_CMD flush set $NFT_TABLE "$_set" &> /dev/null
done
}
-DestroyIpsets() {
- local _set
- for _set in "$@"
- do
- IsIpsetExists "$_set" && $IPSET_CMD destroy "$_set"
- done
-}
-
-FillAllowedHostsSet() {
- local _entry
- for _entry in $ALLOWED_HOSTS_LIST
- do
- $IPSET_CMD add "$IPSET_ALLOWED_HOSTS" "$_entry"
- done
-}
-
-AddIptRules() {
- IptMainAdd
- if [ "$PROXY_LOCAL_CLIENTS" = "1" ]; then
- IptLocalClientsAdd
+AddNftSets() {
+ local _hosts
+ $NFT_CMD add set $NFT_TABLE "$NFTSET_CIDR" { type "$NFTSET_CIDR_TYPE"\; size $NFTSET_MAXELEM_CIDR\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
+ $NFT_CMD add set $NFT_TABLE "$NFTSET_CIDR_USER" { type "$NFTSET_CIDR_TYPE"\; size $NFTSET_MAXELEM_CIDR\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
+ $NFT_CMD add set $NFT_TABLE "$NFTSET_IP" { type "$NFTSET_IP_TYPE"\; size $NFTSET_MAXELEM_IP\; policy "$NFTSET_POLICY_IP"\; }
+ $NFT_CMD add set $NFT_TABLE "$NFTSET_IP_USER" { type "$NFTSET_IP_TYPE"\; size $NFTSET_MAXELEM_IP\; policy "$NFTSET_POLICY_IP"\; }
+ $NFT_CMD add set $NFT_TABLE "$NFTSET_DNSMASQ" { type "$NFTSET_DNSMASQ_TYPE"\; size $NFTSET_MAXELEM_DNSMASQ\; policy "$NFTSET_POLICY_DNSMASQ"\; flags timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; }
+ $NFT_CMD add set $NFT_TABLE "$NFTSET_DNSMASQ_USER" { type "$NFTSET_DNSMASQ_TYPE"\; size $NFTSET_MAXELEM_DNSMASQ\; policy "$NFTSET_POLICY_DNSMASQ"\; flags timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; }
+ $NFT_CMD add set $NFT_TABLE "$NFTSET_ONION" { type "$NFTSET_DNSMASQ_TYPE"\; size $NFTSET_MAXELEM_DNSMASQ\; policy "$NFTSET_POLICY_DNSMASQ"\; flags timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; }
+ $NFT_CMD add set $NFT_TABLE "$NFTSET_ALLOWED_HOSTS" { type "$NFTSET_ALLOWED_HOSTS_TYPE"\; policy "$NFTSET_POLICY_IP"\; }
+ _hosts=`printf "$ALLOWED_HOSTS_LIST" | $AWK_CMD '{gsub(/[ ]+/, ",", $0); printf $0;}'`
+ if [ -n "$_hosts" ]; then
+ $NFT_CMD add element $NFT_TABLE "$NFTSET_ALLOWED_HOSTS" { "$_hosts" }
fi
}
-DelIptRules() {
- IptLocalClientsDel
- IptMainDel
+UpdateBllistSets() {
+ if [ -f "$IP_DATA_FILE" ]; then
+ echo " Updating nft sets..."
+ $NFT_CMD -f "$IP_DATA_FILE"
+ if [ $? -eq 0 ]; then
+ echo " Ok"
+ else
+ echo " Error! Nft set wasn't updated" >&2
+ MakeLogRecord "err" "Error! Nft set wasn't updated"
+ fi
+ fi
+}
+
+AddNftRules() {
+ NftMainAdd
+ if [ "$PROXY_LOCAL_CLIENTS" = "1" ]; then
+ NftLocalClientsAdd
+ fi
+}
+
+DeleteNftRules() {
+ NftMainDelete
}
SetNetConfig() {
- local _set
- ### Создание списков ipset. Проверка на наличие списка с таким же именем, если нет, то создается новый
- for _set in "$IPSET_CIDR_TMP" "$IPSET_CIDR"
- do
- IsIpsetExists "$_set" || $IPSET_CMD create "$_set" hash:net maxelem $IPSET_MAXELEM
- done
- for _set in "$IPSET_ALLOWED_HOSTS" "$IPSET_IP_TMP" "$IPSET_IP"
- do
- IsIpsetExists "$_set" || $IPSET_CMD create "$_set" hash:ip maxelem $IPSET_MAXELEM
- done
- for _set in "$IPSET_DNSMASQ" "$IPSET_ONION"
- do
- IsIpsetExists "$_set" || $IPSET_CMD create "$_set" hash:ip maxelem $IPSET_MAXELEM timeout $IPSET_DNSMASQ_TIMEOUT
- done
- AddIptRules
+ $NFT_CMD add table $NFT_TABLE
+ AddNftSets
+ AddNftRules
}
DropNetConfig() {
- DelIptRules
- FlushIpSets "$IPSET_ALLOWED_HOSTS" "$IPSET_CIDR_TMP" "$IPSET_CIDR" "$IPSET_IP_TMP" "$IPSET_IP" "$IPSET_DNSMASQ" "$IPSET_ONION"
+ DeleteNftRules
+ FlushNftSets "$NFTSET_ALLOWED_HOSTS" "$NFTSET_CIDR" "$NFTSET_CIDR_USER" "$NFTSET_IP" "$NFTSET_IP_USER" "$NFTSET_DNSMASQ" "$NFTSET_DNSMASQ_USER" "$NFTSET_ONION"
}
-FillIpsets() {
- local _set
- ### Заполнение списков ipset $IPSET_IP и $IPSET_CIDR. Сначала restore загружает во временные списки, а затем swap из временных добавляет в основные
- if [ -f "$IP_DATA_FILE" ]; then
- echo " Filling ipsets..."
- FlushIpSets "$IPSET_IP_TMP" "$IPSET_CIDR_TMP"
- IsIpsetExists "$IPSET_IP_TMP" && IsIpsetExists "$IPSET_CIDR_TMP" && IsIpsetExists "$IPSET_IP" && IsIpsetExists "$IPSET_CIDR" &&\
- cat "$IP_DATA_FILE" | $IPSET_CMD restore && { $IPSET_CMD swap "$IPSET_IP_TMP" "$IPSET_IP"; $IPSET_CMD swap "$IPSET_CIDR_TMP" "$IPSET_CIDR"; }
- if [ $? -eq 0 ]; then
- echo " Ok"
- FlushIpSets "$IPSET_IP_TMP" "$IPSET_CIDR_TMP"
- else
- echo " Error! Ipset wasn't updated" >&2
- MakeLogRecord "err" "Error! Ipset wasn't updated"
- fi
- fi
+DestroyNetConfig() {
+ $NFT_CMD flush table $NFT_TABLE &> /dev/null
+ $NFT_CMD delete table $NFT_TABLE &> /dev/null
}
ClearDataFiles() {
@@ -350,19 +350,8 @@ ClearDataFiles() {
}
CheckStatus() {
- local _set _ipset_return=0 _return_code=1
- if [ "$1" = "ipsets" ]; then
- for _set in "$IPSET_ALLOWED_HOSTS" "$IPSET_CIDR_TMP" "$IPSET_CIDR" "$IPSET_IP_TMP" "$IPSET_IP" "$IPSET_DNSMASQ" "$IPSET_ONION"
- do
- IsIpsetExists "$_set"
- _ipset_return=$?
- [ $_ipset_return -ne 0 ] && break
- done
- fi
- if IptListBllistChain &> /dev/null && [ $_ipset_return -eq 0 ]; then
- _return_code=0
- fi
- return $_return_code
+ NftReturnStatus
+ return $?
}
PreStartCheck() {
@@ -377,43 +366,64 @@ AddUserEntries() {
if [ -f "$USER_ENTRIES_FILE" -a -s "$USER_ENTRIES_FILE" ]; then
$AWK_CMD 'BEGIN {
null="";
- while((getline ip_string 0) {
- split(ip_string, ip_string_arr, " ");
- ip_data_array[ip_string_arr[3]]=null;
- };
- close(ENVIRON["IP_DATA_FILE"]);
- while((getline fqdn_string 0) {
- split(fqdn_string, fqdn_string_arr, "/");
- fqdn_data_array[fqdn_string_arr[2]]=null;
- };
- close(ENVIRON["DNSMASQ_DATA_FILE"]);
+ fqdn_array[0]=null;
+ ip_list="";
+ cidr_list="";
}
- function writeIpsetEntries(val, set) {
- printf "add %s %s\n", set, val >> ENVIRON["IP_DATA_FILE"];
- };
function writeDNSData(val, dns) {
- if(length(dns) == 0 && length(ENVIRON["USER_ENTRIES_DNS"]) > 0)
+ if(length(dns) == 0 && length(ENVIRON["USER_ENTRIES_DNS"]) > 0) {
dns=ENVIRON["USER_ENTRIES_DNS"];
- if(length(dns) > 0)
+ };
+ if(length(dns) > 0) {
printf "server=/%s/%s\n", val, dns >> ENVIRON["DNSMASQ_DATA_FILE"];
- printf "ipset=/%s/%s\n", val, ENVIRON["IPSET_DNSMASQ"] >> ENVIRON["DNSMASQ_DATA_FILE"];
+ };
+ printf "nftset=/%s/%s#%s\n", val, ENVIRON["NFT_TABLE_DNSMASQ"], ENVIRON["NFTSET_DNSMASQ_USER"] >> 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}$/ && !($0 in ip_data_array))
- writeIpsetEntries($0, ENVIRON["IPSET_IP_TMP"]);
- else if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}[\057][0-9]{1,2}$/ && !($0 in ip_data_array))
- writeIpsetEntries($0, ENVIRON["IPSET_CIDR_TMP"]);
- 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})?)?$/ && !($1 in fqdn_data_array))
- writeDNSData($1, $2);
+ if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}$/) {
+ ip_list=ip_list $0 ",";
+ }
+ else if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}[\057][0-9]{1,2}$/) {
+ cidr_list=cidr_list $0 ",";
+ }
+ 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 {\nset %s {type %s;size %s;flags interval;auto-merge;", ENVIRON["NFT_TABLE"], ENVIRON["NFTSET_CIDR_USER"], ENVIRON["NFTSET_CIDR_TYPE"], ENVIRON["NFTSET_MAXELEM_CIDR"] >> ENVIRON["IP_DATA_FILE"];
+ if(length(cidr_list) > 0) {
+ printf "elements={%s};", cidr_list >> ENVIRON["IP_DATA_FILE"];
+ };
+ printf "}\nset %s {type %s;size %s;", ENVIRON["NFTSET_IP_USER"], ENVIRON["NFTSET_IP_TYPE"], ENVIRON["NFTSET_MAXELEM_IP"] >> ENVIRON["IP_DATA_FILE"];
+ if(length(ip_list) > 0) {
+ printf "elements={%s};", ip_list >> ENVIRON["IP_DATA_FILE"];
+ };
+ printf "}\n}\n" >> ENVIRON["IP_DATA_FILE"];
+ writeFqdnEntries();
}' "$USER_ENTRIES_FILE"
fi
fi
}
+ToggleUPIDFile() {
+ if [ "$1" = "del" ]; then
+ rm -f "$U_PID_FILE"
+ else
+ echo "$$" > "$U_PID_FILE"
+ fi
+}
+
GetDataFiles() {
local _return_code=1 _attempt=1 _update_string
PreStartCheck
- echo "$$" > "$UPDATE_PID_FILE"
if [ -n "$BLLIST_PRESET" -a -n "$BLLIST_MODULE" ]; then
while :
do
@@ -445,16 +455,16 @@ GetDataFiles() {
_return_code=0
else
_return_code=2
- rm -f "$UPDATE_PID_FILE"
return $_return_code
fi
- if [ "$PROXY_MODE" = "2" -o "$PROXY_MODE" = "3" ]; then
- printf "\n" >> "$DNSMASQ_DATA_FILE"
- else
- ### Запись для .onion в $DNSMASQ_DATA_FILE
- printf "server=/onion/%s\nipset=/onion/%s\n" "${ONION_DNS_ADDR}" "${IPSET_ONION}" >> "$DNSMASQ_DATA_FILE"
+ if [ $_return_code -eq 0 ]; then
+ if [ "$PROXY_MODE" = "2" -o "$PROXY_MODE" = "3" ]; then
+ printf "\n" >> "$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"
+ fi
fi
- rm -f "$UPDATE_PID_FILE"
return $_return_code
}
@@ -464,22 +474,25 @@ MakeToken() {
Update() {
local _return_code=0
- if CheckStatus ipsets; then
+ if CheckStatus; then
:
else
echo " ${NAME} ${1} - Error! ${NAME} does not running or another error has occurred" >&2
return 1
fi
MakeToken
- if [ -e "$UPDATE_PID_FILE" ] && [ "$1" != "force-update" ]; then
+ if [ -e "$U_PID_FILE" ] && [ "$1" != "force-update" ]; then
echo " ${NAME} ${1} - Error! Another instance of update is already running" >&2
MakeLogRecord "err" "${1} - Error! Another instance of update is already running"
_return_code=2
else
+ ToggleUPIDFile add
echo " ${NAME} ${1}..."
MakeLogRecord "notice" "${1}..."
- if [ "$IPSET_CLEAR_SETS" = "1" ]; then
- FlushIpSets "$IPSET_IP" "$IPSET_CIDR" "$IPSET_DNSMASQ"
+ if [ "$NFTSET_CLEAR_SETS" = "1" ]; then
+ FlushNftSets "$NFTSET_CIDR" "$NFTSET_CIDR_USER" "$NFTSET_IP" "$NFTSET_IP_USER" "$NFTSET_DNSMASQ" "$NFTSET_DNSMASQ_USER"
+ elif [ -z "$BLLIST_PRESET" -a -z "$BLLIST_MODULE" ]; then
+ FlushNftSets "$NFTSET_IP" "$NFTSET_CIDR"
fi
GetDataFiles
case $? in
@@ -488,8 +501,8 @@ Update() {
MakeLogRecord "notice" "Blacklist updated"
;;
2)
- echo " Blacklist update error!" >&2
- MakeLogRecord "err" "Blacklist update error!"
+ echo " Error! Blacklist update error" >&2
+ MakeLogRecord "err" "Error! Blacklist update error"
_return_code=1
;;
*)
@@ -498,10 +511,13 @@ Update() {
_return_code=1
;;
esac
- FlushIpSets "$IPSET_DNSMASQ"
- FillIpsets
- _return_code=$?
+ FlushNftSets "$NFTSET_DNSMASQ" "$NFTSET_ONION" "$NFTSET_DNSMASQ_USER"
+ if [ "$ADD_USER_ENTRIES" != "1" ]; then
+ FlushNftSets "$NFTSET_CIDR_USER" "$NFTSET_IP_USER"
+ fi
+ UpdateBllistSets
DnsmasqRestart
+ ToggleUPIDFile del
fi
MakeToken
return $_return_code
@@ -524,10 +540,8 @@ Start() {
MakeLogRecord "info" "${1}..."
DropNetConfig &> /dev/null
SetNetConfig
- FillAllowedHostsSet
PreStartCheck
- FillIpsets
- _return_code=$?
+ UpdateBllistSets
### Start-script
[ -x "$START_SCRIPT" ] && $START_SCRIPT > /dev/null 2>&1 &
fi
@@ -565,48 +579,55 @@ Reload() {
sleep 1
done
echo " ${NAME} reload..."
- DelIptRules &> /dev/null
- AddIptRules &> /dev/null
+ DeleteNftRules &> /dev/null
+ AddNftRules &> /dev/null
MakeToken
}
Status() {
- local _set
- if CheckStatus; then
- printf "\n \033[1m${NAME} status\033[m: \033[1;32mEnabled\033[m\n\n PROXY_MODE: ${PROXY_MODE}\n PROXY_LOCAL_CLIENTS: ${PROXY_LOCAL_CLIENTS}\n BLLIST_PRESET: ${BLLIST_PRESET}\n BLLIST_MODULE: ${BLLIST_MODULE}\n"
- if [ -f "$UPDATE_STATUS_FILE" ]; then
- $AWK_CMD '{
- update_string=(NF < 4) ? "No data" : $4" (CIDR: "$1" | IP: "$2" | FQDN: "$3")";
- printf "\n Last blacklist update: %s\n", update_string;
- }' "$UPDATE_STATUS_FILE"
- else
- printf "\n Last blacklist update: No data\n"
- fi
- if [ "$PROXY_MODE" = "2" ] && ! IptVpnRouteStatus; then
- printf "\n \033[1;31mVPN ROUTING ERROR! (NEED THE RESTART)\033[m\n"
- fi
- printf "\n \033[4mIptables rules\033[m:\n\n"
- IptListBllistChain | $AWK_CMD '
- {
- if(NR > 2) {
- printf " Match-set: %s\n Bytes: %s\n\n", $11, $2;
- };
- }'
- printf " \033[4mIp sets\033[m:\n\n"
- for _set in "$IPSET_ALLOWED_HOSTS" "$IPSET_ONION" "$IPSET_CIDR_TMP" "$IPSET_CIDR" "$IPSET_IP_TMP" "$IPSET_IP" "$IPSET_DNSMASQ"
- do
- $IPSET_CMD list "$_set" -terse | $AWK_CMD -F ":" '
- {
- if($1 ~ /^(Name|Size in memory|Number of entries)/) {
- printf " %s: %s\n", $1, $2;
- if($1 ~ /^Number of entries/) printf "\n";
- };
- }'
- done
+ local _update_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")";
+ printf "Last blacklist update: %s", update_string;
+ }' "$UPDATE_STATUS_FILE"`
else
- printf "\n \033[1m${NAME} status\033[m: \033[1mDisabled\033[m\n\n"
- exit 2
+ _update_status="Last blacklist update: No data"
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" '
+ BEGIN {
+ rules_str = "";
+ nftset = "";
+ bytes = "";
+ }
+ /@/ {
+ if(match($0, /@[^ ]+/) != 0) {
+ nftset = substr($0, RSTART+1, RLENGTH-1);
+ if(match($0, /bytes [^ ]+/) != 0) {
+ bytes = substr($0, RSTART+6, RLENGTH-6);
+ };
+ rules_str = rules_str " Match-set: " nftset "\n Bytes: " bytes "\n\n";
+ };
+ }
+ END {
+ if(NR == 0) {
+ 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(VPN_ERROR) > 0) {
+ printf "\n "VPN_ERROR"\n";
+ };
+
+ printf "\n \033[4mNftables rules\033[m:\n\n";
+ printf rules_str;
+ }'
}
StatusOutput() {
@@ -651,7 +672,7 @@ case "$BLLIST_PRESET" in
export BLLIST_MODE="fqdn"
BLLIST_MODULE="DownloadRuabBlacklist $BLLIST_MODE"
;;
- *)
+ *)
export BLLIST_SOURCE=""
export BLLIST_MODE=""
;;
@@ -683,10 +704,10 @@ case "$1" in
;;
destroy)
Stop "$1" &> /dev/null
- DestroyIpsets "$IPSET_ALLOWED_HOSTS" "$IPSET_CIDR_TMP" "$IPSET_CIDR" "$IPSET_IP_TMP" "$IPSET_IP" "$IPSET_DNSMASQ" "$IPSET_ONION"
+ DestroyNetConfig
ClearDataFiles
return_code=$?
- rm -f "$UPDATE_PID_FILE" "$START_PID_FILE"
+ ToggleUPIDFile del
DnsmasqRestart
StatusOutput
;;
@@ -696,7 +717,7 @@ case "$1" in
StatusOutput
;;
data-files)
- if [ -e "$UPDATE_PID_FILE" ] && [ "$1" != "force-update" ]; then
+ if [ -e "$U_PID_FILE" ] && [ "$1" != "force-update" ]; then
echo " ${NAME} - Error! Another instance of update is already running" >&2
exit 2
else
@@ -716,7 +737,7 @@ case "$1" in
if [ -e "$START_PID_FILE" ]; then
return_code=3
echo 3
- elif [ -e "$UPDATE_PID_FILE" ]; then
+ elif [ -e "$U_PID_FILE" ]; then
return_code=4
echo 4
else
@@ -730,7 +751,7 @@ case "$1" in
esac
;;
vpn-route-status)
- IptVpnRouteStatus
+ NftVpnRouteStatus
return_code=$?
echo $return_code
;;