update 2026-08-23 16:22:34

This commit is contained in:
action committed 2026-08-23 16:22:34 +08:00
1 parent 36fa3c9afa
commit c9995f5dbc
38 files changed
+841 -1678

No files matched your search

@@ -149,7 +149,8 @@ end
o = s:taboption("Main", Value, "node_socks_port", translate("Node") .. " Socks " .. translate("Listen Port"))
o.default = 1070
o.datatype = "port"
o.datatype = "range(1,65535)"
o.rmempty = false
o:depends({ node = "", ["!reverse"] = true })
--[[
if has_singbox or has_xray then
@@ -727,7 +728,7 @@ end)
o = s2:option(Value, "port", "Socks " .. translate("Listen Port"))
o.default = n + 1080
o.datatype = "port"
o.datatype = "range(1,65535)"
o.rmempty = false
--[[
@@ -46,8 +46,9 @@ o:depends("console_auth", true)
---- Console Port
o = s:option(Value, "console_port", translate("Console Port"), translate("In the browser input routing IP plus port access, such as:192.168.1.1:1188"))
o.datatype = "port"
o.default = 1188
o.datatype = "range(1,65535)"
o.rmempty = false
o:depends("balancing_enable", true)
o = s:option(Flag, "bind_local", translate("Haproxy Port") .. " " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
@@ -151,8 +152,8 @@ end
---- Haproxy Port
o = s:option(Value, "haproxy_port", translate("Haproxy Port"))
o.datatype = "port"
o.default = 1181
o.datatype = "range(1,65535)"
o.rmempty = false
---- Node Weight
@@ -63,7 +63,7 @@ end)
o = s:option(Value, "port", "Socks " .. translate("Listen Port"))
o.default = n + 1080
o.datatype = "port"
o.datatype = "range(1,65535)"
o.rmempty = false
if has_singbox or has_xray then
@@ -1215,11 +1215,15 @@ table td, .table .td {
const set_node_div = {
section: '',
open(cbi_id) {
open(cbi_id, protocol) {
this.section = cbi_id;
document.getElementById("set_node_div").style.display="block";
const node_name = document.getElementById("cbid.<%=appname%>." + cbi_id + ".remarks").value;
document.getElementById("set_node_name").textContent = node_name;
const shunt_div = document.getElementById("set_node_shunt_div");
if (shunt_div) {
shunt_div.style.display = protocol === "_shunt" ? "none" : "";
}
},
close() {
document.getElementById("set_node_div").style.display="none";
@@ -1286,7 +1290,7 @@ table td, .table .td {
<td class="td cbi-section-table-cell nowrap cbi-section-actions pw-actions">
<div class="node-wrapper">
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:To Top%>" onclick="node_action('row_top', null, {btn:this, group:'{{group}}'})" title="<%:To Top%>"/>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="set_node_div.open('{{id}}')"/>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="set_node_div.open('{{id}}','{{protocol}}')"/>
<input class="btn cbi-button cbi-button-add" type="button" value="<%:Copy%>" onclick="node_action('copy', '{{id}}')"/>
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="node_action('edit', '{{id}}')" alt="<%:Edit%>" title="<%:Edit%>">
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="node_action('del', '{{id}}')" alt="<%:Delete%>" title="<%:Delete%>">
@@ -1432,6 +1436,7 @@ table td, .table .td {
innerHTML = innerHTML.split("{{remarks_val}}").join(o["remarks"]);
innerHTML = innerHTML.split("{{address_val}}").join(o["address"] || "");
innerHTML = innerHTML.split("{{port_val}}").join(o["port"] || "");
innerHTML = innerHTML.split("{{protocol}}").join(o["protocol"] || "");
node_tr_html += innerHTML
}
@@ -1620,20 +1625,27 @@ table td, .table .td {
<div style="display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: center; justify-content: center;">
<div id="set_node_div">
<div class="cbi-value" style="display: flex; justify-content: center; align-items: center; margin: 1em 0; height: 2em;">
<div class="cbi-value" style="display: flex; justify-content: center; align-items: center; margin: 0.2em 0; height: 2em;">
<font color=#666><%:You choose node is:%></font><a style="color: red" id="set_node_name"></a>
<div style="position:absolute; right:0.5em; top: 0.5em;"><input class="btn cbi-button" type="button" onclick="set_node_div.close()" value="X" /></div>
</div>
<div class="cbi-value" style="justify-content: center; gap: 8px; margin: 1em 0;">
<%- if default_node_type == "_shunt" then
for i, v in ipairs(shunt_rule_list) do
-%>
<input class="btn cbi-button" type="button" onclick="set_node_div.set('<%=node%>', '<%=v[".name"]%>')" value="<%=v.remarks%>" />
<%-
end
-%>
<% else %>
<input class="btn cbi-button" type="button" onclick="set_node_div.set('@global[0]', 'node')" value="<%:Node%>" />
<div class="cbi-value" style="justify-content: center; gap: 8px; margin: 0.2em 0;">
<div style="margin: 0.5em 0; padding: 0.5em; background: #f7f7f7; border-radius: 4px;">
<div class="cbi-section-descr" style="text-align: left;"><a style="color:#FF8C00"><%:Set as the main proxy node:%></a></div>
<div>
<input class="btn cbi-button" type="button" onclick="set_node_div.set('@global[0]', 'node')" value="<%:OK%>" />
</div>
</div>
<% if default_node_type == "_shunt" then %>
<div id="set_node_shunt_div" style="margin: 0.5em 0; padding: 0.5em; background: #f7f7f7; border-radius: 4px;">
<div class="cbi-section-descr" style="text-align: left;"><a style="color:#FF8C00"><%:Set as the routing rule node:%></a></div>
<div>
<% for i, v in ipairs(shunt_rule_list) do %>
<input class="btn cbi-button" type="button" onclick="set_node_div.set('<%=node%>', '<%=v[".name"]%>')" value="<%=v.remarks%>" />
<% end %>
<input class="btn cbi-button" type="button" onclick="set_node_div.set('<%=node%>', 'default_node')" value="<%:Default%>" />
</div>
</div>
<% end %>
</div>
</div>
+6
View File
@@ -427,6 +427,12 @@ msgstr "你确定要删除选择的节点吗?"
msgid "You no select nodes !"
msgstr "你没有选择任何节点!"
msgid "Set as the main proxy node:"
msgstr "应用为主代理节点:"
msgid "Set as the routing rule node:"
msgstr "应用为分流规则节点:"
msgid "Are you sure set this node?"
msgstr "你确定要设置这个节点吗?"
-6
View File
@@ -14,7 +14,6 @@ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \
@@ -85,11 +84,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy
select PACKAGE_haproxy
default y if aarch64||arm||i386||x86_64
config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria
bool "Include Hysteria"
select PACKAGE_hysteria
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client
bool "Include Shadowsocks Rust Client"
depends on !i386
@@ -71,7 +71,6 @@ function index()
entry({"admin", "services", appname, "get_now_use_node"}, call("get_now_use_node")).leaf = true
entry({"admin", "services", appname, "get_redir_log"}, call("get_redir_log")).leaf = true
entry({"admin", "services", appname, "get_socks_log"}, call("get_socks_log")).leaf = true
entry({"admin", "services", appname, "get_acl_log"}, call("get_acl_log")).leaf = true
entry({"admin", "services", appname, "get_log"}, call("get_log")).leaf = true
entry({"admin", "services", appname, "clear_log"}, call("clear_log")).leaf = true
entry({"admin", "services", appname, "index_status"}, call("index_status")).leaf = true
@@ -248,10 +247,9 @@ end
function get_redir_log()
local id = http.formvalue("id")
local name = http.formvalue("name")
local file_path = api.TMP_PATH .. "/acl/" .. id .. "/" .. name .. ".log"
local file_path = api.TMP_PATH .. "/acl/" .. id .. ".log"
if nixio.fs.access(file_path) then
local content = luci.sys.exec("tail -n 19999 '" .. file_path .. "'")
local content = luci.sys.exec("tail -n 5000 '" .. file_path .. "'")
content = content:gsub("\n", "<br />")
http.write(content)
else
@@ -271,18 +269,6 @@ function get_socks_log()
end
end
function get_acl_log()
local id = http.formvalue("id")
local path = api.TMP_PATH .. "/acl/" .. id .. "/node.log"
if nixio.fs.access(path) then
local content = luci.sys.exec("tail -n 5000 '" .. path .. "'")
content = content:gsub("\n", "<br />")
http.write(content)
else
http.write(string.format("<script>alert('%s');window.close();</script>", i18n.translate("Not enabled log")))
end
end
function get_log()
-- luci.sys.exec("[ -f /tmp/log/passwall2.log ] && sed '1!G;h;$!d' /tmp/log/passwall2.log > /tmp/log/passwall2_show.log")
http.write(luci.sys.exec("[ -f '/tmp/log/passwall2.log' ] && cat /tmp/log/passwall2.log"))
@@ -294,7 +280,7 @@ end
function index_status()
local e = {}
e["global_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/bin/' | grep 'default' | grep 'global' >/dev/null" % api.TMP_PATH) == 0
e["global_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/bin/' | grep '/acl/default' >/dev/null" % api.TMP_PATH) == 0
http_write_json(e)
end
@@ -50,20 +50,11 @@ end
o = s:option(DummyValue, "sources", translate("Source"))
o.rawhtml = true
o.cfgvalue = function(t, n)
local e = ''
local v = Value.cfgvalue(t, n) or '-'
string.gsub(v, '[^' .. " " .. ']+', function(w)
local a = w
if mac_t[w] then
a = a .. ' (' .. mac_t[w].ip .. ')'
end
if #e > 0 then
e = e .. "<br />"
end
e = e .. a
end)
return e
o.cfgvalue = function(self, section)
local v = self.map:get(section, self.option) or {}
if type(v) == "table" then
return table.concat(v, "<br/>")
end
end
i = s:option(DummyValue, "mode", translate("Mode"))
@@ -71,6 +62,8 @@ i.cfgvalue = function(t, n)
local v = Value.cfgvalue(t, n) or '0'
if v == "1" then
return translate("Proxy")
elseif v == "2" then
return translate("Proxy") .. " " .. translate("Use global config")
end
return translate("No Proxy")
end
@@ -98,25 +98,9 @@ sources.description = "<ul><li>" .. translate("Example:")
.. "</li><li>" .. translate("IP range") .. ": 192.168.1.100-192.168.1.200"
.. "</li><li>" .. translate("IPSet") .. ": ipset:lanlist"
.. "</li></ul>"
sources.cast = "string"
for _, key in pairs(mac_t) do
sources:value(key.mac, "%s (%s)" % {key.mac, key.ip})
end
sources.cfgvalue = function(self, section)
local value
if self.tag_error[section] then
value = self:formvalue(section)
else
value = self.map:get(section, self.option)
if type(value) == "string" then
local value2 = {}
string.gsub(value, '[^' .. " " .. ']+', function(w) table.insert(value2, w) end)
value = value2
end
end
return value
end
sources.validate = function(self, value, t)
local err = {}
for _, v in ipairs(value) do
@@ -155,47 +139,75 @@ sources.validate = function(self, value, t)
return value
end
local NODE = m:get("@global[0]", "node")
o = s:option(ListValue, "mode", translate("Mode"))
o:value("0", translate("No Proxy"))
o:value("1", translate("Proxy"))
o:value("2", translate("Proxy") .. " " .. translate("Use global config") .. "(" .. api.get_node_name(NODE) .. ")")
---- TCP No Redir Ports
local TCP_NO_REDIR_PORTS = m:get("@global_forwarding[0]", "tcp_no_redir_ports")
o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports"))
o:value("", translate("Use global config") .. "(" .. TCP_NO_REDIR_PORTS .. ")")
o:value("disable", translate("No patterns are used"))
o:value("", translate("No patterns are used"))
o:value("1:65535", translate("All"))
o:depends("mode", "1")
o:depends("mode", "2")
o.validate = port_validate
---- UDP No Redir Ports
local UDP_NO_REDIR_PORTS = m:get("@global_forwarding[0]", "udp_no_redir_ports")
o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"))
o:value("", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")")
o:value("disable", translate("No patterns are used"))
o:value("", translate("No patterns are used"))
o:value("1:65535", translate("All"))
o:depends("mode", "1")
o:depends("mode", "2")
o.validate = port_validate
o = s:option(DummyValue, "_hide_node_option", "")
o = s:option(DummyValue, "_show_tcp_redir", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends({ tcp_no_redir_ports = "1:65535", ['!reverse'] = true })
o = s:option(DummyValue, "_show_udp_redir", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends({ udp_no_redir_ports = "1:65535", ['!reverse'] = true })
o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"))
o:value("1:65535", translate("All"))
o:value("22,25,53,80,143,443,465,587,853,873,993,995,5222,8080,8443,9418", translate("Common Use"))
o:value("80,443", "80,443")
o.default = o.keylist[1]
o.validate = port_validate
o:depends({ _node = "1", _show_tcp_redir = "1" })
o:depends({ mode = "2", _show_tcp_redir = "1" })
o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"))
o:value("1:65535", translate("All"))
o.default = o.keylist[1]
o.validate = port_validate
o:depends({ _node = "1", _show_udp_redir = "1" })
o:depends({ mode = "2", _show_udp_redir = "1" })
o = s:option(DummyValue, "tips", " ")
o.rawhtml = true
o.cfgvalue = function(t, n)
return string.format('<font color="red">%s</font>',
translate("The port settings support single ports and ranges.<br>Separate multiple ports with commas (,).<br>Example: 21,80,443,1000:2000."))
end
o:depends("mode", "1")
o:depends("mode", "2")
o = s:option(DummyValue, "_no_proxy", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends("mode", "0")
o:depends({ tcp_no_redir_ports = "1:65535", udp_no_redir_ports = "1:65535" })
if TCP_NO_REDIR_PORTS == "1:65535" and UDP_NO_REDIR_PORTS == "1:65535" then
o:depends({ tcp_no_redir_ports = "", udp_no_redir_ports = "" })
end
local GLOBAL_ENABLED = m:get("@global[0]", "enabled")
local NODE = m:get("@global[0]", "node")
o = s:option(DummyValue, "_show_node_option", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends({ mode = "1", _no_proxy = "" })
o = s:option(ListValue, "node", "<a style='color: red'>" .. translate("Node") .. "</a>")
if GLOBAL_ENABLED == "1" and NODE then
o:value("", translate("Use global config") .. "(" .. api.get_node_name(NODE) .. ")")
o.group = {""}
else
o.group = {}
end
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
o.group = {}
o:depends("_show_node_option", "1")
o.template = m:template_path("/cbi/nodes_listvalue")
current_node_id = o:formvalue(arg[1])
@@ -204,9 +216,14 @@ if not current_node_id then
end
current_node = current_node_id and m:get(current_node_id) or {}
o = s:option(Flag, "log", translate("Enable Node Log"))
o = s:option(DummyValue, "_node", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends({ node = "", ['!reverse'] = true })
o = s:option(Flag, "log", translate("Enable Node Log"))
o:depends("_node", "1")
o = s:option(ListValue, "loglevel", translate("Log Level"))
o.default = "warn"
o:value("debug", "Debug")
@@ -218,8 +235,8 @@ o:depends("log", "1")
o = s:option(DummyValue, "_acl_log", translate("Log File"))
o.rawhtml = true
o.cfgvalue = function(t, n)
local log_path = api.TMP_PATH .. "/acl/" .. arg[1] .. "/node.log"
local log_url = api.url("get_acl_log") .. "?id=" .. arg[1]
local log_path = api.TMP_PATH .. "/acl/" .. arg[1] .. ".log"
local log_url = api.url("get_redir_log") .. "?id=" .. arg[1]
return string.format(
'<code>%s</code>&nbsp;&nbsp;<input class="btn cbi-button cbi-button-apply" type="button" value="%s" onclick="window.open(\'%s\', \'_blank\')" />',
log_path,
@@ -229,46 +246,17 @@ o.cfgvalue = function(t, n)
end
o:depends("log", "1")
---- TCP Redir Ports
local TCP_REDIR_PORTS = m:get("@global_forwarding[0]", "tcp_redir_ports")
o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"))
o:value("", translate("Use global config") .. "(" .. TCP_REDIR_PORTS .. ")")
o:value("1:65535", translate("All"))
o:value("22,25,53,80,143,443,465,587,853,873,993,995,5222,8080,8443,9418", translate("Common Use"))
o:value("80,443", "80,443")
o.validate = port_validate
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
---- UDP Redir Ports
local UDP_REDIR_PORTS = m:get("@global_forwarding[0]", "udp_redir_ports")
o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"))
o:value("", translate("Use global config") .. "(" .. UDP_REDIR_PORTS .. ")")
o:value("1:65535", translate("All"))
o.validate = port_validate
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
o = s:option(DummyValue, "tips", " ")
o.rawhtml = true
o.cfgvalue = function(t, n)
return string.format('<font color="red">%s</font>',
translate("The port settings support single ports and ranges.<br>Separate multiple ports with commas (,).<br>Example: 21,80,443,1000:2000."))
end
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
o = s:option(DummyValue, "_hide_dns_option", "")
o = s:option(DummyValue, "_show_dns_option", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends({ node = "" })
if GLOBAL_ENABLED == "1" and NODE then
o:depends({ node = NODE })
end
o:depends("_hide", "1")
o = s:option(ListValue, "direct_dns_query_strategy", translate("Direct Query Strategy"))
o.default = "UseIP"
o:value("UseIP")
o:value("UseIPv4")
o:value("UseIPv6")
o:depends({ _hide_dns_option = "1", ['!reverse'] = true })
o:depends("_show_dns_option", "1")
o = s:option(ListValue, "remote_dns_protocol", translate("Remote DNS Protocol"))
o:value("tcp", "TCP")
@@ -279,7 +267,7 @@ if current_node.type == "sing-box" then
o:value("quic", "QUIC(DoQ)")
o:value("http3", "HTTP3(DoH3)")
end
o:depends({ _hide_dns_option = "1", ['!reverse'] = true })
o:depends("_show_dns_option", "1")
---- DNS over TCP or UDP or TLS (DoT) or QUIC (DoQ)
o = s:option(Value, "remote_dns", translate("Remote DNS"))
@@ -356,12 +344,13 @@ o:depends("remote_dns_protocol", "tls")
o = s:option(Value, "remote_rewrite_ttl", translate("Remote DNS") .. " TTL")
o.datatype = "min(1)"
o.default = "30"
o:depends("_hide", "1")
o = s:option(ListValue, "dns_hosts_mode", translate("Domain Override"))
o:value("default", translate("Use global config"))
o:value("disable", translate("No patterns are used"))
o:value("custom", translate("-- custom --"))
o:depends({ _hide_dns_option = "1", ['!reverse'] = true })
o:depends("_show_dns_option", "1")
o = s:option(TextValue, "dns_hosts", translate("Domain Override"))
o.rows = 5
@@ -385,6 +374,7 @@ for k, v in pairs(nodes_table) do
if v.type == "sing-box" then
s.fields["remote_rewrite_ttl"]:depends({ node = v.id })
end
s.fields["_show_dns_option"]:depends({ mode = "1", node = v.id })
if v.node_type == "normal" or v.protocol == "_balancing" or v.protocol == "_urltest" then
--Shunt node has its own separate options.
s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "tcp" })
@@ -282,8 +282,8 @@ loglevel:value("error")
o = s:taboption("log", DummyValue, "_log", translate("Log File"))
o.rawhtml = true
o.cfgvalue = function(t, n)
local log_path = api.TMP_PATH .. "/acl/default/global.log"
local log_url = api.url("get_redir_log") .. "?id=default&name=global"
local log_path = api.TMP_PATH .. "/acl/default.log"
local log_url = api.url("get_redir_log") .. "?id=default"
return string.format(
'<code>%s</code>&nbsp;&nbsp;<input class="btn cbi-button cbi-button-apply" type="button" value="%s" onclick="window.open(\'%s\', \'_blank\')" />',
log_path,
@@ -4,7 +4,6 @@ api.set_default_cbi()
local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria")
local ss_type = {}
local trojan_type = {}
local vmess_type = {}
@@ -33,10 +32,6 @@ if has_xray then
table.insert(hysteria2_type, s)
end
end
if has_hysteria2 then
local s = "hysteria2"
table.insert(hysteria2_type, s)
end
m = Map()
@@ -17,7 +17,6 @@ m:appendTemplate("/cbi/nodes_listvalue_com")
local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria")
local ss_type = {}
local trojan_type = {}
local vmess_type = {}
@@ -46,10 +45,6 @@ if has_xray then
table.insert(hysteria2_type, s)
end
end
if has_hysteria2 then
local s = "hysteria2"
table.insert(hysteria2_type, s)
end
local nodes_table = {}
for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" then
@@ -72,8 +72,7 @@ s = m:section(NamedSection, "@global_forwarding[0]", "global_forwarding", transl
---- TCP No Redir Ports
o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports"))
o.default = "disable"
o:value("disable", translate("No patterns are used"))
o:value("", translate("No patterns are used"))
o:value("1:65535", translate("All"))
o.validate = port_validate
@@ -82,23 +81,22 @@ o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
"<font color='red'>" ..
translate("Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
"</font>")
o.default = "disable"
o:value("disable", translate("No patterns are used"))
o:value("", translate("No patterns are used"))
o:value("1:65535", translate("All"))
o.validate = port_validate
---- TCP Redir Ports
o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"))
o.default = "22,25,53,80,143,443,465,587,853,873,993,995,5222,8080,8443,9418"
o:value("1:65535", translate("All"))
o:value("22,25,53,80,143,443,465,587,853,873,993,995,5222,8080,8443,9418", translate("Common Use"))
o:value("80,443", translate("Only Web"))
o.default = o.keylist[1]
o.validate = port_validate
---- UDP Redir Ports
o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"))
o.default = "1:65535"
o:value("1:65535", translate("All"))
o.default = o.keylist[1]
o.validate = port_validate
o = s:option(DummyValue, "tips", " ")
@@ -1,106 +0,0 @@
if not api.finded_com("hysteria") then
return
end
-- [[ Hysteria2 ]]
local m, s1 = ...
local type_name = "Hysteria2"
s1.fields["type"]:value(type_name, "Hysteria2")
if s1.val["type"] ~= type_name then
return
end
local s = NamedSection(m, arg[1], "server")
s.type_name = type_name
s.option_prefix = "hysteria2_"
o = s:option(Value, "address", translate("Address (Support Domain Name)"))
o:depends({ realms = false })
o = s:option(Value, "port", translate("Port"))
o.datatype = "port"
o:depends({ realms = false })
o = s:option(Value, "hop", translate("Port hopping range"))
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
o:depends({ realms = false })
o = s:option(Value, "hop_interval", translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
o.datatype = "or(uinteger,portrange)"
o.placeholder = "30"
o.default = "30"
o:depends({ realms = false })
o = s:option(Flag, "realms", translate("Realms"))
o.default = "0"
o = s:option(Value, "realm_url", translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name")
o:depends({ realms = "1" })
o.validate = function(self, value)
value = api.trim(value)
local realm = api.parse_realm_uri(value)
if realm then return value end
return nil, translate("Invalid Realm URL.")
end
o = s:option(DynamicList, "realm_stun", translate("Realm STUN"))
o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" }
o:depends({ realms = "1" })
o = s:option(Value, "auth_password", translate("Auth Password"))
o.password = true
o = s:option(ListValue, "obfs_type", translate("Obfs Type"))
o:value("", translate("Disable"))
o:value("salamander")
o:value("gecko")
o = s:option(Value, "obfs_password", translate("Obfs Password"))
o:depends({ obfs_type = "salamander" })
o:depends({ obfs_type = "gecko" })
o = s:option(Value, "obfs_MinPacketSize", translate("Gecko Packet Size (min)"))
o.datatype = "uinteger"
o.placeholder = "512"
o.default = "512"
o:depends({ obfs_type = "gecko" })
o = s:option(Value, "obfs_MaxPacketSize", translate("Gecko Packet Size (max)"))
o.datatype = "uinteger"
o.placeholder = "1200"
o.default = "1200"
o:depends({ obfs_type = "gecko" })
o = s:option(Flag, "fast_open", translate("Fast Open"))
o.default = "0"
o = s:option(Value, "tls_serverName", translate("Domain"))
o = s:option(Flag, "tls_allowInsecure", translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
o.default = "0"
o = s:option(Value, "tls_pinSHA256", translate("PinSHA256"),translate("Certificate fingerprint"))
o = s:option(Value, "up_mbps", translate("Max upload Mbps"))
o = s:option(Value, "down_mbps", translate("Max download Mbps"))
o = s:option(Value, "recv_window", translate("QUIC stream receive window"))
o = s:option(Value, "recv_window_conn", translate("QUIC connection receive window"))
o = s:option(Value, "idle_timeout", translate("Idle Timeout"), translate("Units:seconds") .. " (4~120)")
o.datatype = "range(4,120)"
o = s:option(Value, "keep_alive_period", translate("QUIC KeepAlive interval"), translate("Units:seconds") .. " (2~60)")
o.datatype = "range(2,60)"
o = s:option(Flag, "disable_mtu_discovery", translate("Disable MTU detection"))
o.default = "0"
o = s:option(Flag, "lazy_start", translate("Lazy Start"))
o.default = "0"
api.luci_types(s1, s)
@@ -1,143 +0,0 @@
if not api.finded_com("hysteria") then
return
end
-- [[ Hysteria2 ]]
local m, s1 = ...
local type_name = "Hysteria2"
s1.fields["type"]:value(type_name, "Hysteria2")
if not s1.val["type"] then
s1.val["type"] = type_name
end
if s1.val["type"] and s1.val["type"] ~= type_name then
return
end
local s = NamedSection(m, arg[1], "server")
s.type_name = type_name
s.option_prefix = "hysteria2_"
o = s:option(Flag, "custom", translate("Use Custom Config"))
o = s:option(TextValue, "custom_config", translate("Custom Config"))
o.rows = 10
o.wrap = "off"
o:depends({ custom = true })
o.datatype = "json"
local o_validate = o.validate
o.validate = function(self, value)
local v = o_validate(self, value)
if v then return v end
return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!")
end
o.custom_cfgvalue = function(self, section, value)
local config_str = m:get(section, "config_str")
if config_str then
return api.base64Decode(config_str)
end
end
o.custom_write = function(self, section, value)
m:set(section, "config_str", api.base64Encode(value) or "")
end
o = s:option(Value, "port", translate("Listen Port"))
o.datatype = "port"
o:depends({ custom = false })
o = s:option(DynamicList, "users", translate("User"))
for i, v in ipairs(user_list) do
o:value(v[".name"], v.username)
end
o:depends({ custom = false })
o = s:option(Flag, "realms", translate("Realms"))
o.default = "0"
o:depends({ custom = false })
o = s:option(Value, "realm_url", translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name")
o:depends({ realms = true })
o.validate = function(self, value)
value = api.trim(value)
local realm = api.parse_realm_uri(value)
if realm then return value end
return nil, translate("Invalid Realm URL.")
end
o = s:option(DynamicList, "realm_stun", translate("Realm STUN"))
o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" }
o:depends({ realms = true })
o = s:option(ListValue, "obfs_type", translate("Obfs Type"))
o:value("", translate("Disable"))
o:value("salamander")
o:value("gecko")
o:depends({ custom = false })
o = s:option(Value, "obfs_password", translate("Obfs Password"))
o:depends({ obfs_type = "salamander" })
o:depends({ obfs_type = "gecko" })
o = s:option(Value, "obfs_MinPacketSize", translate("Gecko Packet Size (min)"))
o.datatype = "uinteger"
o.placeholder = "512"
o.default = "512"
o:depends({ obfs_type = "gecko" })
o = s:option(Value, "obfs_MaxPacketSize", translate("Gecko Packet Size (max)"))
o.datatype = "uinteger"
o.placeholder = "1200"
o.default = "1200"
o:depends({ obfs_type = "gecko" })
o = s:option(Flag, "udp", translate("UDP"))
o.default = "1"
o:depends({ custom = false })
o = s:option(Value, "up_mbps", translate("Max upload Mbps"))
o:depends({ custom = false })
o = s:option(Value, "down_mbps", translate("Max download Mbps"))
o:depends({ custom = false })
o = s:option(Flag, "ignoreClientBandwidth", translate("ignoreClientBandwidth"))
o.default = "0"
o:depends({ custom = false })
o = s:option(FileUpload, "tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o.validate = function(self, value, t)
if value and value ~= "" then
if not api.fs.access(value) then
return nil, translate("Can't find this file!")
else
return value
end
end
return nil
end
o:depends({ custom = false })
o = s:option(FileUpload, "tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o.validate = function(self, value, t)
if value and value ~= "" then
if not api.fs.access(value) then
return nil, translate("Can't find this file!")
else
return value
end
end
return nil
end
o:depends({ custom = false })
o = s:option(Flag, "log", translate("Log"))
o.default = "1"
o.rmempty = false
api.luci_types(s1, s)
+6 -4
View File
@@ -26,6 +26,7 @@ TMP_PATH = "/tmp/etc/" .. c_config
CACHE_PATH = TMP_PATH .. "_tmp"
S_TMP_PATH = "/tmp/etc/" .. s_config
TMP_IFACE_PATH = TMP_PATH .. "/iface"
TMP_ACL_PATH = TMP_PATH .. "/acl"
local lang = uci:get("luci", "main", "lang") or "auto"
if lang == "auto" then
@@ -201,9 +202,10 @@ function get_cache_var(key)
return val
end
function get_new_port()
function get_new_port(p)
if not p then p = "auto" end
local cmd_format = ". /usr/share/passwall2/utils.sh ; echo -n $(get_new_port %s tcp,udp)"
return tonumber(sys.exec(string.format(cmd_format, "auto")))
return tonumber(sys.exec(string.format(cmd_format, p)))
end
function exec_call(cmd)
@@ -613,7 +615,7 @@ function get_valid_nodes()
end
end
local port = e.port or e.hysteria_hop or e.hysteria2_hop
local is_realm = (e.type == "Hysteria2" or e.protocol == 'hysteria2') and e.hysteria2_realms or nil
local is_realm = e.protocol == 'hysteria2' and e.hysteria2_realms or nil
if (port and e.address) or is_realm then
local address = e.address
if is_ip(address) or datatypes.hostname(address) or is_realm then
@@ -739,7 +741,7 @@ function get_node_remarks(n)
end
type_name = type_name .. " " .. protocol
end
if (n.type == "Hysteria2" or n.protocol == 'hysteria2') and n.hysteria2_realms then
if n.protocol == "hysteria2" and n.hysteria2_realms then
type_name = type_name .. " Realm"
end
remarks = trim("%s:[%s]" % {type_name, n.remarks})
@@ -10,21 +10,6 @@ local function gh_pre_release_url(self)
return "https://github.com/Openwrt-Passwall/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-pre-release-api.json"
end
_M.hysteria = {
name = "Hysteria",
repo = "HyNetwork/hysteria",
get_url = gh_release_url,
cmd_version = "version | awk '/^Version:/ {print $2}'",
remote_version_str_replace = "app/",
zipped = false,
default_path = "/usr/bin/hysteria",
match_fmt_str = "linux%%-%s$",
file_tree = {
armv6 = "arm",
armv7 = "arm"
}
}
_M["sing-box"] = {
name = "Sing-Box",
repo = "SagerNet/sing-box",
@@ -169,13 +169,6 @@ local function start()
config = require(require_dir .. "util_sing-box").gen_config_server(server)
end
bin = ln_run(api.get_app_path("sing-box"), "sing-box", "run -c " .. config_file, log_path)
elseif type == "Hysteria2" then
if server.custom == "1" and server.config_str then
config = jsonc.parse(api.base64Decode(server.config_str))
else
config = require(require_dir .. "util_hysteria2").gen_config_server(server)
end
bin = ln_run(api.get_app_path("hysteria"), "hysteria", "-c " .. config_file .. " server", log_path)
end
if next(config) then
@@ -1,197 +0,0 @@
module("luci.passwall2.util_hysteria2", package.seeall)
local api = require "luci.passwall2.api"
local jsonc = api.jsonc
function gen_config_server(node)
local users = nil
if node.users and #node.users > 0 then
users = {}
for i, v in ipairs(node.users) do
local user = api.uci_get_s(v) or {}
if user[".type"] == "user" then
users[user.username] = user.password
end
end
if not next(users) then
users = nil
end
end
local config = {
listen = (function()
if node.realms and node.realm_url then
local url = node.realm_url:gsub("/+$", "")
if node.port then
url = url .. (url:find("?") and "&lport=" or "?lport=") .. node.port
end
return url
end
return ":" .. (node.port or "0")
end)(),
tls = {
cert = node.tls_certificateFile,
key = node.tls_keyFile,
},
obfs = (node.obfs_type and node.obfs_password) and {
type = node.obfs_type,
[node.obfs_type] = {
password = node.obfs_password
}
} or nil,
auth = users and {
type = "userpass",
userpass = users
} or nil,
bandwidth = (node.up_mbps or node.down_mbps) and {
up = node.up_mbps and node.up_mbps .. " mbps" or nil,
down = node.down_mbps and node.down_mbps .. " mbps" or nil
} or nil,
ignoreClientBandwidth = (node.ignoreClientBandwidth == "1") and true or false,
disableUDP = (node.udp == "0") and true or false,
realm = (node.realms and node.realm_stun) and {
stunServers = node.realm_stun
} or nil
}
if config.obfs and config.obfs.gecko then
local min = tonumber(node.obfs_MinPacketSize) or 512
local max = tonumber(node.obfs_MaxPacketSize) or 1200
if min <= 0 or min > max or max > 2048 then
min = 512
max = 1200
end
config.obfs.gecko.minPacketSize = min
config.obfs.gecko.maxPacketSize = max
end
return config
end
function gen_config(var)
local node_id = var["node"]
if not node_id then
print("node Cannot be empty!")
return
end
local node = api.uci_get_c(node_id)
local local_socks_address = var["local_socks_address"] or "0.0.0.0"
local local_socks_port = var["local_socks_port"]
local local_socks_username = var["local_socks_username"]
local local_socks_password = var["local_socks_password"]
local local_http_address = var["local_http_address"] or "0.0.0.0"
local local_http_port = var["local_http_port"]
local local_http_username = var["local_http_username"]
local local_http_password = var["local_http_password"]
local server_host = var["server_host"] or (node.address or ""):lower()
local server_port = var["server_port"] or node.port
if api.is_ipv6(server_host) then
server_host = api.get_ipv6_full(server_host)
end
local port_hop = ((server_port or "") .. "," .. (node.hysteria2_hop or "")):gsub("^[%s,]+", ""):gsub("[%s,]+$", ""):gsub(":", "-")
local server = server_host .. ":" .. (port_hop ~= "" and port_hop or "443")
local config = {
server = (function()
if node.hysteria2_realms and node.hysteria2_realm_url then
return node.hysteria2_realm_url:gsub("/+$", "")
end
return server
end)(),
realm = (node.hysteria2_realms and node.hysteria2_realm_stun) and {
stunServers = node.hysteria2_realm_stun
} or nil,
transport = {
type = "udp",
udp = node.hysteria2_hop and (function()
local udp = {}
local t = node.hysteria2_hop_interval
if not t then return nil end
if t:find("-", 1, true) then
local min, max = t:match("^(%d+)%-(%d+)$")
min = tonumber(min)
max = tonumber(max)
if min and max then
min = (min >= 5) and min or 5
max = (max >= min) and max or min
udp.minHopInterval = min .. "s"
udp.maxHopInterval = max .. "s"
return udp
end
end
t = tonumber((t or "30"):match("^%d+"))
t = (t and t >= 5) and t or 30
udp.hopInterval = t .. "s"
return udp
end)() or nil
},
obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and {
type = node.hysteria2_obfs_type,
[node.hysteria2_obfs_type] = {
password = node.hysteria2_obfs_password
}
} or nil,
auth = node.hysteria2_auth_password,
tls = {
sni = node.tls_serverName,
insecure = (node.tls_allowInsecure == "1") and true or false,
pinSHA256 = (node.tls_pinSHA256) and node.tls_pinSHA256 or nil,
},
quic = {
initStreamReceiveWindow = (node.hysteria2_recv_window) and tonumber(node.hysteria2_recv_window) or nil,
initConnReceiveWindow = (node.hysteria2_recv_window_conn) and tonumber(node.hysteria2_recv_window_conn) or nil,
maxIdleTimeout = (function(t)
t = tonumber(tostring(t or "30"):match("^%d+"))
return (t and t >= 4 and t <= 120) and t .. "s" or "30s"
end)(node.hysteria2_idle_timeout),
keepAlivePeriod = (function(t)
t = tonumber(tostring(t or "0"):match("^%d+"))
return (t and t >= 2 and t <= 60) and t .. "s" or nil
end)(node.hysteria2_keep_alive_period),
disablePathMTUDiscovery = (node.hysteria2_disable_mtu_discovery) and true or false,
},
bandwidth = (node.hysteria2_up_mbps or node.hysteria2_down_mbps) and {
up = node.hysteria2_up_mbps and node.hysteria2_up_mbps .. " mbps" or nil,
down = node.hysteria2_down_mbps and node.hysteria2_down_mbps .. " mbps" or nil
} or nil,
fast_open = (node.fast_open == "1") and true or false,
lazy = (node.hysteria2_lazy_start == "1") and true or false,
socks5 = (local_socks_address and local_socks_port) and {
listen = local_socks_address .. ":" .. local_socks_port,
username = (local_socks_username and local_socks_password) and local_socks_username or nil,
password = (local_socks_username and local_socks_password) and local_socks_password or nil,
disableUDP = false,
} or nil,
http = (local_http_address and local_http_port) and {
listen = local_http_address .. ":" .. local_http_port,
username = (local_http_username and local_http_password) and local_http_username or nil,
password = (local_http_username and local_http_password) and local_http_password or nil,
} or nil
}
if config.obfs and config.obfs.gecko then
local min = tonumber(node.hysteria2_obfs_MinPacketSize) or 512
local max = tonumber(node.hysteria2_obfs_MaxPacketSize) or 1200
if min <= 0 or min > max or max > 2048 then
min = 512
max = 1200
end
config.obfs.gecko.minPacketSize = min
config.obfs.gecko.maxPacketSize = max
end
return jsonc.stringify(config, 1)
end
_G.gen_config = gen_config
if arg[1] then
local func =_G[arg[1]]
if func then
local var = nil
if arg[2] then
var = jsonc.parse(arg[2])
end
print(func(var))
end
end
@@ -133,7 +133,7 @@ local sid = "@global[0]"
const m = cbid.match(/\.node$/);
if (m) {
html += '<a href="#" onclick="window.open(\'' + '<%=api.url("get_redir_log")%>?id=default&name=' + 'global' + '\', \'_blank\')"><%:Log%></a>';
html += '<a href="#" onclick="window.open(\'' + '<%=api.url("get_redir_log")%>?id=default' + '\', \'_blank\')"><%:Log%></a>';
}
html = '<div class="node-actions" style="display:inline-flex; align-items:center; gap:4px; flex-wrap:wrap; margin-left:4px;">' + html + '</div>'
@@ -7,13 +7,12 @@ local map = self.map
local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria")
local ss_type = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}})
local trojan_type = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}})
local vmess_type = api.get_core("vmess_type", {{has_xray,"xray"},{has_singbox,"sing-box"}})
local vless_type = api.get_core("vless_type", {{has_xray,"xray"},{has_singbox,"sing-box"}})
local hysteria2_type = api.get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{has_singbox,"sing-box"}, {has_xray,"xray"}})
local hysteria2_type = api.get_core("hysteria2_type", {{has_singbox,"sing-box"}, {has_xray,"xray"}})
local current_node = map:get(section)
-%>
@@ -21,7 +20,6 @@ local current_node = map:get(section)
<script type="text/javascript">//<![CDATA[
let has_singbox = "<%=has_singbox%>"
let has_xray = "<%=has_xray%>"
let has_hysteria2 = "<%=has_hysteria2%>"
let ss_type = "<%=ss_type%>"
let trojan_type = "<%=trojan_type%>"
let vmess_type = "<%=vmess_type%>"
@@ -585,7 +583,7 @@ local current_node = map:get(section)
params = params.substring(1);
}
url += params;
} else if ((v_type === "Hysteria2") || ((v_type === "sing-box" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "hysteria2")) {
} else if (((v_type === "sing-box" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "hysteria2")) {
protocol = "hysteria2"
var v_port = opt.get(dom_prefix + "port");
var params = "";
@@ -595,36 +593,20 @@ local current_node = map:get(section)
params += opt.query("pcs", dom_prefix + "tls_pinSHA256");
params += opt.query("vcn", dom_prefix + "tls_CertByName");
var v_password = null;
if (v_type === "Hysteria2") {
v_password = opt.get("hysteria2_auth_password");
var dom_obfs_type = opt.get("hysteria2_obfs_type");
if (dom_obfs_type && dom_obfs_type.value != "") {
params += opt.query("obfs", "hysteria2_obfs_type");
params += opt.query("obfs-password", "hysteria2_obfs_password");
if (dom_obfs_type.value === "gecko") {
params += opt.query("minPacketSize", "hysteria2_obfs_MinPacketSize");
params += opt.query("maxPacketSize", "hysteria2_obfs_MaxPacketSize");
}
}
params += opt.query("mport", "hysteria2_hop");
} else {
v_password = opt.get(dom_prefix + "hysteria2_auth_password");
var dom_obfs_type = opt.get(dom_prefix + "hysteria2_obfs_type");
if (dom_obfs_type && dom_obfs_type.value != "") {
params += opt.query("obfs", dom_prefix + "hysteria2_obfs_type");
params += opt.query("obfs-password", dom_prefix + "hysteria2_obfs_password");
if (dom_obfs_type.value === "gecko") {
params += opt.query("minPacketSize", dom_prefix + "hysteria2_obfs_MinPacketSize");
params += opt.query("maxPacketSize", dom_prefix + "hysteria2_obfs_MaxPacketSize");
}
}
params += opt.query("mport", dom_prefix + "hysteria2_hop");
if (opt.get(dom_prefix + "use_finalmask")?.checked) {
params += opt.query("fm", dom_prefix + "finalmask");
var v_password = opt.get(dom_prefix + "hysteria2_auth_password");
var dom_obfs_type = opt.get(dom_prefix + "hysteria2_obfs_type");
if (dom_obfs_type && dom_obfs_type.value != "") {
params += opt.query("obfs", dom_prefix + "hysteria2_obfs_type");
params += opt.query("obfs-password", dom_prefix + "hysteria2_obfs_password");
if (dom_obfs_type.value === "gecko") {
params += opt.query("minPacketSize", dom_prefix + "hysteria2_obfs_MinPacketSize");
params += opt.query("maxPacketSize", dom_prefix + "hysteria2_obfs_MaxPacketSize");
}
}
params += opt.query("mport", dom_prefix + "hysteria2_hop");
if (opt.get(dom_prefix + "use_finalmask")?.checked) {
params += opt.query("fm", dom_prefix + "finalmask");
}
params = params.replace(/^&/, "");
url =
_address + ":" +
@@ -1640,19 +1622,6 @@ local current_node = map:get(section)
opt.set(dom_prefix + 'hysteria2_hop', queryParam.mport || "");
opt.set(dom_prefix + 'use_finalmask', !!queryParam.fm);
opt.set(dom_prefix + 'finalmask', queryParam.fm || "");
} else if (has_hysteria2) {
opt.set('type', "Hysteria2");
dom_prefix = "hysteria2_"
opt.set(dom_prefix + 'auth_password', decodeURIComponent(password));
if (queryParam["obfs-password"] || queryParam["obfs_password"]) {
opt.set(dom_prefix + 'obfs_type', queryParam.obfs || "salamander");
opt.set(dom_prefix + 'obfs_password', queryParam["obfs-password"] || queryParam["obfs_password"]);
}
if (queryParam.obfs === "gecko") {
opt.set(dom_prefix + 'obfs_MinPacketSize', queryParam.minPacketSize || "512");
opt.set(dom_prefix + 'obfs_MaxPacketSize', queryParam.maxPacketSize || "1200");
}
opt.set(dom_prefix + 'hop', queryParam.mport || "");
}
opt.set(dom_prefix + 'address', unbracketIP(m.hostname));
@@ -329,15 +329,19 @@ table td, .table .td {
var shunt_rule_list = result
var group_shunt_rules = {}
for (let i = 0; i < shunt_rule_list.length; i++) {
let _shunt_rule = shunt_rule_list[i]
if (!_shunt_rule.group || _shunt_rule.group === "") {
_shunt_rule.group = "default"
if (shunt_rule_list.length > 0) {
for (let i = 0; i < shunt_rule_list.length; i++) {
let _shunt_rule = shunt_rule_list[i]
if (!_shunt_rule.group || _shunt_rule.group === "") {
_shunt_rule.group = "default"
}
if (!group_shunt_rules[_shunt_rule.group]) {
group_shunt_rules[_shunt_rule.group] = []
}
group_shunt_rules[_shunt_rule.group].push(_shunt_rule)
}
if (!group_shunt_rules[_shunt_rule.group]) {
group_shunt_rules[_shunt_rule.group] = []
}
group_shunt_rules[_shunt_rule.group].push(_shunt_rule)
} else {
group_shunt_rules["default"] = [];
}
var tab_ul_li_html = '';
+2 -2
View File
@@ -2147,8 +2147,8 @@ msgstr "پروکسی نکردن همه %s"
msgid "Use the %s node [%s]"
msgstr "استفاده از گره %s [%s]"
msgid "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server."
msgstr "استفاده از گره‌ای متفاوت از پیکربندی سراسری، DNS به اجبار به سرور DNS اختصاصی هدایت شده است."
msgid "DNS will redirected to the dedicated DNS server [%s]."
msgstr "DNS به سرور DNS اختصاصی [%s] هدایت خواهد شد."
msgid "Add direct DNS to %s: %s"
msgstr "افزودن DNS مستقیم به %s: %s"
+2 -2
View File
@@ -2148,8 +2148,8 @@ msgstr "не прокси все %s"
msgid "Use the %s node [%s]"
msgstr "Использовать %s сервер [%s]"
msgid "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server."
msgstr "Используется сервер, отличный от глобальной настройки: DNS принудительно перенаправлен на выделенный DNS-сервер."
msgid "DNS will redirected to the dedicated DNS server [%s]."
msgstr "DNS будет перенаправлен на выделенный DNS-сервер [%s]."
msgid "Add direct DNS to %s: %s"
msgstr "Добавление прямого DNS в %s: %s"
+2 -2
View File
@@ -2133,8 +2133,8 @@ msgstr "不代理所有 %s"
msgid "Use the %s node [%s]"
msgstr "使用 %s 节点[%s]"
msgid "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server."
msgstr "使用与全局配置不相同节点,已将DNS强制重定向到专用 DNS 服务器。"
msgid "DNS will redirected to the dedicated DNS server [%s]."
msgstr "DNS 将重定向到专用 DNS 服务器 [%s]。"
msgid "Add direct DNS to %s: %s"
msgstr "追加直连 DNS 到 %s: %s"
+2 -2
View File
@@ -2139,8 +2139,8 @@ msgstr "不代理所有 %s"
msgid "Use the %s node [%s]"
msgstr "使用 %s 節點[%s]"
msgid "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server."
msgstr "使用与全局配置不相同節點,已將DNS強制重定向到專用 DNS 服務器。"
msgid "DNS will redirected to the dedicated DNS server [%s]."
msgstr "DNS 將重定向到專用 DNS 服務器 [%s]。"
msgid "Add direct DNS to %s: %s"
msgstr "追加直連 DNS 到 %s: %s"
@@ -30,45 +30,10 @@ else
fi
uci commit firewall
[ ! -s "/etc/config/passwall2" ] && cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2
chmod +x /usr/share/passwall2/*.sh
[ "$(uci -q get passwall2.@global_xray[0].sniffing)" == "1" ] && [ "$(uci -q get passwall2.@global_xray[0].route_only)" != "1" ] && uci -q set passwall2.@global_xray[0].sniffing_override_dest=1
uci -q delete passwall2.@global_xray[0].sniffing
uci -q delete passwall2.@global_xray[0].route_only
frag_len=$(uci -q get passwall2.@global_xray[0].fragment_length)
[ -n "$frag_len" ] && uci -q set passwall2.@global_xray[0].fragment_lengths="$frag_len" && uci -q delete passwall2.@global_xray[0].fragment_length
frag_dly=$(uci -q get passwall2.@global_xray[0].fragment_delay)
[ -n "$frag_dly" ] && uci -q set passwall2.@global_xray[0].fragment_delays="$frag_dly" && uci -q delete passwall2.@global_xray[0].fragment_delay
for sid in $(uci show passwall2 | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}'); do
if [ -z "$(echo ${sid} | grep '^socks_')" ]; then
new_id="socks_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 5)"
old_ref="Socks_${sid}"
uci -q rename passwall2.${sid}="${new_id}"
for item in $(uci show passwall2 | grep "='${old_ref}'\$" | cut -d '=' -sf 1); do
uci -q set ${item}="${new_id}"
done
unset sid new_id old_ref item
fi
done
for sid in $(uci show passwall2 | grep "@acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
new_id="acl_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 5)"
uci -q rename passwall2.${sid}="${new_id}"
unset sid new_id
done
for sid in $(uci show passwall2 | grep "@subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
new_id="sub_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 5)"
uci -q rename passwall2.${sid}="${new_id}"
unset sid new_id
done
uci -q commit passwall2
sed -i "s#add_from#group#g" /etc/config/passwall2 2>/dev/null
rm -f /tmp/luci-indexcache /tmp/luci-indexcache.*
rm -rf /tmp/luci-modulecache/
killall -HUP rpcd 2>/dev/null
@@ -25,8 +25,6 @@ config global_delay
option start_delay '60'
config global_forwarding
option tcp_no_redir_ports 'disable'
option udp_no_redir_ports 'disable'
option tcp_redir_ports '1:65535'
option udp_redir_ports '1:65535'
option accept_icmp '0'
@@ -45,13 +43,12 @@ config global_rules
option geosite_update '1'
option geoip_update '1'
option v2ray_location_asset '/usr/share/v2ray/'
option geoip_url 'https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat'
option geoip_url 'https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat'
option geosite_url 'https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat'
config global_app
option geoview_file '/usr/bin/geoview'
option xray_file '/usr/bin/xray'
option hysteria_file '/usr/bin/hysteria'
option sing_box_file '/usr/bin/sing-box'
config global_subscribe
+115 -375
View File
@@ -7,17 +7,15 @@
. /usr/share/libubox/jshn.sh
. /usr/share/passwall2/utils.sh
GLOBAL_ACL_PATH=${TMP_ACL_PATH}/default
LUA_UTIL_PATH=/usr/lib/lua/luci/passwall2
UTIL_SINGBOX=$LUA_UTIL_PATH/util_sing-box.lua
UTIL_SS=$LUA_UTIL_PATH/util_shadowsocks.lua
UTIL_XRAY=$LUA_UTIL_PATH/util_xray.lua
UTIL_HYSTERIA2=$LUA_UTIL_PATH/util_hysteria2.lua
SINGBOX_BIN=$(first_type $(config_t_get global_app sing_box_file) sing-box)
XRAY_BIN=$(first_type $(config_t_get global_app xray_file) xray)
SINGBOX_BIN=$(first_type $(config_n_get @global_app[0] sing_box_file) sing-box)
XRAY_BIN=$(first_type $(config_n_get @global_app[0] xray_file) xray)
check_run_environment() {
local prefer_nft=$(config_t_get global_forwarding prefer_nft 1)
local prefer_nft=$(config_n_get @global_forwarding[0] prefer_nft 1)
local dnsmasq_info=$(dnsmasq -v 2>/dev/null)
local dnsmasq_ver=$(echo "$dnsmasq_info" | sed -n '1s/.*version \([0-9.]*\).*/\1/p')
# local dnsmasq_opts=$(echo "$dnsmasq_info" | grep -i "Compile time options")
@@ -70,13 +68,13 @@ check_run_environment() {
}
run_xray() {
local flag node redir_port tcp_proxy_way socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local flag node redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache
local loglevel log_file config_file
eval_set_val $@
node_protocol=$(config_n_get $node protocol)
[ -n "$log_file" ] || local log_file="/dev/null"
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warning")
[ -z "$loglevel" ] && local loglevel=$(config_n_get @global[0] loglevel "warning")
json_init
json_add_string "loglevel" "${loglevel}"
@@ -106,9 +104,8 @@ run_xray() {
[ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}"
[ "${node_protocol}" = "_shunt" ] && local write_ipset_direct=$(config_n_get $node write_ipset_direct 0)
[ "${write_ipset_direct}" = "1" ] && {
direct_dnsmasq_listen_port=$(get_new_port $(expr $dns_listen_port + 1) udp)
local direct_ipset_conf=${GLOBAL_ACL_PATH}/dns_${flag}_direct.conf
[ -n "$(echo ${flag} | grep '^acl')" ] && direct_ipset_conf=${TMP_ACL_PATH}/${sid}/dns_${flag}_direct.conf
direct_dnsmasq_listen_port=$(get_new_port auto)
local direct_ipset_conf=${TMP_ACL_PATH}/dns_${flag}_direct.conf
if [ "${nftflag}" = "1" ]; then
local direct_nftset4="psw2_${node}_white"
local direct_nftset6="psw2_${node}_white6"
@@ -178,7 +175,7 @@ run_xray() {
[ -n "${redir_port}" ] && {
json_add_string "redir_port" "${redir_port}"
set_cache_var "node_${node}_redir_port" "${redir_port}"
[ -n "${tcp_proxy_way}" ] && json_add_string "tcp_proxy_way" "${tcp_proxy_way}"
json_add_string "tcp_proxy_way" "${TCP_PROXY_WAY}"
}
json_add_string "node" "${node}"
@@ -199,7 +196,7 @@ run_xray() {
}
run_singbox() {
local flag node redir_port tcp_proxy_way socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local flag node redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy remote_rewrite_ttl dns_cache
local loglevel log_file config_file
eval_set_val $@
@@ -207,7 +204,7 @@ run_singbox() {
[ -z "$type" ] && return 1
node_protocol=$(config_n_get $node protocol)
[ -n "$log_file" ] || local log_file="/dev/null"
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warn")
[ -z "$loglevel" ] && local loglevel=$(config_n_get @global[0] loglevel "warn")
local singbox_tag=$($SINGBOX_BIN version | grep 'Tags:' | awk '{print $2}')
json_init
@@ -244,9 +241,8 @@ run_singbox() {
[ -n "$dns_listen_port" ] && {
[ "${node_protocol}" = "_shunt" ] && local write_ipset_direct=$(config_n_get $node write_ipset_direct 0)
[ "${write_ipset_direct}" = "1" ] && {
direct_dnsmasq_listen_port=$(get_new_port $(expr $dns_listen_port + 1) udp)
local direct_ipset_conf=${GLOBAL_ACL_PATH}/dns_${flag}_direct.conf
[ -n "$(echo ${flag} | grep '^acl')" ] && direct_ipset_conf=${TMP_ACL_PATH}/${sid}/dns_${flag}_direct.conf
direct_dnsmasq_listen_port=$(get_new_port auto)
local direct_ipset_conf=${TMP_ACL_PATH}/dns_${flag}_direct.conf
if [ "${nftflag}" = "1" ]; then
local direct_nftset4="psw2_${node}_white"
local direct_nftset6="psw2_${node}_white6"
@@ -325,7 +321,7 @@ run_singbox() {
[ -n "${redir_port}" ] && {
json_add_string "redir_port" "${redir_port}"
set_cache_var "node_${node}_redir_port" "${redir_port}"
[ -n "${tcp_proxy_way}" ] && json_add_string "tcp_proxy_way" "${tcp_proxy_way}"
json_add_string "tcp_proxy_way" "${TCP_PROXY_WAY}"
}
json_add_string "node" "${node}"
@@ -411,7 +407,7 @@ run_socks() {
json_add_null "server_port"
}
[ "${log_file}" != "/dev/null" ] && {
local loglevel=$(config_t_get global loglevel "warn")
local loglevel=$(config_n_get @global[0] loglevel "warn")
json_add_string "log" "1"
json_add_string "loglevel" "${loglevel}"
json_add_string "logfile" "${log_file}"
@@ -439,7 +435,7 @@ run_socks() {
json_add_null "server_port"
}
[ "${log_file}" != "/dev/null" ] && {
local loglevel=$(config_t_get global loglevel "warn")
local loglevel=$(config_n_get @global[0] loglevel "warn")
json_add_string "log" "1"
json_add_string "loglevel" "${loglevel}"
}
@@ -478,19 +474,6 @@ run_socks() {
lua $UTIL_SS gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
;;
hysteria2)
json_add_string "local_socks_address" "${bind}"
json_add_string "local_socks_port" "${socks_port}"
[ "$http_port" != "0" ] && {
http_flag=1
config_file="${config_file%%.*}+http${config_file#${config_file%%.*}}"
json_add_string "local_http_address" "${bind}"
json_add_string "local_http_port" "${http_port}"
}
local _json_arg="$(json_dump)"
lua $UTIL_HYSTERIA2 gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client
;;
esac
# http to socks
@@ -561,146 +544,6 @@ socks_node_switch() {
}
}
run_global() {
[ -z "$NODE" ] && return 1
TYPE=$(echo $(config_n_get $NODE type) | tr 'A-Z' 'a-z')
[ -z "$TYPE" ] && return 1
if [ $PROXY_IPV6 == "1" ]; then
log_i18n 0 "To enable experimental IPv6 transparent proxy (TProxy), please ensure your node and type support IPv6!"
fi
TUN_DNS_PORT=15353
TUN_DNS="127.0.0.1#${TUN_DNS_PORT}"
V2RAY_ARGS="flag=global node=$NODE redir_port=$REDIR_PORT tcp_proxy_way=${TCP_PROXY_WAY}"
V2RAY_ARGS="${V2RAY_ARGS} dns_listen_port=${TUN_DNS_PORT} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY} dns_cache=${DNS_CACHE}"
local dns_msg="DNS: ${TUN_DNS} ($(i18n "Direct DNS: %s" "${AUTO_DNS}")"
[ -n "$REMOTE_DNS_PROTOCOL" ] && {
V2RAY_ARGS="${V2RAY_ARGS} remote_dns_protocol=${REMOTE_DNS_PROTOCOL} remote_dns_detour=${REMOTE_DNS_DETOUR}"
case "$REMOTE_DNS_PROTOCOL" in
udp|\
quic)
V2RAY_ARGS="${V2RAY_ARGS} remote_dns_udp_server=${REMOTE_DNS}"
dns_msg="${dns_msg} $(i18n "Remote DNS: %s" "${REMOTE_DNS}")"
;;
tcp|\
tls)
V2RAY_ARGS="${V2RAY_ARGS} remote_dns_tcp_server=${REMOTE_DNS}"
dns_msg="${dns_msg} $(i18n "Remote DNS: %s" "${REMOTE_DNS}")"
;;
doh|\
http3)
REMOTE_DNS_DOH=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
V2RAY_ARGS="${V2RAY_ARGS} remote_dns_doh=${REMOTE_DNS_DOH}"
dns_msg="${dns_msg} $(i18n "Remote DNS: %s" "${REMOTE_DNS_DOH}")"
;;
esac
[ "$REMOTE_FAKEDNS" = "1" ] && {
V2RAY_ARGS="${V2RAY_ARGS} remote_fakedns=1"
dns_msg="${dns_msg} + FakeDNS "
}
local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip)
[ -n "${_remote_dns_client_ip}" ] && V2RAY_ARGS="${V2RAY_ARGS} remote_dns_client_ip=${_remote_dns_client_ip}"
V2RAY_ARGS="${V2RAY_ARGS} remote_rewrite_ttl=$(config_t_get global remote_rewrite_ttl)"
}
dns_msg="${dns_msg})"
V2RAY_CONFIG=${GLOBAL_ACL_PATH}/global.json
V2RAY_LOG=${GLOBAL_ACL_PATH}/global.log
[ "$(config_t_get global log_node 1)" != "1" ] && V2RAY_LOG="/dev/null"
V2RAY_ARGS="${V2RAY_ARGS} log_file=${V2RAY_LOG} config_file=${V2RAY_CONFIG}"
node_socks_port=$(config_t_get global node_socks_port 1070)
node_socks_bind_local=$(config_t_get global node_socks_bind_local 1)
node_socks_bind="127.0.0.1"
[ "${node_socks_bind_local}" != "1" ] && node_socks_bind="0.0.0.0"
V2RAY_ARGS="${V2RAY_ARGS} socks_address=${node_socks_bind} socks_port=${node_socks_port}"
set_cache_var "GLOBAL_SOCKS_server" "127.0.0.1:$node_socks_port"
node_http_port=$(config_t_get global node_http_port 0)
[ "$node_http_port" != "0" ] && V2RAY_ARGS="${V2RAY_ARGS} http_port=${node_http_port}"
local run_func
[ -n "${XRAY_BIN}" ] && run_func="run_xray"
[ -n "${SINGBOX_BIN}" ] && run_func="run_singbox"
if [ "${TYPE}" = "xray" ] && [ -n "${XRAY_BIN}" ]; then
run_func="run_xray"
elif [ "${TYPE}" = "sing-box" ] && [ -n "${SINGBOX_BIN}" ]; then
run_func="run_singbox"
fi
${run_func} ${V2RAY_ARGS}; local status=$?
if [ "$status" == 0 ]; then
log 0 ${dns_msg}
else
log_i18n 0 "[%s] process %s error, skip this transparent proxy!" $(i18n "Global") "${V2RAY_CONFIG}"
cat ${_error_log_file} >> ${LOG_FILE}
unset _error_log_file
ENABLED_DEFAULT_ACL=0
return 1
fi
set_cache_var "ACL_GLOBAL_node" "$NODE"
set_cache_var "ACL_GLOBAL_redir_port" "$REDIR_PORT"
}
run_global_dnsmasq() {
[ -z "${ACL_GLOBAL_node}" ] && return
local RUN_NEW_DNSMASQ=1
RUN_NEW_DNSMASQ=${DNS_REDIRECT}
DNSMASQ_DEFAULT_DNS="${AUTO_DNS}"
DNSMASQ_LOCAL_DNS="${LOCAL_DNS:-${AUTO_DNS}}"
DNSMASQ_TUN_DNS="${TUN_DNS}"
if [ "${RUN_NEW_DNSMASQ}" == "0" ]; then
#The old logic will be removed in the future.
#Run a copy dnsmasq instance, DNS hijack that don't need a proxy devices.
[ "1" = "0" ] && {
DIRECT_DNSMASQ_PORT=$(get_new_port 11400)
DIRECT_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/direct_dnsmasq.conf
DIRECT_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/direct_dnsmasq.d
mkdir -p ${DIRECT_DNSMASQ_CONF_PATH}
json_init
json_add_string "LISTEN_PORT" "${DIRECT_DNSMASQ_PORT}"
json_add_string "DNSMASQ_CONF" "${DIRECT_DNSMASQ_CONF}"
json_add_string "TMP_DNSMASQ_PATH" "${DIRECT_DNSMASQ_CONF_PATH}"
lua $APP_PATH/helper_dnsmasq.lua copy_instance "$(json_dump)"
ln_run 0 "$(first_type dnsmasq)" "dnsmasq_direct" "/dev/null" -C ${DIRECT_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/direct_dnsmasq.pid
set_cache_var "DIRECT_DNSMASQ_PORT" "${DIRECT_DNSMASQ_PORT}"
}
#Rewrite the default DNS service configuration
#Modify the default dnsmasq service
lua $APP_PATH/helper_dnsmasq.lua stretch
json_init
json_add_string "FLAG" "default"
json_add_string "TMP_DNSMASQ_PATH" "${GLOBAL_DNSMASQ_CONF_PATH}"
json_add_string "DNSMASQ_CONF_FILE" "${GLOBAL_DNSMASQ_CONF}"
json_add_string "DEFAULT_DNS" "${DNSMASQ_DEFAULT_DNS}"
json_add_string "LOCAL_DNS" "${DNSMASQ_LOCAL_DNS}"
json_add_string "TUN_DNS" "${DNSMASQ_TUN_DNS}"
json_add_string "NFTFLAG" "${nftflag:-0}"
json_add_string "NO_LOGIC_LOG" "${NO_LOGIC_LOG:-0}"
lua $APP_PATH/helper_dnsmasq.lua add_rule "$(json_dump)"
uci -q add_list dhcp.@dnsmasq[0].addnmount=${GLOBAL_DNSMASQ_CONF_PATH}
uci -q commit dhcp
json_init
json_add_string "LOG" "1"
lua $APP_PATH/helper_dnsmasq.lua logic_restart "$(json_dump)"
else
#Run a copy dnsmasq instance, DNS hijack for that need proxy devices.
GLOBAL_DNSMASQ_PORT=$(get_new_port 11400)
run_copy_dnsmasq flag="default" listen_port=$GLOBAL_DNSMASQ_PORT local_dns="${DNSMASQ_LOCAL_DNS}" tun_dns="${DNSMASQ_TUN_DNS}" default_dns="${DNSMASQ_DEFAULT_DNS}"
DNS_REDIRECT_PORT=${GLOBAL_DNSMASQ_PORT}
#dhcp.leases to hosts
$APP_PATH/lease2hosts.sh > /dev/null 2>&1 &
fi
}
start_socks() {
[ "$SOCKS_ENABLED" = "1" ] && {
local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
@@ -746,7 +589,7 @@ clean_crontab() {
start_crontab() {
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
start_daemon=$(config_t_get global_delay start_daemon 0)
start_daemon=$(config_n_get @global_delay[0] start_daemon 0)
[ "$start_daemon" = "1" ] && { $APP_PATH/monitor.sh > /dev/null 2>&1 & }
fi
@@ -763,8 +606,8 @@ start_crontab() {
return
}
stop_week_mode=$(config_t_get global_delay stop_week_mode)
stop_time_mode=$(config_t_get global_delay stop_time_mode)
stop_week_mode=$(config_n_get @global_delay[0] stop_week_mode)
stop_time_mode=$(config_n_get @global_delay[0] stop_time_mode)
if [ -n "$stop_week_mode" ]; then
stop_time_hh=$(echo $stop_time_mode | awk -F ':' '{print $1}')
stop_time_mm=$(echo $stop_time_mode | awk -F ':' '{print $2}')
@@ -774,8 +617,8 @@ start_crontab() {
log_i18n 0 "Scheduled tasks: Auto stop service."
fi
start_week_mode=$(config_t_get global_delay start_week_mode)
start_time_mode=$(config_t_get global_delay start_time_mode)
start_week_mode=$(config_n_get @global_delay[0] start_week_mode)
start_time_mode=$(config_n_get @global_delay[0] start_time_mode)
if [ -n "$start_week_mode" ]; then
start_time_hh=$(echo $start_time_mode | awk -F ':' '{print $1}')
start_time_mm=$(echo $start_time_mode | awk -F ':' '{print $2}')
@@ -785,8 +628,8 @@ start_crontab() {
log_i18n 0 "Scheduled tasks: Auto start service."
fi
restart_week_mode=$(config_t_get global_delay restart_week_mode)
restart_time_mode=$(config_t_get global_delay restart_time_mode)
restart_week_mode=$(config_n_get @global_delay[0] restart_week_mode)
restart_time_mode=$(config_n_get @global_delay[0] restart_time_mode)
if [ -n "$restart_week_mode" ]; then
restart_time_hh=$(echo $restart_time_mode | awk -F ':' '{print $1}')
restart_time_mm=$(echo $restart_time_mode | awk -F ':' '{print $2}')
@@ -800,8 +643,8 @@ start_crontab() {
log_i18n 0 "Scheduled tasks: Auto restart service."
fi
rules_update_week_mode=$(config_t_get global_rules update_week_mode)
rules_update_time_mode=$(config_t_get global_rules update_time_mode)
rules_update_week_mode=$(config_n_get @global_rules[0] update_week_mode)
rules_update_time_mode=$(config_n_get @global_rules[0] update_time_mode)
if [ -n "$rules_update_week_mode" ]; then
rules_update_time_hh=$(echo $rules_update_time_mode | awk -F ':' '{print $1}')
rules_update_time_mm=$(echo $rules_update_time_mode | awk -F ':' '{print $2}')
@@ -865,7 +708,7 @@ stop_crontab() {
}
start_haproxy() {
[ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && return
[ "$(config_n_get @global_haproxy[0] balancing_enable 0)" != "1" ] && return
haproxy_path=$TMP_PATH/haproxy
haproxy_conf="config.cfg"
lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf}
@@ -875,8 +718,9 @@ start_haproxy() {
run_copy_dnsmasq() {
local flag listen_port local_dns tun_dns default_dns
eval_set_val $@
local dnsmasq_conf=$TMP_ACL_PATH/$flag/dnsmasq.conf
local dnsmasq_conf_path=$TMP_ACL_PATH/$flag/dnsmasq.d
local dnsmasq_conf="${TMP_ACL_PATH}/${flag}_dnsmasq.conf"
local dnsmasq_conf_path="${TMP_ACL_PATH}/${flag}_dnsmasq.d"
local dnsmasq_pid="${TMP_ACL_PATH}/${flag}_dnsmasq.pid"
mkdir -p $dnsmasq_conf_path
json_init
@@ -895,7 +739,7 @@ run_copy_dnsmasq() {
json_add_string "NO_LOGIC_LOG" "${NO_LOGIC_LOG:-0}"
lua $APP_PATH/helper_dnsmasq.lua add_rule "$(json_dump)"
ln_run 0 "$(first_type dnsmasq)" "dnsmasq_${flag}" "/dev/null" -C $dnsmasq_conf -x $TMP_ACL_PATH/$flag/dnsmasq.pid
ln_run 0 "$(first_type dnsmasq)" "dnsmasq_${flag}" "/dev/null" -C ${dnsmasq_conf} -x ${dnsmasq_pid}
set_cache_var "ACL_${flag}_dns_port" "${listen_port}"
}
@@ -958,156 +802,75 @@ run_ipset_dnsmasq() {
ln_run 0 "$(first_type dnsmasq)" "dnsmasq" "/dev/null" -C $config_file
}
acl_app() {
local items=$(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1)
if [ -z "$items" ]; then
ENABLED_ACLS=0
return
else
local has_enabled
local index=0
local sid
local redir_port dns_port dnsmasq_port socks_port
local ipt_tmp msg msg2
redir_port=11200
socks_port=11600
dns_port=11300
dnsmasq_port=${GLOBAL_DNSMASQ_PORT:-11400}
for sid in $items; do
index=$(expr $index + 1)
local enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy remote_rewrite_ttl log loglevel log_file
local _ip _mac _iprange _ipset _ip_or_mac source_list config_file
[ "$(config_n_get $sid enabled)" = "1" ] || continue
has_enabled=1
eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-)
acl_node() {
local run_func
[ -n "${XRAY_BIN}" ] && run_func="run_xray"
[ -n "${SINGBOX_BIN}" ] && run_func="run_singbox"
local acl_node_num=0
for nid in $(jsonfilter -s "${acl_json}" -e '$.node_order[*]'); do
[ ! -f ${TMP_ACL_PATH}/acl_node_${nid} ] && continue
acl_node_num=$(expr $acl_node_num + 1)
local _var=$(cat ${TMP_ACL_PATH}/acl_node_${nid} 2>/dev/null)
eval local ${_var}
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
[ -n "${type}" ] || continue
if [ "${type}" = "xray" ] && [ -n "${XRAY_BIN}" ]; then
run_func="run_xray"
elif [ "${type}" = "sing-box" ] && [ -n "${SINGBOX_BIN}" ]; then
run_func="run_singbox"
fi
${run_func} ${_var}
local status=$?
if [ "$status" != 0 ]; then
log_i18n 2 "[%s] process %s error, skip this transparent proxy!" "${node}" "${config_file}"
cat ${_error_log_file} >> ${LOG_FILE}
unset _error_log_file
continue
fi
if [ "${flag}" = "default" ]; then
set_cache_var "GLOBAL_SOCKS_server" "127.0.0.1:$socks_port"
set_cache_var "ACL_GLOBAL_node" "$node"
local RUN_NEW_DNSMASQ=$(config_n_get @global[0] dns_redirect 1)
local DNSMASQ_DEFAULT_DNS="${AUTO_DNS}"
local DNSMASQ_LOCAL_DNS="${LOCAL_DNS:-${AUTO_DNS}}"
local DNSMASQ_TUN_DNS="127.0.0.1#${dns_listen_port}"
if [ "${RUN_NEW_DNSMASQ}" == "0" ]; then
#Rewrite the default DNS service configuration
#Modify the default dnsmasq service
lua $APP_PATH/helper_dnsmasq.lua stretch
json_init
json_add_string "FLAG" "default"
json_add_string "TMP_DNSMASQ_PATH" "${GLOBAL_DNSMASQ_CONF_PATH}"
json_add_string "DNSMASQ_CONF_FILE" "${GLOBAL_DNSMASQ_CONF}"
json_add_string "DEFAULT_DNS" "${DNSMASQ_DEFAULT_DNS}"
json_add_string "LOCAL_DNS" "${DNSMASQ_LOCAL_DNS}"
json_add_string "TUN_DNS" "${DNSMASQ_TUN_DNS}"
json_add_string "NFTFLAG" "${nftflag:-0}"
json_add_string "NO_LOGIC_LOG" "${NO_LOGIC_LOG:-0}"
lua $APP_PATH/helper_dnsmasq.lua add_rule "$(json_dump)"
uci -q add_list dhcp.@dnsmasq[0].addnmount=${GLOBAL_DNSMASQ_CONF_PATH}
uci -q commit dhcp
if [ -n "${sources}" ]; then
for s in $sources; do
local s2
is_iprange=$(lua_api "iprange(\"${s}\")")
if [ "${is_iprange}" = "true" ]; then
s2="iprange:${s}"
elif [ -n "$(echo ${s} | grep '^ipset:')" ]; then
s2="ipset:${s}"
else
_ip_or_mac=$(lua_api "ip_or_mac(\"${s}\")")
if [ "${_ip_or_mac}" = "ip" ]; then
s2="ip:${s}"
elif [ "${_ip_or_mac}" = "mac" ]; then
s2="mac:${s}"
fi
fi
[ -n "${s2}" ] && source_list="${source_list}\n${s2}"
unset s2
done
json_init
json_add_string "LOG" "1"
lua $APP_PATH/helper_dnsmasq.lua logic_restart "$(json_dump)"
else
source_list="any"
#Run a copy dnsmasq instance, DNS hijack for that need proxy devices.
dnsmasq_port=$(get_new_port auto)
run_copy_dnsmasq flag="default" listen_port=${dnsmasq_port} local_dns="${DNSMASQ_LOCAL_DNS}" tun_dns="${DNSMASQ_TUN_DNS}" default_dns="${DNSMASQ_DEFAULT_DNS}"
#dhcp.leases to hosts
$APP_PATH/lease2hosts.sh > /dev/null 2>&1 &
fi
local acl_path=${TMP_ACL_PATH}/$sid
mkdir -p ${acl_path}
[ -n "${source_list}" ] && echo -e "${source_list}" | sed '/^$/d' > ${acl_path}/source_list
log=${log:-0}
loglevel=${loglevel:-warn}
log_file="/dev/null"
[ "${log}" = "1" ] && log_file="${acl_path}/node.log"
node=${node:-default}
tcp_no_redir_ports=${tcp_no_redir_ports:-default}
udp_no_redir_ports=${udp_no_redir_ports:-default}
[ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS
[ "$udp_no_redir_ports" = "default" ] && udp_no_redir_ports=$UDP_NO_REDIR_PORTS
if has_1_65535 "$tcp_no_redir_ports" && has_1_65535 "$udp_no_redir_ports"; then
unset node
fi
[ -n "$node" ] && {
tcp_proxy_mode="global"
udp_proxy_mode="global"
direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP}
remote_dns_protocol=${remote_dns_protocol:-tcp}
remote_dns=${remote_dns:-1.1.1.1}
case "$remote_dns_protocol" in
doh|\
http3)
remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
;;
esac
remote_dns_detour=${remote_dns_detour:-remote}
remote_fakedns=${remote_fakedns:-0}
remote_dns_query_strategy=${remote_dns_query_strategy:-UseIPv4}
local GLOBAL_node=$(get_cache_var "ACL_GLOBAL_node")
[ -n "${GLOBAL_node}" ] && GLOBAL_redir_port=$(get_cache_var "ACL_GLOBAL_redir_port")
if [ "$node" = "default" ]; then
if [ -n "${GLOBAL_node}" ]; then
set_cache_var "ACL_${sid}_node" "${GLOBAL_node}"
set_cache_var "ACL_${sid}_redir_port" "${GLOBAL_redir_port}"
set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}"
set_cache_var "ACL_${sid}_default" "1"
else
log 1 "$(i18n "Global nodes are not enabled, skip [%s]." "${remarks}")"
fi
else
[ "$(config_get_type $node)" = "nodes" ] && {
if [ -n "${GLOBAL_node}" ] && [ "$node" = "${GLOBAL_node}" ]; then
set_cache_var "ACL_${sid}_node" "${GLOBAL_node}"
set_cache_var "ACL_${sid}_redir_port" "${GLOBAL_redir_port}"
set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}"
set_cache_var "ACL_${sid}_default" "1"
else
redir_port=$(get_new_port $(expr $redir_port + 1))
socks_port=$(get_new_port $(expr $socks_port + 1))
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
if [ -n "${type}" ]; then
config_file=$TMP_ACL_PATH/${node}_TCP_UDP_DNS_${redir_port}.json
dns_port=$(get_new_port $(expr $dns_port + 1))
local acl_socks_port=$socks_port
local run_func
[ -n "${XRAY_BIN}" ] && run_func="run_xray"
[ -n "${SINGBOX_BIN}" ] && run_func="run_singbox"
if [ "${type}" = "xray" ] && [ -n "${XRAY_BIN}" ]; then
run_func="run_xray"
elif [ "${type}" = "sing-box" ] && [ -n "${SINGBOX_BIN}" ]; then
run_func="run_singbox"
fi
${run_func} flag=acl_$sid node=$node redir_port=$redir_port tcp_proxy_way=${TCP_PROXY_WAY} \
socks_address=127.0.0.1 socks_port=$acl_socks_port \
dns_listen_port=${dns_port} \
direct_dns_query_strategy=${direct_dns_query_strategy} \
remote_dns_protocol=${remote_dns_protocol} remote_dns_tcp_server=${remote_dns} remote_dns_udp_server=${remote_dns} remote_dns_doh="${remote_dns}" \
remote_dns_client_ip=${remote_dns_client_ip} remote_dns_detour=${remote_dns_detour} remote_dns_query_strategy=${remote_dns_query_strategy} \
remote_fakedns=${remote_fakedns} remote_rewrite_ttl=${remote_rewrite_ttl} \
config_file=${config_file} \
log_file="${log_file}" loglevel="${loglevel}"
local status=$?
if [ "$status" != 0 ]; then
log_i18n 2 "[%s] process %s error, skip this transparent proxy!" "${remarks}" "${config_file}"
cat ${_error_log_file} >> ${LOG_FILE}
unset _error_log_file
continue
fi
fi
dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1))
run_copy_dnsmasq flag="$sid" listen_port=$dnsmasq_port local_dns="${LOCAL_DNS:-${AUTO_DNS}}" tun_dns="127.0.0.1#${dns_port}" default_dns="${AUTO_DNS}"
#dhcp.leases to hostsMore actions
$APP_PATH/lease2hosts.sh > /dev/null 2>&1 &
set_cache_var "ACL_${sid}_node" "$node"
set_cache_var "ACL_${sid}_redir_port" "$redir_port"
fi
}
fi
}
unset enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy remote_rewrite_ttl
unset _ip _mac _iprange _ipset _ip_or_mac source_list config_file
done
unset redir_port dns_port dnsmasq_port
[ -n "${has_enabled}" ] || ENABLED_ACLS=0
fi
else
dnsmasq_port=$(get_new_port auto)
run_copy_dnsmasq flag="${flag}" listen_port=${dnsmasq_port} local_dns="${LOCAL_DNS:-${AUTO_DNS}}" tun_dns="127.0.0.1#${dns_listen_port}" default_dns="${AUTO_DNS}"
#dhcp.leases to hostsMore actions
$APP_PATH/lease2hosts.sh > /dev/null 2>&1 &
fi
rm -f ${TMP_ACL_PATH}/acl_node_${nid}
done
[ ! -f ${TMP_ACL_PATH}/acl_node_default ] && ENABLED_DEFAULT_ACL=0
[ "${acl_node_num}" == 0 ] && ENABLED_ACLS=0 && ENABLED_DEFAULT_ACL=0
}
start() {
@@ -1118,7 +881,7 @@ start() {
}
mkdir -p /tmp/etc /tmp/log $TMP_PATH $TMP_BIN_PATH $TMP_SCRIPT_FUNC_PATH $TMP_ROUTE_PATH $TMP_ACL_PATH $TMP_PATH2
get_config
export V2RAY_LOCATION_ASSET=$(config_t_get global_rules v2ray_location_asset "/usr/share/v2ray/")
export V2RAY_LOCATION_ASSET=$(config_n_get @global_rules[0] v2ray_location_asset "/usr/share/v2ray/")
export XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET
export ENABLE_DEPRECATED_GEOSITE=true
export ENABLE_DEPRECATED_GEOIP=true
@@ -1129,21 +892,16 @@ start() {
nftflag=0
USE_TABLES=""
check_run_environment
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
[ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" == "1" ] && {
uci -q set ${CONFIG}.@global[0].dnsmasq_dns_redirect='1'
uci -q commit ${CONFIG}
uci -q set dhcp.@dnsmasq[0].dns_redirect='0'
uci -q commit dhcp
[ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" == "1" ] && {
uci -q set ${CONFIG}.@global[0].dnsmasq_dns_redirect='1'
uci -q commit ${CONFIG}
uci -q set dhcp.@dnsmasq[0].dns_redirect='0'
uci -q commit dhcp
json_init
json_add_string "LOG" "0"
lua $APP_PATH/helper_dnsmasq.lua restart "$(json_dump)"
}
fi
mkdir -p ${GLOBAL_ACL_PATH}
[ "$ENABLED_DEFAULT_ACL" == 1 ] && run_global
run_global_dnsmasq
json_init
json_add_string "LOG" "0"
lua $APP_PATH/helper_dnsmasq.lua restart "$(json_dump)"
}
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start
set_cache_var "USE_TABLES" "$USE_TABLES"
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
@@ -1200,7 +958,7 @@ stop() {
rm -rf $GLOBAL_DNSMASQ_CONF_PATH
[ "1" = "1" ] && {
#restore logic
bak_dnsmasq_dns_redirect=$(config_t_get global dnsmasq_dns_redirect)
bak_dnsmasq_dns_redirect=$(config_n_get @global[0] dnsmasq_dns_redirect)
[ -n "${bak_dnsmasq_dns_redirect}" ] && {
uci -q set dhcp.@dnsmasq[0].dns_redirect="${bak_dnsmasq_dns_redirect}"
uci -q commit dhcp
@@ -1247,32 +1005,14 @@ get_direct_dns() {
get_config() {
ENABLED_DEFAULT_ACL=0
ENABLED=$(config_t_get global enabled 0)
NODE=$(config_t_get global node)
[ "$ENABLED" == 1 ] && {
[ -n "$NODE" ] && [ "$(config_get_type $NODE)" == "nodes" ] && ENABLED_DEFAULT_ACL=1
}
ENABLED_ACLS=$(config_t_get global acl_enable 0)
SOCKS_ENABLED=$(config_t_get global socks_enabled 0)
REDIR_PORT=$(echo $(get_new_port 1041 tcp,udp))
TCP_PROXY_WAY=$(config_t_get global_forwarding tcp_proxy_way redirect)
TCP_NO_REDIR_PORTS=$(config_t_get global_forwarding tcp_no_redir_ports 'disable')
UDP_NO_REDIR_PORTS=$(config_t_get global_forwarding udp_no_redir_ports 'disable')
TCP_REDIR_PORTS=$(config_t_get global_forwarding tcp_redir_ports '22,25,53,143,465,587,853,993,995,80,443')
UDP_REDIR_PORTS=$(config_t_get global_forwarding udp_redir_ports '1:65535')
PROXY_IPV6=$(config_t_get global_forwarding ipv6_tproxy 0)
TCP_PROXY_MODE="global"
UDP_PROXY_MODE="global"
LOCALHOST_PROXY=$(config_t_get global localhost_proxy '1')
CLIENT_PROXY=$(config_t_get global client_proxy '1')
DIRECT_DNS_QUERY_STRATEGY=$(config_t_get global direct_dns_query_strategy UseIP)
REMOTE_DNS_PROTOCOL=$(config_t_get global remote_dns_protocol tcp)
REMOTE_DNS_DETOUR=$(config_t_get global remote_dns_detour remote)
REMOTE_DNS=$(config_t_get global remote_dns 1.1.1.1:53 | sed 's/#/:/g' | sed -E 's/\:([^:]+)$/#\1/g')
REMOTE_FAKEDNS=$(config_t_get global remote_fakedns '0')
REMOTE_DNS_QUERY_STRATEGY=$(config_t_get global remote_dns_query_strategy UseIPv4)
DNS_CACHE=$(config_t_get global dns_cache 1)
DNS_REDIRECT=$(config_t_get global dns_redirect 1)
ENABLED=$(config_n_get @global[0] enabled 0)
NODE=$(config_n_get @global[0] node)
[ "$ENABLED" == 1 ] && [ -n "$NODE" ] && [ "$(config_get_type $NODE)" == "nodes" ] && ENABLED_DEFAULT_ACL=1
ENABLED_ACLS=$(config_n_get @global[0] acl_enable 0)
SOCKS_ENABLED=$(config_n_get @global[0] socks_enabled 0)
TCP_PROXY_WAY=$(config_n_get @global_forwarding[0] tcp_proxy_way redirect)
PROXY_IPV6=$(config_n_get @global_forwarding[0] ipv6_tproxy 0)
DIRECT_DNS_QUERY_STRATEGY=$(config_n_get @global[0] direct_dns_query_strategy UseIP)
get_direct_dns
@@ -1288,7 +1028,7 @@ get_config() {
fi
fi
set_cache_var GLOBAL_DNSMASQ_CONF ${DNSMASQ_CONF_DIR}/dnsmasq-${CONFIG}.conf
set_cache_var GLOBAL_DNSMASQ_CONF_PATH ${GLOBAL_ACL_PATH}/dnsmasq.d
set_cache_var GLOBAL_DNSMASQ_CONF_PATH ${TMP_ACL_PATH}/default_dnsmasq.d
QUEUE_RUN=1
}
@@ -0,0 +1,227 @@
-- Copyright (C) 2026 xiaorouji
local api = require "luci.passwall2.api"
local jsonc = api.jsonc
local sys = api.sys
local fs = api.fs
local i18n = api.i18n
local log = api.log
local uci, uci_get, uci_set, uci_del, uci_foreach, uci_save = api.uci, api.uci_get_c, api.uci_set_c, api.uci_del_c, api.uci_foreach_c, api.uci_save_c
local VAR = {} -- Set VAR
local D = {} -- Default Global Access Control
local L = {
acl = {},
node = {},
node_order = {}
}
function add_args(t, k, v)
if not t or not k or not v then return end
table.insert(t, k .. "=" .. '"' .. v .. '"')
end
function init_acl()
if true then
-- Get Default AC
D.flag = "default"
D.remarks = api.i18n.translatef("Default")
D.tcp_no_redir_ports = uci_get("@global_forwarding[0]", "tcp_no_redir_ports")
D.udp_no_redir_ports = uci_get("@global_forwarding[0]", "udp_no_redir_ports")
D.tcp_redir_ports = uci_get("@global_forwarding[0]", "tcp_redir_ports")
D.udp_redir_ports = uci_get("@global_forwarding[0]", "udp_redir_ports")
D.node = uci_get("@global[0]", "node")
D.local_proxy = uci_get("@global[0]", "localhost_proxy")
D.client_proxy = uci_get("@global[0]", "client_proxy")
if D.node then
local node = uci_get(D.node)
if node and node[".type"] == "nodes" then
local n = {
config = node,
enabled = uci_get("@global[0]", "enabled") or "0",
log = uci_get("@global[0]", "log_node") or "0",
loglevel = uci_get("@global[0]", "loglevel") or "warn",
socks_listen = uci_get("@global[0]", "node_socks_bind_local") == "0" and "0.0.0.0" or "127.0.0.1",
socks_port = uci_get("@global[0]", "node_socks_port"),
redir_port = api.get_new_port(),
dns_port = api.get_new_port(),
direct_dns_query_strategy = uci_get("@global[0]", "direct_dns_query_strategy") or "UseIP",
remote_dns_protocol = uci_get("@global[0]", "remote_dns_protocol") or "tcp",
remote_dns_detour = uci_get("@global[0]", "remote_dns_detour") or "remote",
remote_dns = uci_get("@global[0]", "remote_dns") or "1.1.1.1:53",
remote_dns_doh = uci_get("@global[0]", "remote_dns_doh") or "https://1.1.1.1/dns-query",
remote_dns_client_ip = uci_get("@global[0]", "remote_dns_client_ip"),
remote_dns_query_strategy = uci_get("@global[0]", "remote_dns_query_strategy") or "UseIPv4",
remote_rewrite_ttl = uci_get("@global[0]", "remote_rewrite_ttl"),
remote_fakedns = uci_get("@global[0]", "remote_fakedns") or "0",
}
L.node[D.flag] = n
D.use = D.flag
if n.enabled == "1" then
L.node_order[#L.node_order + 1] = D.flag
end
end
end
end
local acl_num = 0
if uci_get("@global[0]", "acl_enable") == "1" then
uci_foreach("acl_rule", function(o)
if o.enabled == "1" then
acl_num = acl_num + 1
local a = {}
a.flag = o[".name"]
a.remarks = o.remarks
a.interface = o.interface
a.sources = o.sources
a.tcp_no_redir_ports = o.tcp_no_redir_ports
a.udp_no_redir_ports = o.udp_no_redir_ports
a.tcp_redir_ports = o.tcp_redir_ports
a.udp_redir_ports = o.udp_redir_ports
a.client_proxy = "1"
a.local_proxy = "0"
a.node = o.node
if o.mode == "0" then
a.tcp_no_redir_ports = "1:65535"
a.udp_no_redir_ports = "1:65535"
elseif o.mode == "2" then
local U = L.node[D.use]
if U.enabled == "0" then
U.enabled = "1"
D.local_proxy = "0"
D.client_proxy = "0"
end
a.use = D.use
end
if a.tcp_no_redir_ports == "1:65535" and a.udp_no_redir_ports == "1:65535" then
a.node = nil
end
if a.node then
local node = uci_get(a.node)
if node and node[".type"] == "nodes" then
local n = {
config = node,
enabled = "1",
log = o.log or "0",
loglevel = o.loglevel or "warn",
redir_port = api.get_new_port(),
dns_port = api.get_new_port(),
direct_dns_query_strategy = o.direct_dns_query_strategy,
remote_dns_protocol = o.remote_dns_protocol,
remote_dns_detour = o.remote_dns_detour,
remote_dns = o.remote_dns,
remote_dns_doh = o.remote_dns_doh,
remote_dns_client_ip = o.remote_dns_client_ip,
remote_dns_query_strategy = o.remote_dns_query_strategy,
remote_rewrite_ttl = o.remote_rewrite_ttl,
remote_fakedns = o.remote_fakedns,
}
L.node[a.flag] = n
a.use = a.flag
if n.enabled == "1" then
L.node_order[#L.node_order + 1] = a.flag
end
end
end
L.acl[#L.acl + 1] = a
end
end)
end
if next(D) then
L.acl[#L.acl + 1] = D
end
VAR["ENABLED_ACLS"] = acl_num > 0 and 1 or 0
return L
end
function acl_app(l)
if not l then l = L end
for i, v in ipairs(l.acl) do
local sid = v.flag
local acl_path = api.TMP_ACL_PATH .. "/" .. sid
sys.call("mkdir -p " .. acl_path)
local out = io.open(acl_path .. "/var", "a")
for k2, v2 in pairs(v) do
if type(v2) == "string" then
out:write(k2 .. "=" .. '"' .. v2 .. '"' .. "\n")
end
end
if v.use then
local node = l.node[v.use]
if node.config then
out:write("node" .. "=" .. '"' .. node.config[".name"] .. '"' .. "\n")
out:write("node_remarks" .. "=" .. '"' .. node.config.remarks .. '"' .. "\n")
end
out:write("redir_port" .. "=" .. '"' .. node.redir_port .. '"' .. "\n")
end
out:close()
local source_list = "any"
if v.sources and #v.sources > 0 then
local s1 = {}
for i, w in ipairs(v.sources) do
if api.iprange(w) then
s1[#s1 + 1] = "iprange:" .. w
elseif w:find("ipset:") == 1 then
s1[#s1 + 1] = "ipset:" .. w
else
local _ip_or_mac = api.ip_or_mac(w)
if _ip_or_mac == "ip" then
s1[#s1 + 1] = "ip:" .. w
elseif _ip_or_mac == "mac" then
s1[#s1 + 1] = "mac:" .. w
end
end
end
if #s1 > 0 then
source_list = table.concat(s1, "\n")
end
end
if #source_list > 0 then
local out = io.open(acl_path .. "/source_list", "a")
out:write(source_list)
out:close()
end
end
-- Gen shell param
for _, v1 in ipairs(l.node_order) do
local v = l.node[v1]
if v.enabled == "1" then
local flag = v1
local node = v.config
local run_args = {}
local config_path = api.TMP_ACL_PATH .. "/" .. flag
local config_file = config_path .. ".json"
local log_file = v.log == "0" and "/dev/null" or config_path .. ".log"
add_args(run_args, "flag", flag)
add_args(run_args, "node", node[".name"])
add_args(run_args, "redir_port", v.redir_port)
add_args(run_args, "socks_address", v.socks_listen)
add_args(run_args, "socks_port", v.socks_port)
add_args(run_args, "dns_listen_port", v.dns_port)
add_args(run_args, "direct_dns_query_strategy", v.direct_dns_query_strategy)
add_args(run_args, "remote_dns_protocol", v.remote_dns_protocol)
add_args(run_args, "remote_dns_tcp_server", v.remote_dns)
add_args(run_args, "remote_dns_udp_server", v.remote_dns)
add_args(run_args, "remote_dns_doh", v.remote_dns_doh)
add_args(run_args, "remote_dns_client_ip", v.remote_dns_client_ip)
add_args(run_args, "remote_dns_detour", v.remote_dns_detour)
add_args(run_args, "remote_dns_query_strategy", v.remote_dns_query_strategy)
add_args(run_args, "remote_fakedns", v.remote_fakedns)
add_args(run_args, "remote_rewrite_ttl", v.remote_rewrite_ttl)
add_args(run_args, "config_file", config_file)
add_args(run_args, "loglevel", v.loglevel)
add_args(run_args, "log_file", log_file)
local out = io.open(api.TMP_ACL_PATH .. "/acl_node_" .. flag , "a")
out:write(table.concat(run_args, " "))
out:close()
end
end
for k, v in pairs(VAR) do
api.set_cache_var(k, v)
end
end
local acls = init_acl()
acl_app()
print(jsonc.stringify(acls, 1))
@@ -211,7 +211,7 @@ gen_shunt_list() {
[ -n "$_geoip_code" ] && {
get_geoip $_geoip_code ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $ipset_v4 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R
get_geoip $_geoip_code ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $ipset_v6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R
log 1 "$(i18n "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." "${shunt_id}" "${_geoip_code}" "IPSET")"
#log 3 "$(i18n "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." "${shunt_id}" "${_geoip_code}" "IPSET[${ipset_v4},${ipset_v6}]")"
}
}
}
@@ -230,6 +230,7 @@ gen_shunt_list() {
}
[ -n "${_SHUNT_LIST4}" ] && eval ${shunt_list4_var_name}=\"${_SHUNT_LIST4}\"
[ -n "${_SHUNT_LIST6}" ] && eval ${shunt_list6_var_name}=\"${_SHUNT_LIST6}\"
set_cache_var "${node}_gen_shunt_list" "1"
}
add_shunt_t_rule() {
@@ -255,45 +256,21 @@ add_shunt_t_rule() {
}
load_acl() {
acl_json=$(lua $APP_PATH/app_acl.lua)
acl_node
log_i18n 1 "Access Control:"
[ "$ENABLED_ACLS" == 1 ] && {
acl_app
for sid in $(ls -F ${TMP_ACL_PATH} | grep '/$' | awk -F '/' '{print $1}' | grep -v 'default'); do
eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-)
for sid in $(jsonfilter -s "${acl_json}" -e '$.acl[*].flag'); do
eval local $(cat "${TMP_ACL_PATH}/${sid}/var")
mode=${mode:-0}
tcp_no_redir_ports=${tcp_no_redir_ports:-default}
udp_no_redir_ports=${udp_no_redir_ports:-default}
tcp_proxy_mode="global"
udp_proxy_mode="global"
tcp_redir_ports=${tcp_redir_ports:-default}
udp_redir_ports=${udp_redir_ports:-default}
node=${node:-default}
[ "$mode" = "0" ] && {
tcp_no_redir_ports="1:65535"
udp_no_redir_ports="1:65535"
}
[ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS
[ "$udp_no_redir_ports" = "default" ] && udp_no_redir_ports=$UDP_NO_REDIR_PORTS
[ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS
[ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS
[ -z "$(get_cache_var "${node}_gen_shunt_list")" ] && [ -n "${node}" ] && gen_shunt_list "${node}" shunt_list4 shunt_list6
[ -n "${use}" ] && local dns_redirect_port=$(get_cache_var "ACL_${use}_dns_port")
[ -n "$(get_cache_var "ACL_${sid}_node")" ] && node=$(get_cache_var "ACL_${sid}_node")
[ -n "$(get_cache_var "ACL_${sid}_redir_port")" ] && redir_port=$(get_cache_var "ACL_${sid}_redir_port")
[ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port")
[ -n "$node" ] && node_remark=$(config_n_get $node remarks)
local ipt_tmp=$ipt_n
[ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m
if [ -n "$(get_cache_var "ACL_${sid}_default")" ]; then
shunt_list4=${SHUNT_LIST4}
shunt_list6=${SHUNT_LIST6}
else
# Shunt rules IP list (import when use shunt node)
gen_shunt_list "${node}" shunt_list4 shunt_list6
fi
_acl_list=${TMP_ACL_PATH}/${sid}/source_list
for i in $(cat $_acl_list); do
[ "${client_proxy}" = "1" ] && {
msg1="$(i18n "[%s]," "${remarks}")"
for i in $(cat ${TMP_ACL_PATH}/${sid}/source_list); do
local _ipt_source _ipv4
local msg
if [ -n "${interface}" ]; then
@@ -344,41 +321,39 @@ load_acl() {
else
continue
fi
msg="$(i18n "[%s]," "${remarks}")${msg}"
ipt_tmp=$ipt_n
[ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m
[ "$tcp_no_redir_ports" != "disable" ] && {
msg="${msg1}${msg}"
[ -n "$tcp_no_redir_ports" ] && {
if ! has_1_65535 "$tcp_no_redir_ports"; then
[ "$_ipv4" != "1" ] && add_port_rules "$ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp" $tcp_no_redir_ports "-j RETURN" 2>/dev/null
add_port_rules "$ipt_tmp -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp" $tcp_no_redir_ports "-j RETURN"
log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${tcp_no_redir_ports}")"
else
# It will return when it ends, so no extra rules are needed.
tcp_proxy_mode="disable"
no_tcp_proxy="1"
log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
fi
}
[ "$udp_no_redir_ports" != "disable" ] && {
[ -n "$udp_no_redir_ports" ] && {
if ! has_1_65535 "$udp_no_redir_ports"; then
[ "$_ipv4" != "1" ] && add_port_rules "$ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp" $udp_no_redir_ports "-j RETURN" 2>/dev/null
add_port_rules "$ipt_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp" $udp_no_redir_ports "-j RETURN"
log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${udp_no_redir_ports}")"
else
# It will return when it ends, so no extra rules are needed.
udp_proxy_mode="disable"
no_udp_proxy="1"
log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
fi
}
if ([ "$tcp_proxy_mode" != "disable" ] || [ "$udp_proxy_mode" != "disable" ]) && [ -n "$dns_redirect_port" ]; then
if ([ -z "$no_tcp_proxy" ] || [ -z "$no_udp_proxy" ]) && [ -n "$dns_redirect_port" ]; then
$ipt_n -A PSW2_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port
$ip6t_n -A PSW2_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null
$ipt_n -A PSW2_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port
$ip6t_n -A PSW2_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null
[ -z "$(get_cache_var "ACL_${sid}_default")" ] && log 2 "${msg}$(i18n "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server.")"
log 2 "${msg}$(i18n "DNS will redirected to the dedicated DNS server [%s]." "${dns_redirect_port}")"
else
$ipt_n -A PSW2_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN
$ip6t_n -A PSW2_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null
@@ -386,8 +361,8 @@ load_acl() {
$ip6t_n -A PSW2_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null
fi
[ "$tcp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remark}")"
[ -z "$no_tcp_proxy" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remarks}")"
if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${redir_port})"
ipt_j="-j PSW2_RULE"
@@ -424,8 +399,8 @@ load_acl() {
$ipt_tmp -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp -j RETURN
[ "$_ipv4" != "1" ] && $ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp -j RETURN 2>/dev/null
[ "$udp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remark}")(TPROXY:${redir_port})"
[ -z "$no_tcp_proxy" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remarks}")(TPROXY:${redir_port})"
$ipt_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source} -d $FAKE_IP -j PSW2_RULE
add_shunt_t_rule "${shunt_list4}" "$ipt_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source}" "-j PSW2_RULE" $udp_redir_ports
@@ -442,105 +417,143 @@ load_acl() {
}
$ipt_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp -j RETURN
[ "$_ipv4" != "1" ] && $ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp -j RETURN 2>/dev/null
unset ipt_tmp ipt_j _ipt_source msg msg2 _ipv4
unset ipt_j _ipt_source msg msg2 _ipv4 no_tcp_proxy no_udp_proxy
done
unset enabled sid remarks sources tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node interface
unset node_remark _acl_list
done
}
[ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ] && {
local comment_d="$(i18n "Default")"
msg="$(i18n "[%s]," ${comment_d})"
local ipt_tmp=$ipt_n
[ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN"
add_port_rules "$ipt_tmp -A PSW2 $(comment "${comment_d}") -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN"
if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then
log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${TCP_NO_REDIR_PORTS}")"
else
TCP_PROXY_MODE="disable"
log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
fi
unset msg1
}
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && {
add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN"
add_port_rules "$ipt_tmp -A PSW2 $(comment "${comment_d}") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN"
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then
log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")"
else
UDP_PROXY_MODE="disable"
log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
fi
}
if ([ "$TCP_PROXY_MODE" != "disable" ] || [ "$UDP_PROXY_MODE" != "disable" ]) && [ -n "$NODE" ]; then
[ -n "$DNS_REDIRECT_PORT" ] && {
$ipt_n -A PSW2_DNS $(comment "${comment_d}") -p udp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT
$ip6t_n -A PSW2_DNS $(comment "${comment_d}") -p udp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null
$ipt_n -A PSW2_DNS $(comment "${comment_d}") -p tcp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT
$ip6t_n -A PSW2_DNS $(comment "${comment_d}") -p tcp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null
[ "${local_proxy}" = "1" ] && {
msg="$(i18n "[Local],")"
[ -n "$tcp_no_redir_ports" ] && {
add_port_rules "$ipt_tmp -A PSW2_OUTPUT -p tcp" $tcp_no_redir_ports "-j RETURN"
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p tcp" $tcp_no_redir_ports "-j RETURN"
if ! has_1_65535 "$tcp_no_redir_ports"; then
log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${tcp_no_redir_ports}")"
else
no_tcp_local_proxy="1"
log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
fi
}
fi
if [ "$TCP_PROXY_MODE" != "disable" ] && [ -n "$NODE" ]; then
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "$(config_n_get $NODE remarks)")"
if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${REDIR_PORT})"
ipt_j="-j PSW2_RULE"
else
msg2="${msg2}(REDIRECT:${REDIR_PORT})"
ipt_j="$(REDIRECT $REDIR_PORT)"
fi
[ "$accept_icmp" = "1" ] && {
$ipt_n -A PSW2 $(comment "${comment_d}") -p icmp -d $FAKE_IP $(REDIRECT)
add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_n -A PSW2 $(comment "${comment_d}") -p icmp" "$(REDIRECT)"
$ipt_n -A PSW2 $(comment "${comment_d}") -p icmp $(REDIRECT)
[ -n "$udp_no_redir_ports" ] && {
add_port_rules "$ipt_m -A PSW2_OUTPUT -p udp" $udp_no_redir_ports "-j RETURN"
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p udp" $udp_no_redir_ports "-j RETURN"
if ! has_1_65535 "$udp_no_redir_ports"; then
log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${udp_no_redir_ports}")"
else
no_udp_local_proxy="1"
log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
fi
}
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && {
$ip6t_n -A PSW2 $(comment "${comment_d}") -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT)
add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_n -A PSW2 $(comment "${comment_d}") -p ipv6-icmp" "$(REDIRECT)"
$ip6t_n -A PSW2 $(comment "${comment_d}") -p ipv6-icmp $(REDIRECT)
}
if [ -n "$node" ] && ([ -z "$no_tcp_local_proxy" ] || [ -z "$no_udp_local_proxy" ]); then
[ -n "$dns_redirect_port" ] && {
$ipt_n -A OUTPUT $(comment "PSW2_DNS") -p udp -o lo --dport 53 -j REDIRECT --to-ports $dns_redirect_port
$ip6t_n -A OUTPUT $(comment "PSW2_DNS") -p udp -o lo --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null
$ipt_n -A OUTPUT $(comment "PSW2_DNS") -p tcp -o lo --dport 53 -j REDIRECT --to-ports $dns_redirect_port
$ip6t_n -A OUTPUT $(comment "PSW2_DNS") -p tcp -o lo --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null
log 2 "${msg}$(i18n "DNS will redirected to the dedicated DNS server [%s]." "${dns_redirect_port}")"
}
fi
$ipt_tmp -A PSW2 $(comment "${comment_d}") -p tcp -d $FAKE_IP ${ipt_j}
add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_tmp -A PSW2 $(comment "${comment_d}") -p tcp" "${ipt_j}" $TCP_REDIR_PORTS
add_port_rules "$ipt_tmp -A PSW2 $(comment "${comment_d}") -p tcp" $TCP_REDIR_PORTS "${ipt_j}"
[ -n "${is_tproxy}" ] && $ipt_m -A PSW2 $(comment "${comment_d}") -p tcp $(REDIRECT $REDIR_PORT TPROXY)
local comment_l="$(i18n "Local")"
[ "$PROXY_IPV6" == "1" ] && {
$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp -d $FAKE_IP_6 -j PSW2_RULE
add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp" "-j PSW2_RULE" $TCP_REDIR_PORTS
add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp" $TCP_REDIR_PORTS "-j PSW2_RULE"
$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp $(REDIRECT $REDIR_PORT TPROXY)
}
# Loading local router proxy TCP
if [ -n "$node" ] && [ -z "$no_tcp_local_proxy" ]; then
[ "$accept_icmp" = "1" ] && {
$ipt_n -A OUTPUT $(dst $IPSET_DIRECT !) -p icmp -j PSW2_OUTPUT
$ipt_n -A PSW2_OUTPUT -p icmp -d $FAKE_IP $(REDIRECT)
add_shunt_t_rule "${shunt_list4}" "$ipt_n -A PSW2_OUTPUT -p icmp" "$(REDIRECT)"
$ipt_n -A PSW2_OUTPUT -p icmp $(REDIRECT)
}
log 2 "${msg2}"
fi
[ "$accept_icmpv6" = "1" ] && {
$ip6t_n -A OUTPUT $(dst $IPSET_DIRECT6 !) -p ipv6-icmp -j PSW2_OUTPUT
$ip6t_n -A PSW2_OUTPUT -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT)
add_shunt_t_rule "${shunt_list6}" "$ip6t_n -A PSW2_OUTPUT -p ipv6-icmp" "$(REDIRECT)"
$ip6t_n -A PSW2_OUTPUT -p ipv6-icmp $(REDIRECT)
}
if [ "$UDP_PROXY_MODE" != "disable" ] && [ -n "$NODE" ]; then
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "$(config_n_get $NODE remarks)")(TPROXY:${REDIR_PORT})"
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remarks}")"
if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${redir_port})"
ipt_j="-j PSW2_RULE"
else
msg2="${msg2}(REDIRECT:${redir_port})"
ipt_j="$(REDIRECT $redir_port)"
fi
$ipt_m -A PSW2 $(comment "${comment_d}") -p udp -d $FAKE_IP -j PSW2_RULE
add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_m -A PSW2 $(comment "${comment_d}") -p udp" "-j PSW2_RULE" $UDP_REDIR_PORTS
add_port_rules "$ipt_m -A PSW2 $(comment "${comment_d}") -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE"
$ipt_m -A PSW2 $(comment "${comment_d}") -p udp $(REDIRECT $REDIR_PORT TPROXY)
$ipt_tmp -A PSW2_OUTPUT -p tcp -d $FAKE_IP ${ipt_j}
add_shunt_t_rule "${shunt_list4}" "$ipt_tmp -A PSW2_OUTPUT -p tcp" "${ipt_j}" $tcp_redir_ports
add_port_rules "$ipt_tmp -A PSW2_OUTPUT -p tcp" $tcp_redir_ports "${ipt_j}"
[ -z "${is_tproxy}" ] && $ipt_n -A OUTPUT $(dst $IPSET_DIRECT !) -p tcp -j PSW2_OUTPUT
[ -n "${is_tproxy}" ] && {
$ipt_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo $(REDIRECT $redir_port TPROXY)
$ipt_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo -j RETURN
insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) $(dst $IPSET_DIRECT !) -p tcp -j PSW2_OUTPUT"
}
[ "$PROXY_IPV6" == "1" ] && {
$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp -d $FAKE_IP_6 -j PSW2_RULE
add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp" "-j PSW2_RULE" $UDP_REDIR_PORTS
add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE"
$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp $(REDIRECT $REDIR_PORT TPROXY)
}
[ "$PROXY_IPV6" == "1" ] && {
$ip6t_m -A PSW2_OUTPUT -p tcp -d $FAKE_IP_6 -j PSW2_RULE
add_shunt_t_rule "${shunt_list6}" "$ip6t_m -A PSW2_OUTPUT -p tcp" "-j PSW2_RULE" $tcp_redir_ports
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p tcp" $tcp_redir_ports "-j PSW2_RULE"
$ip6t_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo $(REDIRECT $redir_port TPROXY)
$ip6t_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo -j RETURN
insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) $(dst $IPSET_DIRECT6 !) -p tcp -j PSW2_OUTPUT"
}
log 2 "${msg2}"
fi
}
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do
$ipt_n -A PSW2_OUTPUT -o $iface -p tcp -j RETURN
$ipt_m -A PSW2_OUTPUT -o $iface -p tcp -j RETURN
done
}
log 2 "${msg2}"
fi
# Loading local router proxy UDP
if [ -n "$node" ] && [ -z "$no_udp_local_proxy" ]; then
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remarks}")(TPROXY:${redir_port})"
$ipt_m -A PSW2_OUTPUT -p udp -d $FAKE_IP -j PSW2_RULE
add_shunt_t_rule "${shunt_list4}" "$ipt_m -A PSW2_OUTPUT -p udp" "-j PSW2_RULE" $udp_redir_ports
add_port_rules "$ipt_m -A PSW2_OUTPUT -p udp" $udp_redir_ports "-j PSW2_RULE"
$ipt_m -A PSW2 $(comment "${comment_l}") -p udp -i lo $(REDIRECT $redir_port TPROXY)
$ipt_m -A PSW2 $(comment "${comment_l}") -p udp -i lo -j RETURN
insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) $(dst $IPSET_DIRECT !) -p udp -j PSW2_OUTPUT"
[ "$PROXY_IPV6" == "1" ] && {
$ip6t_m -A PSW2_OUTPUT -p udp -d $FAKE_IP_6 -j PSW2_RULE
add_shunt_t_rule "${shunt_list6}" "$ip6t_m -A PSW2_OUTPUT -p udp" "-j PSW2_RULE" $udp_redir_ports
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p udp" $udp_redir_ports "-j PSW2_RULE"
$ip6t_m -A PSW2 $(comment "${comment_l}") -p udp -i lo $(REDIRECT $redir_port TPROXY)
$ip6t_m -A PSW2 $(comment "${comment_l}") -p udp -i lo -j RETURN
insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) $(dst $IPSET_DIRECT6 !) -p udp -j PSW2_OUTPUT"
}
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do
$ipt_n -A PSW2_OUTPUT -o $iface -p udp -j RETURN
$ipt_m -A PSW2_OUTPUT -o $iface -p udp -j RETURN
done
}
log 2 "${msg2}"
fi
$ipt_m -I OUTPUT $(comment "mangle-OUTPUT-PSW2") -o lo -j RETURN
insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -m mark --mark ${FWMARK} -j RETURN"
$ip6t_m -I OUTPUT $(comment "mangle-OUTPUT-PSW2") -o lo -j RETURN
insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -m mark --mark ${FWMARK} -j RETURN"
$ipt_m -A PSW2 -p tcp --dport 53 -j ACCEPT
$ipt_m -A PSW2 -p udp --dport 53 -j ACCEPT
$ip6t_m -A PSW2 -p tcp --dport 53 -j ACCEPT
$ip6t_m -A PSW2 -p udp --dport 53 -j ACCEPT
unset msg msg2 comment_l
}
unset dns_redirect_port ipt_tmp
unset $(cat "${TMP_ACL_PATH}/${sid}/var" | awk -F '=' '{print $1}' | tr "\n" " ")
done
}
filter_haproxy() {
@@ -684,15 +697,12 @@ add_firewall_rule() {
done
}
# Shunt rules IP list (import when use shunt node)
gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6
# Filter all node IPs
filter_vpsip > /dev/null 2>&1 &
filter_haproxy > /dev/null 2>&1 &
accept_icmp=$(config_t_get global_forwarding accept_icmp 0)
accept_icmpv6=$(config_t_get global_forwarding accept_icmpv6 0)
accept_icmp=$(config_n_get @global_forwarding[0] accept_icmp 0)
accept_icmpv6=$(config_n_get @global_forwarding[0] accept_icmpv6 0)
if [ "${TCP_PROXY_WAY}" = "redirect" ]; then
unset is_tproxy
@@ -720,7 +730,7 @@ add_firewall_rule() {
$ipt_n -A PSW2_OUTPUT -m mark --mark 255 -j RETURN
$ipt_n -N PSW2_DNS
if [ $(config_t_get global dns_redirect "1") = "0" ]; then
if [ $(config_n_get @global[0] dns_redirect "1") = "0" ]; then
#Only hijack when dest address is local IP
$ipt_n -I PREROUTING -m set --match-set $IPSET_DIRECT src $(dst $IPSET_LOCAL) -j PSW2_DNS
else
@@ -763,7 +773,7 @@ add_firewall_rule() {
}
$ip6t_n -N PSW2_DNS
if [ $(config_t_get global dns_redirect "1") = "0" ]; then
if [ $(config_n_get @global[0] dns_redirect "1") = "0" ]; then
#Only hijack when dest address is local IP
$ip6t_n -I PREROUTING -m set --match-set $IPSET_DIRECT6 src $(dst $IPSET_LOCAL6) -j PSW2_DNS
else
@@ -809,134 +819,6 @@ add_firewall_rule() {
ip -6 rule add fwmark ${FWMARK} table 999 priority 999
ip -6 route add local ::/0 dev lo table 999
[ "$ENABLED_DEFAULT_ACL" == 1 ] && {
local ipt_tmp=$ipt_n
[ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m
TCP_LOCALHOST_PROXY=$LOCALHOST_PROXY
UDP_LOCALHOST_PROXY=$LOCALHOST_PROXY
msg="$(i18n "[Local],")"
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
add_port_rules "$ipt_tmp -A PSW2_OUTPUT -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN"
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN"
if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then
log 1 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${TCP_NO_REDIR_PORTS}")"
else
unset TCP_LOCALHOST_PROXY
log 1 "${msg}$(i18n "not proxy all %s" "TCP")"
fi
}
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && {
add_port_rules "$ipt_m -A PSW2_OUTPUT -p udp" $UDP_NO_REDIR_PORTS "-j RETURN"
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p udp" $UDP_NO_REDIR_PORTS "-j RETURN"
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then
log 1 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")"
else
unset UDP_LOCALHOST_PROXY
log 1 "${msg}$(i18n "not proxy all %s" "UDP")"
fi
}
if [ -n "$NODE" ] && ([ "$TCP_LOCALHOST_PROXY" = "1" ] || [ "$UDP_LOCALHOST_PROXY" = "1" ]); then
[ -n "$DNS_REDIRECT_PORT" ] && {
$ipt_n -A OUTPUT $(comment "PSW2_DNS") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT
$ip6t_n -A OUTPUT $(comment "PSW2_DNS") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null
$ipt_n -A OUTPUT $(comment "PSW2_DNS") -p tcp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT
$ip6t_n -A OUTPUT $(comment "PSW2_DNS") -p tcp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null
}
fi
local comment_l="$(i18n "Local")"
# Loading local router proxy TCP
if [ -n "$NODE" ] && [ "$TCP_LOCALHOST_PROXY" = "1" ]; then
[ "$accept_icmp" = "1" ] && {
$ipt_n -A OUTPUT $(dst $IPSET_DIRECT !) -p icmp -j PSW2_OUTPUT
$ipt_n -A PSW2_OUTPUT -p icmp -d $FAKE_IP $(REDIRECT)
add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_n -A PSW2_OUTPUT -p icmp" "$(REDIRECT)"
$ipt_n -A PSW2_OUTPUT -p icmp $(REDIRECT)
}
[ "$accept_icmpv6" = "1" ] && {
$ip6t_n -A OUTPUT $(dst $IPSET_DIRECT6 !) -p ipv6-icmp -j PSW2_OUTPUT
$ip6t_n -A PSW2_OUTPUT -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT)
add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_n -A PSW2_OUTPUT -p ipv6-icmp" "$(REDIRECT)"
$ip6t_n -A PSW2_OUTPUT -p ipv6-icmp $(REDIRECT)
}
if [ -n "${is_tproxy}" ]; then
ipt_j="-j PSW2_RULE"
else
ipt_j="$(REDIRECT $REDIR_PORT)"
fi
$ipt_tmp -A PSW2_OUTPUT -p tcp -d $FAKE_IP ${ipt_j}
add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_tmp -A PSW2_OUTPUT -p tcp" "${ipt_j}" $TCP_REDIR_PORTS
add_port_rules "$ipt_tmp -A PSW2_OUTPUT -p tcp" $TCP_REDIR_PORTS "${ipt_j}"
[ -z "${is_tproxy}" ] && $ipt_n -A OUTPUT $(dst $IPSET_DIRECT !) -p tcp -j PSW2_OUTPUT
[ -n "${is_tproxy}" ] && {
$ipt_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo $(REDIRECT $REDIR_PORT TPROXY)
$ipt_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo -j RETURN
insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) $(dst $IPSET_DIRECT !) -p tcp -j PSW2_OUTPUT"
}
[ "$PROXY_IPV6" == "1" ] && {
$ip6t_m -A PSW2_OUTPUT -p tcp -d $FAKE_IP_6 -j PSW2_RULE
add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_m -A PSW2_OUTPUT -p tcp" "-j PSW2_RULE" $TCP_REDIR_PORTS
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p tcp" $TCP_REDIR_PORTS "-j PSW2_RULE"
$ip6t_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo $(REDIRECT $REDIR_PORT TPROXY)
$ip6t_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo -j RETURN
insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) $(dst $IPSET_DIRECT6 !) -p tcp -j PSW2_OUTPUT"
}
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do
$ipt_n -A PSW2_OUTPUT -o $iface -p tcp -j RETURN
$ipt_m -A PSW2_OUTPUT -o $iface -p tcp -j RETURN
done
}
fi
# Loading local router proxy UDP
if [ -n "$NODE" ] && [ "$UDP_LOCALHOST_PROXY" = "1" ]; then
$ipt_m -A PSW2_OUTPUT -p udp -d $FAKE_IP -j PSW2_RULE
add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_m -A PSW2_OUTPUT -p udp" "-j PSW2_RULE" $UDP_REDIR_PORTS
add_port_rules "$ipt_m -A PSW2_OUTPUT -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE"
$ipt_m -A PSW2 $(comment "${comment_l}") -p udp -i lo $(REDIRECT $REDIR_PORT TPROXY)
$ipt_m -A PSW2 $(comment "${comment_l}") -p udp -i lo -j RETURN
insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) $(dst $IPSET_DIRECT !) -p udp -j PSW2_OUTPUT"
[ "$PROXY_IPV6" == "1" ] && {
$ip6t_m -A PSW2_OUTPUT -p udp -d $FAKE_IP_6 -j PSW2_RULE
add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_m -A PSW2_OUTPUT -p udp" "-j PSW2_RULE" $UDP_REDIR_PORTS
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE"
$ip6t_m -A PSW2 $(comment "${comment_l}") -p udp -i lo $(REDIRECT $REDIR_PORT TPROXY)
$ip6t_m -A PSW2 $(comment "${comment_l}") -p udp -i lo -j RETURN
insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) $(dst $IPSET_DIRECT6 !) -p udp -j PSW2_OUTPUT"
}
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do
$ipt_n -A PSW2_OUTPUT -o $iface -p udp -j RETURN
$ipt_m -A PSW2_OUTPUT -o $iface -p udp -j RETURN
done
}
fi
$ipt_m -I OUTPUT $(comment "mangle-OUTPUT-PSW2") -o lo -j RETURN
insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -m mark --mark ${FWMARK} -j RETURN"
$ip6t_m -I OUTPUT $(comment "mangle-OUTPUT-PSW2") -o lo -j RETURN
insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -m mark --mark ${FWMARK} -j RETURN"
$ipt_m -A PSW2 -p tcp --dport 53 -j ACCEPT
$ipt_m -A PSW2 -p udp --dport 53 -j ACCEPT
$ip6t_m -A PSW2 -p tcp --dport 53 -j ACCEPT
$ip6t_m -A PSW2 -p udp --dport 53 -j ACCEPT
}
load_acl
filter_direct_node_list > /dev/null 2>&1 &
@@ -1062,7 +944,7 @@ start() {
stop() {
[ -z "$(command -v log_i18n)" ] && . "$UTILS_PATH"
del_firewall_rule
[ $(config_t_get global flush_set "0") = "1" ] && {
[ $(config_n_get @global[0] flush_set "0") = "1" ] && {
uci -q delete ${CONFIG}.@global[0].flush_set
uci -q commit ${CONFIG}
flush_ipset
@@ -3,9 +3,9 @@
. /usr/share/passwall2/utils.sh
LOCK_FILE=${LOCK_PATH}/${CONFIG}_monitor.lock
ENABLED=$(config_t_get global enabled 0)
ENABLED=$(config_n_get @global[0] enabled 0)
[ "$ENABLED" != 1 ] && return 1
ENABLED=$(config_t_get global_delay start_daemon 0)
ENABLED=$(config_n_get @global_delay[0] start_daemon 0)
[ "$ENABLED" != 1 ] && return 1
sleep 58s
while [ "$ENABLED" -eq 1 ]; do
@@ -252,7 +252,7 @@ gen_shunt_list() {
[ -n "$_geoip_code" ] && {
get_geoip $_geoip_code ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $nftset_v4 "0"
get_geoip $_geoip_code ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $nftset_v6 "0"
log 1 "$(i18n "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." "${shunt_id}" "${_geoip_code}" "NFTSET")"
#log 3 "$(i18n "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." "${shunt_id}" "${_geoip_code}" "NFTSET[${nftset_v4},${nftset_v6}]")"
}
}
}
@@ -271,6 +271,7 @@ gen_shunt_list() {
}
[ -n "${_SHUNT_LIST4}" ] && eval ${shunt_list4_var_name}=\"${_SHUNT_LIST4}\"
[ -n "${_SHUNT_LIST6}" ] && eval ${shunt_list6_var_name}=\"${_SHUNT_LIST6}\"
set_cache_var "${node}_gen_shunt_list" "1"
}
add_shunt_t_rule() {
@@ -293,45 +294,18 @@ add_shunt_t_rule() {
}
load_acl() {
[ "$ENABLED_ACLS" == 1 ] && {
log_i18n 1 "Access Control:"
acl_app
for sid in $(ls -F ${TMP_ACL_PATH} | grep '/$' | awk -F '/' '{print $1}' | grep -v 'default'); do
eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-)
acl_json=$(lua $APP_PATH/app_acl.lua)
acl_node
log_i18n 1 "Access Control:"
for sid in $(jsonfilter -s "${acl_json}" -e '$.acl[*].flag'); do
eval $(cat "${TMP_ACL_PATH}/${sid}/var")
mode=${mode:-0}
tcp_no_redir_ports=${tcp_no_redir_ports:-default}
udp_no_redir_ports=${udp_no_redir_ports:-default}
tcp_proxy_mode="global"
udp_proxy_mode="global"
tcp_redir_ports=${tcp_redir_ports:-default}
udp_redir_ports=${udp_redir_ports:-default}
node=${node:-default}
[ "$mode" = "0" ] && {
tcp_no_redir_ports="1:65535"
udp_no_redir_ports="1:65535"
}
[ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS
[ "$udp_no_redir_ports" = "default" ] && udp_no_redir_ports=$UDP_NO_REDIR_PORTS
[ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS
[ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS
[ -z "$(get_cache_var "${node}_gen_shunt_list")" ] && [ -n "${node}" ] && gen_shunt_list "${node}" shunt_list4 shunt_list6
[ -n "${use}" ] && local dns_redirect_port=$(get_cache_var "ACL_${use}_dns_port")
[ -n "$(get_cache_var "ACL_${sid}_node")" ] && node=$(get_cache_var "ACL_${sid}_node")
[ -n "$(get_cache_var "ACL_${sid}_redir_port")" ] && redir_port=$(get_cache_var "ACL_${sid}_redir_port")
[ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port")
[ -n "$node" ] && node_remark=$(config_n_get $node remarks)
if [ -n "$(get_cache_var "ACL_${sid}_default")" ]; then
shunt_list4=${SHUNT_LIST4}
shunt_list6=${SHUNT_LIST6}
else
# Shunt rules IP list (import when use shunt node)
gen_shunt_list "${node}" shunt_list4 shunt_list6
fi
_acl_list=${TMP_ACL_PATH}/${sid}/source_list
for i in $(cat $_acl_list); do
[ "${client_proxy}" = "1" ] && {
msg1="$(i18n "[%s]," "${remarks}")"
for i in $(cat ${TMP_ACL_PATH}/${sid}/source_list); do
local _ipt_source _ipv4
local msg
if [ -n "${interface}" ]; then
@@ -375,40 +349,38 @@ load_acl() {
else
continue
fi
msg="$(i18n "[%s]," "${remarks}")${msg}"
msg="${msg1}${msg}"
[ "$tcp_no_redir_ports" != "disable" ] && {
[ -n "$tcp_no_redir_ports" ] && {
if ! has_1_65535 "$tcp_no_redir_ports"; then
nft "add rule $NFTABLE_NAME $nft_prerouting_chain ${_ipt_source} ip protocol tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\""
[ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ${_ipt_source} meta l4proto tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\""
log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${tcp_no_redir_ports}")"
else
# It will return when it ends, so no extra rules are needed.
tcp_proxy_mode="disable"
no_tcp_proxy="1"
log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
fi
}
[ "$udp_no_redir_ports" != "disable" ] && {
[ -n "$udp_no_redir_ports" ] && {
if ! has_1_65535 "$udp_no_redir_ports"; then
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\""
[ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\"" 2>/dev/null
log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${udp_no_redir_ports}")"
else
# It will return when it ends, so no extra rules are needed.
udp_proxy_mode="disable"
no_udp_proxy="1"
log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
fi
}
if ([ "$tcp_proxy_mode" != "disable" ] || [ "$udp_proxy_mode" != "disable" ]) && [ -n "$dns_redirect_port" ]; then
[ -n "$dns_redirect_port" ] && {
nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\""
[ -z "$(get_cache_var "ACL_${sid}_default")" ] && log 2 "${msg}$(i18n "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server.")"
}
if ([ -z "$no_tcp_proxy" ] || [ -z "$no_udp_proxy" ]) && [ -n "$dns_redirect_port" ]; then
nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\""
log 2 "${msg}$(i18n "DNS will redirected to the dedicated DNS server [%s]." "${dns_redirect_port}")"
else
nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\""
@@ -416,8 +388,8 @@ load_acl() {
nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\""
fi
[ "$tcp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remark}")"
[ -z "$no_tcp_proxy" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remarks}")"
if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${redir_port})"
nft_chain="PSW2_MANGLE"
@@ -458,8 +430,8 @@ load_acl() {
nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} counter return comment \"$remarks\""
[ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null
[ "$udp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remark}")(TPROXY:${redir_port})"
[ -z "$no_tcp_proxy" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remarks}")(TPROXY:${redir_port})"
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} ip daddr $FAKE_IP counter jump PSW2_RULE comment \"$remarks\""
add_shunt_t_rule "${shunt_list4}" "nft add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr" "counter jump PSW2_RULE" "$remarks"
@@ -476,108 +448,140 @@ load_acl() {
}
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} counter return comment \"$remarks\""
[ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null
unset nft_chain nft_j _ipt_source msg msg2 _ipv4
unset nft_chain nft_j _ipt_source msg msg2 _ipv4 no_tcp_proxy no_udp_proxy
done
unset enabled sid remarks sources tcp_proxy_mode udp_proxy_mode tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node interface
unset redir_port node_remark _acl_list
done
}
[ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ] && {
local comment="$(i18n "Default")"
msg="$(i18n "[%s]," ${comment})"
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"${comment}\""
if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then
log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${TCP_NO_REDIR_PORTS}")"
else
TCP_PROXY_MODE="disable"
log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
fi
unset msg1
}
[ "${local_proxy}" = "1" ] && {
msg="$(i18n "[Local],")"
[ -n "$tcp_no_redir_ports" ] && {
nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp $(factor $tcp_no_redir_ports "tcp dport") counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $tcp_no_redir_ports "tcp dport") counter return"
if ! has_1_65535 "$tcp_no_redir_ports"; then
log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${tcp_no_redir_ports}")"
else
no_tcp_local_proxy="1"
log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
fi
}
[ -n "$udp_no_redir_ports" ] && {
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $udp_no_redir_ports "udp dport") counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $udp_no_redir_ports "udp dport") counter return"
if ! has_1_65535 "$udp_no_redir_ports"; then
log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${udp_no_redir_ports}")"
else
no_udp_local_proxy="1"
log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
fi
}
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && {
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"${comment}\""
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then
log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")"
else
UDP_PROXY_MODE="disable"
log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
if [ -n "$node" ] && ([ -z "$no_tcp_local_proxy" ] || [ -z "$no_udp_local_proxy" ]); then
[ -n "$dns_redirect_port" ] && {
nft "add rule $NFTABLE_NAME nat_output ip protocol udp oif lo udp dport 53 counter redirect to :$dns_redirect_port comment \"PSW2_DNS\""
nft "add rule $NFTABLE_NAME nat_output ip protocol tcp oif lo tcp dport 53 counter redirect to :$dns_redirect_port comment \"PSW2_DNS\""
nft "add rule $NFTABLE_NAME nat_output meta l4proto udp oif lo udp dport 53 counter redirect to :$dns_redirect_port comment \"PSW2_DNS\""
nft "add rule $NFTABLE_NAME nat_output meta l4proto tcp oif lo tcp dport 53 counter redirect to :$dns_redirect_port comment \"PSW2_DNS\""
log 2 "${msg}$(i18n "DNS will redirected to the dedicated DNS server [%s]." "${dns_redirect_port}")"
}
fi
local comment_l="$(i18n "Local")"
# Loading local router proxy TCP
if [ -n "$node" ] && [ -z "$no_tcp_local_proxy" ]; then
[ "$accept_icmp" = "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp ip daddr $FAKE_IP counter redirect"
add_shunt_t_rule "${shunt_list4}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp ip daddr" "counter redirect"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp counter redirect"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp counter return"
}
[ "$accept_icmpv6" = "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 counter redirect"
add_shunt_t_rule "${shunt_list6}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr" "counter redirect"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter redirect"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter return"
}
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remarks}")"
if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${redir_port})"
nft_chain="PSW2_OUTPUT_MANGLE"
nft_j="counter jump PSW2_RULE"
else
msg2="${msg2}(REDIRECT:${redir_port})"
nft_chain="PSW2_OUTPUT_NAT"
nft_j="$(REDIRECT $redir_port)"
fi
nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr $FAKE_IP ${nft_j}"
add_shunt_t_rule "${shunt_list4}" "nft add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $tcp_redir_ports "tcp dport") ip daddr" "${nft_j}"
nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $tcp_redir_ports "tcp dport") ${nft_j}"
[ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME nat_output ip daddr != @$NFTSET_DIRECT ip protocol tcp counter jump PSW2_OUTPUT_NAT"
[ -n "${is_tproxy}" ] && {
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo $(REDIRECT $redir_port TPROXY4) comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo counter return comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME mangle_output ip daddr != @$NFTSET_DIRECT ip protocol tcp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\""
}
[ "$PROXY_IPV6" == "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE"
add_shunt_t_rule "${shunt_list6}" "nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $tcp_redir_ports "tcp dport") ip6 daddr" "counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $tcp_redir_ports "tcp dport") counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo $(REDIRECT $redir_port TPROXY6) comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo counter return comment \"${comment_l}\""
}
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do
nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp oif $iface counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol tcp oif $iface counter return"
done
}
log 2 "${msg2}"
fi
# Loading local router proxy UDP
if [ -n "$node" ] && [ -z "$no_udp_local_proxy" ]; then
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remarks}")(TPROXY:${redir_port})"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE"
add_shunt_t_rule "${shunt_list4}" "nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $udp_redir_ports "udp dport") ip daddr" "counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $udp_redir_ports "udp dport") counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo $(REDIRECT $redir_port TPROXY4) comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo counter return comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME mangle_output ip daddr != @$NFTSET_DIRECT ip protocol udp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\""
[ "$PROXY_IPV6" == "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE"
add_shunt_t_rule "${shunt_list6}" "nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $udp_redir_ports "udp dport") ip6 daddr" "counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $udp_redir_ports "udp dport") counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo $(REDIRECT $redir_port TPROXY6) comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo counter return comment \"${comment_l}\""
}
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do
nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol udp oif $iface counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol udp oif $iface counter return"
done
}
log 2 "${msg2}"
fi
nft "add rule $NFTABLE_NAME mangle_output oif lo counter return comment \"PSW2_OUTPUT_MANGLE\""
nft "add rule $NFTABLE_NAME mangle_output meta mark ${FWMARK} counter return comment \"PSW2_OUTPUT_MANGLE\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp tcp dport 53 counter accept"
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp udp dport 53 counter accept"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp tcp dport 53 counter accept"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp udp dport 53 counter accept"
unset msg msg2 comment_l
}
if ([ "$TCP_PROXY_MODE" != "disable" ] || [ "$UDP_PROXY_MODE" != "disable" ]) && [ -n "$NODE" ]; then
[ -n "$DNS_REDIRECT_PORT" ] && {
nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol udp udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol tcp tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto udp udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto tcp tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"${comment}\""
}
fi
if [ "$TCP_PROXY_MODE" != "disable" ] && [ -n "$NODE" ]; then
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "$(config_n_get $NODE remarks)")"
if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${REDIR_PORT})"
nft_chain="PSW2_MANGLE"
nft_j="counter jump PSW2_RULE"
else
msg2="${msg2}(REDIRECT:${REDIR_PORT})"
nft_chain="PSW2_NAT"
nft_j="$(REDIRECT $REDIR_PORT)"
fi
[ "$accept_icmp" = "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ip daddr $FAKE_IP $(REDIRECT) comment \"${comment}\""
add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ip daddr" "$(REDIRECT)" "${comment}"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp $(REDIRECT) comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp return comment \"${comment}\""
}
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"${comment}\""
add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr" "$(REDIRECT)" "${comment}"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 $(REDIRECT) comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 return comment \"${comment}\""
}
nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr $FAKE_IP ${nft_j} comment \"${comment}\""
add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip daddr" "${nft_j}" "${comment}"
nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j} comment \"${comment}\""
[ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment}\""
[ "$PROXY_IPV6" == "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"${comment}\""
add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr" "${nft_j}" "${comment}"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW2_RULE comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(REDIRECT $REDIR_PORT TPROXY) comment \"${comment}\""
}
log 2 "${msg2}"
fi
if [ "$UDP_PROXY_MODE" != "disable" ] && [ -n "$NODE" ]; then
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "$(config_n_get $NODE remarks)")(TPROXY:${REDIR_PORT})"
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE comment \"${comment}\""
add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") ip daddr" "counter jump PSW2_RULE" "${comment}"
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment}\""
[ "$PROXY_IPV6" == "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"${comment}\""
add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr" "counter jump PSW2_RULE" "${comment}"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE comment \"${comment}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(REDIRECT $REDIR_PORT TPROXY) comment \"${comment}\""
}
log 2 "${msg2}"
udp_flag=1
fi
}
unset dns_redirect_port
unset $(cat "${TMP_ACL_PATH}/${sid}/var" | awk -F '=' '{print $1}' | tr "\n" " ")
done
}
filter_haproxy() {
@@ -746,9 +750,6 @@ add_firewall_rule() {
done
}
# Shunt rules IP list (import when use shunt node)
gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6
# Filter all node IPs
filter_vpsip > /dev/null 2>&1 &
filter_haproxy > /dev/null 2>&1 &
@@ -756,8 +757,8 @@ add_firewall_rule() {
filter_vps_addr $(config_n_get $NODE address) > /dev/null 2>&1 &
filter_vps_addr $(config_n_get $NODE download_address) > /dev/null 2>&1 &
accept_icmp=$(config_t_get global_forwarding accept_icmp 0)
accept_icmpv6=$(config_t_get global_forwarding accept_icmpv6 0)
accept_icmp=$(config_n_get @global_forwarding[0] accept_icmp 0)
accept_icmpv6=$(config_n_get @global_forwarding[0] accept_icmpv6 0)
if [ "${TCP_PROXY_WAY}" = "redirect" ]; then
unset is_tproxy
@@ -771,7 +772,7 @@ add_firewall_rule() {
nft "add chain $NFTABLE_NAME PSW2_DNS"
nft "flush chain $NFTABLE_NAME PSW2_DNS"
if [ $(config_t_get global dns_redirect "1") = "0" ]; then
if [ $(config_n_get @global[0] dns_redirect "1") = "0" ]; then
#Only hijack when dest address is local IP
nft "insert rule $NFTABLE_NAME dstnat ip saddr @${NFTSET_DIRECT} ip daddr @${NFTSET_LOCAL} jump PSW2_DNS"
nft "insert rule $NFTABLE_NAME dstnat ip6 saddr @${NFTSET_DIRECT6} ip6 daddr @${NFTSET_LOCAL6} jump PSW2_DNS"
@@ -881,128 +882,6 @@ add_firewall_rule() {
ip -6 route add local ::/0 dev lo table 999
}
[ "$ENABLED_DEFAULT_ACL" == 1 ] && {
TCP_LOCALHOST_PROXY=$LOCALHOST_PROXY
UDP_LOCALHOST_PROXY=$LOCALHOST_PROXY
msg="$(i18n "[Local],")"
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return"
if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then
log 1 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${TCP_NO_REDIR_PORTS}")"
else
unset TCP_LOCALHOST_PROXY
log 1 "${msg}$(i18n "not proxy all %s" "TCP")"
fi
}
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && {
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return"
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then
log 1 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")"
else
unset UDP_LOCALHOST_PROXY
log 1 "${msg}$(i18n "not proxy all %s" "UDP")"
fi
}
if [ -n "$NODE" ] && ([ "$TCP_LOCALHOST_PROXY" = "1" ] || [ "$UDP_LOCALHOST_PROXY" = "1" ]); then
[ -n "$DNS_REDIRECT_PORT" ] && {
nft "add rule $NFTABLE_NAME nat_output ip protocol udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW2_DNS\""
nft "add rule $NFTABLE_NAME nat_output ip protocol tcp oif lo tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW2_DNS\""
nft "add rule $NFTABLE_NAME nat_output meta l4proto udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW2_DNS\""
nft "add rule $NFTABLE_NAME nat_output meta l4proto tcp oif lo tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW2_DNS\""
}
fi
local comment_l="$(i18n "Local")"
# Loading local router proxy TCP
if [ -n "$NODE" ] && [ "$TCP_LOCALHOST_PROXY" = "1" ]; then
[ "$accept_icmp" = "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp ip daddr $FAKE_IP counter redirect"
add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp ip daddr" "counter redirect"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp counter redirect"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp counter return"
}
[ "$accept_icmpv6" = "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 counter redirect"
add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr" "counter redirect"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter redirect"
nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter return"
}
if [ -n "${is_tproxy}" ]; then
nft_chain="PSW2_OUTPUT_MANGLE"
nft_j="counter jump PSW2_RULE"
else
nft_chain="PSW2_OUTPUT_NAT"
nft_j="$(REDIRECT $REDIR_PORT)"
fi
nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr $FAKE_IP ${nft_j}"
add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip daddr" "${nft_j}"
nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j}"
[ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME nat_output ip daddr != @$NFTSET_DIRECT ip protocol tcp counter jump PSW2_OUTPUT_NAT"
[ -n "${is_tproxy}" ] && {
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo counter return comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME mangle_output ip daddr != @$NFTSET_DIRECT ip protocol tcp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\""
}
[ "$PROXY_IPV6" == "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE"
add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr" "counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo $(REDIRECT $REDIR_PORT TPROXY6) comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo counter return comment \"${comment_l}\""
}
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do
nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp oif $iface counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol tcp oif $iface counter return"
done
}
fi
# Loading local router proxy UDP
if [ -n "$NODE" ] && [ "$UDP_LOCALHOST_PROXY" = "1" ]; then
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE"
add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") ip daddr" "counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo counter return comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME mangle_output ip daddr != @$NFTSET_DIRECT ip protocol udp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\""
[ "$PROXY_IPV6" == "1" ] && {
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE"
add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr" "counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo $(REDIRECT $REDIR_PORT TPROXY6) comment \"${comment_l}\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo counter return comment \"${comment_l}\""
}
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do
nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol udp oif $iface counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol udp oif $iface counter return"
done
}
fi
nft "add rule $NFTABLE_NAME mangle_output ip daddr != @$NFTSET_DIRECT oif lo counter return comment \"PSW2_OUTPUT_MANGLE\""
nft "add rule $NFTABLE_NAME mangle_output ip daddr != @$NFTSET_DIRECT meta mark ${FWMARK} counter return comment \"PSW2_OUTPUT_MANGLE\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp tcp dport 53 counter accept"
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp udp dport 53 counter accept"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp tcp dport 53 counter accept"
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp udp dport 53 counter accept"
}
load_acl
filter_direct_node_list > /dev/null 2>&1 &
@@ -1093,7 +972,7 @@ start() {
stop() {
[ -z "$(command -v log_i18n)" ] && . "$UTILS_PATH"
del_firewall_rule
[ $(config_t_get global flush_set "0") = "1" ] && {
[ $(config_n_get @global[0] flush_set "0") = "1" ] && {
uci -q delete ${CONFIG}.@global[0].flush_set
uci -q commit ${CONFIG}
#flush_table
@@ -75,7 +75,7 @@ test_node() {
local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ -n "${_type}" ] && {
check_process
local _tmp_port=$(get_new_port 48800 tcp,udp)
local _tmp_port=$(get_new_port 48800)
NO_REC_PROCESS=1 $APP_FILE run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json
sleep 2s
local curlx="socks5h://127.0.0.1:${_tmp_port}"
@@ -29,7 +29,6 @@ local has_ss_rust = api.is_finded("sslocal")
local has_ssr = api.is_finded("ssr-local") and api.is_finded("ssr-redir")
local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria")
local DEFAULT_ALLOWINSECURE = true
local DEFAULT_FILTER_KEYWORD_MODE = uci_get("@global_subscribe[0]", "filter_keyword_mode") or "0"
local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci_get("@global_subscribe[0]", "filter_discard_list") or {}
@@ -39,12 +38,11 @@ local DEFAULT_SS_TYPE = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"
local DEFAULT_TROJAN_TYPE = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}})
local DEFAULT_VMESS_TYPE = api.get_core("vmess_type", {{has_xray,"xray"},{has_singbox,"sing-box"}})
local DEFAULT_VLESS_TYPE = api.get_core("vless_type", {{has_xray,"xray"},{has_singbox,"sing-box"}})
local DEFAULT_HYSTERIA2_TYPE = api.get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{has_singbox,"sing-box"},{has_xray,"xray"}})
local DEFAULT_HYSTERIA2_TYPE = api.get_core("hysteria2_type", {{has_singbox,"sing-box"},{has_xray,"xray"}})
local core_has = {
["xray"] = has_xray,
["sing-box"] = has_singbox,
["shadowsocks-rust"] = has_ss_rust,
["hysteria2"] = has_hysteria2
}
-- Determine whether to filter node keywords
local function is_filter_keyword(sub_cfg, value)
@@ -1771,15 +1769,6 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.protocol = "hysteria2"
result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil
result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil
elseif has_hysteria2 then
result.type = "Hysteria2"
for k1, v1 in pairs(result) do
if k1:find("hysteria2_") == 1 then
local s = split(k1, "hysteria2_")
result[s[2]] = v1
result[k1] = nil
end
end
else
log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "Hysteria2", "Hysteria2"))
return nil
@@ -17,8 +17,8 @@ do
if [ "$CFG_UPDATE_INT" -ne 0 ]; then
restart_week_mode=$(config_t_get global_delay restart_week_mode)
restart_interval_mode=$(config_t_get global_delay restart_interval_mode)
restart_week_mode=$(config_n_get @global_delay[0] restart_week_mode)
restart_interval_mode=$(config_n_get @global_delay[0] restart_interval_mode)
restart_interval_mode=$(expr "$restart_interval_mode" \* 60)
if [ -n "$restart_week_mode" ]; then
[ "$restart_week_mode" = "8" ] && {
@@ -26,8 +26,8 @@ do
}
fi
rules_update_week_mode=$(config_t_get global_rules update_week_mode)
rules_update_interval_mode=$(config_t_get global_rules update_interval_mode)
rules_update_week_mode=$(config_n_get @global_rules[0] update_week_mode)
rules_update_interval_mode=$(config_n_get @global_rules[0] update_interval_mode)
rules_update_interval_mode=$(expr "$rules_update_interval_mode" \* 60)
if [ -n "$rules_update_week_mode" ]; then
[ "$rules_update_week_mode" = "8" ] && {
@@ -46,11 +46,11 @@ url_test_node() {
local node_id=$1
local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ -n "${_type}" ] && {
local _tmp_port=$(get_new_port 48900 tcp,udp)
local _tmp_port=$(get_new_port 48900)
NO_REC_PROCESS=1 /usr/share/${CONFIG}/app.sh run_socks flag="url_test_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=url_test_${node_id}.json
sleep 2s
local curlx="socks5h://127.0.0.1:${_tmp_port}"
local probeUrl=$(config_t_get global_other url_test_url https://www.google.com/generate_204)
local probeUrl=$(config_n_get @global_other[0] url_test_url https://www.google.com/generate_204)
result=$(curl --connect-timeout 3 --max-time 5 -o /dev/null -I -skL -w "%{http_code}:%{time_pretransfer}" -x ${curlx} "${probeUrl}")
# End the SS plugin process
local pid_file="${TMP_PATH}/url_test_${node_id}_plugin.pid"
@@ -33,11 +33,6 @@ config_t_get() {
echo "${ret:=${3}}"
}
config_t_set() {
local index=${4:-0}
local ret=$(uci -q set "${CONFIG}.@${1}[${index}].${2}=${3}" 2>/dev/null)
}
eval_set_val() {
for i in $@; do
for j in $i; do
@@ -157,9 +152,9 @@ get_geoip() {
local geoip_type_flag=""
local output_path="${geo_output_path}/geoip-${geoip_code}-$2"
[ ! -s "${output_path}" ] && {
local geoip_path="$(config_t_get global_rules v2ray_location_asset)"
local geoip_path="$(config_n_get @global_rules[0] v2ray_location_asset)"
geoip_path="${geoip_path%*/}/geoip.dat"
local bin="$(first_type $(config_t_get global_app geoview_file) geoview)"
local bin="$(first_type $(config_n_get @global_app[0] geoview_file) geoview)"
[ -n "$bin" ] && [ -s "$geoip_path" ] || { echo ""; return; }
case "$2" in
"ipv4") geoip_type_flag="-ipv6=false" ;;
@@ -299,7 +294,7 @@ get_new_port() {
local default_start_port=2001
local min_port=1025
local max_port=49151
local port=$1
local port=$1 #Required parameter; please pass "auto" if you want it to be automatic.
local last_get_new_port_auto
if [ "$1" == "auto" ]; then
last_get_new_port_auto=$(get_cache_var "last_get_new_port_auto")
@@ -313,17 +308,28 @@ get_new_port() {
[ "$port" -lt $min_port -o "$port" -gt $max_port ] && port=$default_start_port
local protocol=$(echo $2 | tr 'A-Z' 'a-z')
local result=$(check_port_exists $port $protocol)
[ -n "$(get_cache_var "get_port_${port}")" ] && {
# exist, continue get.
# Make the following result logic true.
result=1
}
if [ "$result" != 0 ]; then
local temp=
if [ "$port" -lt $max_port ]; then
# If the port is smaller than the maximum port, then increment by 1 and continue.
temp=$(expr $port + 1)
elif [ "$port" -gt $min_port ]; then
# If the port is greater than the minimum port, then decrement by 1 and continue.
temp=$(expr $port - 1)
else
# Otherwise, reassign the default starting port.
temp=$default_start_port
fi
# Recursion, until it obtains an unused port.
get_new_port $temp $protocol
else
# Set cache, mark this port as already obtained, so it should not be obtained again.
set_cache_var "get_port_${port}" "1"
[ "$1" == "auto" ] && set_cache_var "last_get_new_port_auto" "$port"
echo $port
fi