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 = s:taboption("Main", Value, "node_socks_port", translate("Node") .. " Socks " .. translate("Listen Port"))
o.default = 1070 o.default = 1070
o.datatype = "port" o.datatype = "range(1,65535)"
o.rmempty = false
o:depends({ node = "", ["!reverse"] = true }) o:depends({ node = "", ["!reverse"] = true })
--[[ --[[
if has_singbox or has_xray then if has_singbox or has_xray then
@@ -727,7 +728,7 @@ end)
o = s2:option(Value, "port", "Socks " .. translate("Listen Port")) o = s2:option(Value, "port", "Socks " .. translate("Listen Port"))
o.default = n + 1080 o.default = n + 1080
o.datatype = "port" o.datatype = "range(1,65535)"
o.rmempty = false o.rmempty = false
--[[ --[[
@@ -46,8 +46,9 @@ o:depends("console_auth", true)
---- Console Port ---- 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 = 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.default = 1188
o.datatype = "range(1,65535)"
o.rmempty = false
o:depends("balancing_enable", true) 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.")) 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 ---- Haproxy Port
o = s:option(Value, "haproxy_port", translate("Haproxy Port")) o = s:option(Value, "haproxy_port", translate("Haproxy Port"))
o.datatype = "port"
o.default = 1181 o.default = 1181
o.datatype = "range(1,65535)"
o.rmempty = false o.rmempty = false
---- Node Weight ---- Node Weight
@@ -63,7 +63,7 @@ end)
o = s:option(Value, "port", "Socks " .. translate("Listen Port")) o = s:option(Value, "port", "Socks " .. translate("Listen Port"))
o.default = n + 1080 o.default = n + 1080
o.datatype = "port" o.datatype = "range(1,65535)"
o.rmempty = false o.rmempty = false
if has_singbox or has_xray then if has_singbox or has_xray then
@@ -1215,11 +1215,15 @@ table td, .table .td {
const set_node_div = { const set_node_div = {
section: '', section: '',
open(cbi_id) { open(cbi_id, protocol) {
this.section = cbi_id; this.section = cbi_id;
document.getElementById("set_node_div").style.display="block"; document.getElementById("set_node_div").style.display="block";
const node_name = document.getElementById("cbid.<%=appname%>." + cbi_id + ".remarks").value; const node_name = document.getElementById("cbid.<%=appname%>." + cbi_id + ".remarks").value;
document.getElementById("set_node_name").textContent = node_name; 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() { close() {
document.getElementById("set_node_div").style.display="none"; 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"> <td class="td cbi-section-table-cell nowrap cbi-section-actions pw-actions">
<div class="node-wrapper"> <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-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-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-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%>"> <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("{{remarks_val}}").join(o["remarks"]);
innerHTML = innerHTML.split("{{address_val}}").join(o["address"] || ""); innerHTML = innerHTML.split("{{address_val}}").join(o["address"] || "");
innerHTML = innerHTML.split("{{port_val}}").join(o["port"] || ""); innerHTML = innerHTML.split("{{port_val}}").join(o["port"] || "");
innerHTML = innerHTML.split("{{protocol}}").join(o["protocol"] || "");
node_tr_html += innerHTML 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 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 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> <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 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>
<div class="cbi-value" style="justify-content: center; gap: 8px; margin: 1em 0;"> <div class="cbi-value" style="justify-content: center; gap: 8px; margin: 0.2em 0;">
<%- if default_node_type == "_shunt" then <div style="margin: 0.5em 0; padding: 0.5em; background: #f7f7f7; border-radius: 4px;">
for i, v in ipairs(shunt_rule_list) do <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('<%=node%>', '<%=v[".name"]%>')" value="<%=v.remarks%>" /> <input class="btn cbi-button" type="button" onclick="set_node_div.set('@global[0]', 'node')" value="<%:OK%>" />
<%- </div>
end </div>
-%> <% if default_node_type == "_shunt" then %>
<% else %> <div id="set_node_shunt_div" style="margin: 0.5em 0; padding: 0.5em; background: #f7f7f7; border-radius: 4px;">
<input class="btn cbi-button" type="button" onclick="set_node_div.set('@global[0]', 'node')" value="<%:Node%>" /> <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 %> <% end %>
</div> </div>
</div> </div>
+6
View File
@@ -427,6 +427,12 @@ msgstr "你确定要删除选择的节点吗?"
msgid "You no select nodes !" msgid "You no select nodes !"
msgstr "你没有选择任何节点!" msgstr "你没有选择任何节点!"
msgid "Set as the main proxy node:"
msgstr "应用为主代理节点:"
msgid "Set as the routing rule node:"
msgstr "应用为分流规则节点:"
msgid "Are you sure set this node?" msgid "Are you sure set this node?"
msgstr "你确定要设置这个节点吗?" msgstr "你确定要设置这个节点吗?"
-6
View File
@@ -14,7 +14,6 @@ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy \ CONFIG_PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy \ 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_Client \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \
@@ -85,11 +84,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy
select PACKAGE_haproxy select PACKAGE_haproxy
default y if aarch64||arm||i386||x86_64 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 config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client
bool "Include Shadowsocks Rust Client" bool "Include Shadowsocks Rust Client"
depends on !i386 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_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_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_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, "get_log"}, call("get_log")).leaf = true
entry({"admin", "services", appname, "clear_log"}, call("clear_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 entry({"admin", "services", appname, "index_status"}, call("index_status")).leaf = true
@@ -248,10 +247,9 @@ end
function get_redir_log() function get_redir_log()
local id = http.formvalue("id") local id = http.formvalue("id")
local name = http.formvalue("name") local file_path = api.TMP_PATH .. "/acl/" .. id .. ".log"
local file_path = api.TMP_PATH .. "/acl/" .. id .. "/" .. name .. ".log"
if nixio.fs.access(file_path) then 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 />") content = content:gsub("\n", "<br />")
http.write(content) http.write(content)
else else
@@ -271,18 +269,6 @@ function get_socks_log()
end end
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() 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") -- 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")) http.write(luci.sys.exec("[ -f '/tmp/log/passwall2.log' ] && cat /tmp/log/passwall2.log"))
@@ -294,7 +280,7 @@ end
function index_status() function index_status()
local e = {} 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) http_write_json(e)
end end
@@ -50,20 +50,11 @@ end
o = s:option(DummyValue, "sources", translate("Source")) o = s:option(DummyValue, "sources", translate("Source"))
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(self, section)
local e = '' local v = self.map:get(section, self.option) or {}
local v = Value.cfgvalue(t, n) or '-' if type(v) == "table" then
string.gsub(v, '[^' .. " " .. ']+', function(w) return table.concat(v, "<br/>")
local a = w end
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
end end
i = s:option(DummyValue, "mode", translate("Mode")) i = s:option(DummyValue, "mode", translate("Mode"))
@@ -71,6 +62,8 @@ i.cfgvalue = function(t, n)
local v = Value.cfgvalue(t, n) or '0' local v = Value.cfgvalue(t, n) or '0'
if v == "1" then if v == "1" then
return translate("Proxy") return translate("Proxy")
elseif v == "2" then
return translate("Proxy") .. " " .. translate("Use global config")
end end
return translate("No Proxy") return translate("No Proxy")
end 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("IP range") .. ": 192.168.1.100-192.168.1.200"
.. "</li><li>" .. translate("IPSet") .. ": ipset:lanlist" .. "</li><li>" .. translate("IPSet") .. ": ipset:lanlist"
.. "</li></ul>" .. "</li></ul>"
sources.cast = "string"
for _, key in pairs(mac_t) do for _, key in pairs(mac_t) do
sources:value(key.mac, "%s (%s)" % {key.mac, key.ip}) sources:value(key.mac, "%s (%s)" % {key.mac, key.ip})
end 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) sources.validate = function(self, value, t)
local err = {} local err = {}
for _, v in ipairs(value) do for _, v in ipairs(value) do
@@ -155,47 +139,75 @@ sources.validate = function(self, value, t)
return value return value
end end
local NODE = m:get("@global[0]", "node")
o = s:option(ListValue, "mode", translate("Mode")) o = s:option(ListValue, "mode", translate("Mode"))
o:value("0", translate("No Proxy")) o:value("0", translate("No Proxy"))
o:value("1", translate("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 = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports"))
o:value("", translate("Use global config") .. "(" .. TCP_NO_REDIR_PORTS .. ")") o:value("", translate("No patterns are used"))
o:value("disable", translate("No patterns are used"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o:depends("mode", "1") o:depends("mode", "1")
o:depends("mode", "2")
o.validate = port_validate 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 = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"))
o:value("", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")") o:value("", translate("No patterns are used"))
o:value("disable", translate("No patterns are used"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o:depends("mode", "1") o:depends("mode", "1")
o:depends("mode", "2")
o.validate = port_validate 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.template = m:template_path("/cbi/hidevalue")
o.value = "1" o.value = "1"
o:depends("mode", "0") o:depends("mode", "0")
o:depends({ tcp_no_redir_ports = "1:65535", udp_no_redir_ports = "1:65535" }) 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") o = s:option(DummyValue, "_show_node_option", "")
local NODE = m:get("@global[0]", "node") 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>") o = s:option(ListValue, "node", "<a style='color: red'>" .. translate("Node") .. "</a>")
if GLOBAL_ENABLED == "1" and NODE then o.group = {}
o:value("", translate("Use global config") .. "(" .. api.get_node_name(NODE) .. ")") o:depends("_show_node_option", "1")
o.group = {""}
else
o.group = {}
end
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
o.template = m:template_path("/cbi/nodes_listvalue") o.template = m:template_path("/cbi/nodes_listvalue")
current_node_id = o:formvalue(arg[1]) current_node_id = o:formvalue(arg[1])
@@ -204,9 +216,14 @@ if not current_node_id then
end end
current_node = current_node_id and m:get(current_node_id) or {} 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: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 = s:option(ListValue, "loglevel", translate("Log Level"))
o.default = "warn" o.default = "warn"
o:value("debug", "Debug") o:value("debug", "Debug")
@@ -218,8 +235,8 @@ o:depends("log", "1")
o = s:option(DummyValue, "_acl_log", translate("Log File")) o = s:option(DummyValue, "_acl_log", translate("Log File"))
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(t, n)
local log_path = api.TMP_PATH .. "/acl/" .. arg[1] .. "/node.log" local log_path = api.TMP_PATH .. "/acl/" .. arg[1] .. ".log"
local log_url = api.url("get_acl_log") .. "?id=" .. arg[1] local log_url = api.url("get_redir_log") .. "?id=" .. arg[1]
return string.format( 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\')" />', '<code>%s</code>&nbsp;&nbsp;<input class="btn cbi-button cbi-button-apply" type="button" value="%s" onclick="window.open(\'%s\', \'_blank\')" />',
log_path, log_path,
@@ -229,46 +246,17 @@ o.cfgvalue = function(t, n)
end end
o:depends("log", "1") o:depends("log", "1")
---- TCP Redir Ports o = s:option(DummyValue, "_show_dns_option", "")
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.template = m:template_path("/cbi/hidevalue") o.template = m:template_path("/cbi/hidevalue")
o.value = "1" o.value = "1"
o:depends({ node = "" }) o:depends("_hide", "1")
if GLOBAL_ENABLED == "1" and NODE then
o:depends({ node = NODE })
end
o = s:option(ListValue, "direct_dns_query_strategy", translate("Direct Query Strategy")) o = s:option(ListValue, "direct_dns_query_strategy", translate("Direct Query Strategy"))
o.default = "UseIP" o.default = "UseIP"
o:value("UseIP") o:value("UseIP")
o:value("UseIPv4") o:value("UseIPv4")
o:value("UseIPv6") 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 = s:option(ListValue, "remote_dns_protocol", translate("Remote DNS Protocol"))
o:value("tcp", "TCP") o:value("tcp", "TCP")
@@ -279,7 +267,7 @@ if current_node.type == "sing-box" then
o:value("quic", "QUIC(DoQ)") o:value("quic", "QUIC(DoQ)")
o:value("http3", "HTTP3(DoH3)") o:value("http3", "HTTP3(DoH3)")
end 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) ---- DNS over TCP or UDP or TLS (DoT) or QUIC (DoQ)
o = s:option(Value, "remote_dns", translate("Remote DNS")) 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 = s:option(Value, "remote_rewrite_ttl", translate("Remote DNS") .. " TTL")
o.datatype = "min(1)" o.datatype = "min(1)"
o.default = "30" o.default = "30"
o:depends("_hide", "1")
o = s:option(ListValue, "dns_hosts_mode", translate("Domain Override")) o = s:option(ListValue, "dns_hosts_mode", translate("Domain Override"))
o:value("default", translate("Use global config")) o:value("default", translate("Use global config"))
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("custom", translate("-- custom --")) 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 = s:option(TextValue, "dns_hosts", translate("Domain Override"))
o.rows = 5 o.rows = 5
@@ -385,6 +374,7 @@ for k, v in pairs(nodes_table) do
if v.type == "sing-box" then if v.type == "sing-box" then
s.fields["remote_rewrite_ttl"]:depends({ node = v.id }) s.fields["remote_rewrite_ttl"]:depends({ node = v.id })
end 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 if v.node_type == "normal" or v.protocol == "_balancing" or v.protocol == "_urltest" then
--Shunt node has its own separate options. --Shunt node has its own separate options.
s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "tcp" }) 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 = s:taboption("log", DummyValue, "_log", translate("Log File"))
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(t, n)
local log_path = api.TMP_PATH .. "/acl/default/global.log" local log_path = api.TMP_PATH .. "/acl/default.log"
local log_url = api.url("get_redir_log") .. "?id=default&name=global" local log_url = api.url("get_redir_log") .. "?id=default"
return string.format( 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\')" />', '<code>%s</code>&nbsp;&nbsp;<input class="btn cbi-button cbi-button-apply" type="button" value="%s" onclick="window.open(\'%s\', \'_blank\')" />',
log_path, log_path,
@@ -4,7 +4,6 @@ api.set_default_cbi()
local has_ss_rust = api.is_finded("sslocal") local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box") local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray") local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria")
local ss_type = {} local ss_type = {}
local trojan_type = {} local trojan_type = {}
local vmess_type = {} local vmess_type = {}
@@ -33,10 +32,6 @@ if has_xray then
table.insert(hysteria2_type, s) table.insert(hysteria2_type, s)
end end
end end
if has_hysteria2 then
local s = "hysteria2"
table.insert(hysteria2_type, s)
end
m = Map() m = Map()
@@ -17,7 +17,6 @@ m:appendTemplate("/cbi/nodes_listvalue_com")
local has_ss_rust = api.is_finded("sslocal") local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box") local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray") local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria")
local ss_type = {} local ss_type = {}
local trojan_type = {} local trojan_type = {}
local vmess_type = {} local vmess_type = {}
@@ -46,10 +45,6 @@ if has_xray then
table.insert(hysteria2_type, s) table.insert(hysteria2_type, s)
end end
end end
if has_hysteria2 then
local s = "hysteria2"
table.insert(hysteria2_type, s)
end
local nodes_table = {} local nodes_table = {}
for k, e in ipairs(api.get_valid_nodes()) do for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" then if e.node_type == "normal" then
@@ -72,8 +72,7 @@ s = m:section(NamedSection, "@global_forwarding[0]", "global_forwarding", transl
---- TCP No Redir Ports ---- TCP No Redir Ports
o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports")) o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports"))
o.default = "disable" o:value("", translate("No patterns are used"))
o:value("disable", translate("No patterns are used"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o.validate = port_validate o.validate = port_validate
@@ -82,23 +81,22 @@ o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
"<font color='red'>" .. "<font color='red'>" ..
translate("Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") .. translate("Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
"</font>") "</font>")
o.default = "disable" o:value("", translate("No patterns are used"))
o:value("disable", translate("No patterns are used"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o.validate = port_validate o.validate = port_validate
---- TCP Redir Ports ---- TCP Redir Ports
o = s:option(Value, "tcp_redir_ports", translate("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("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("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:value("80,443", translate("Only Web"))
o.default = o.keylist[1]
o.validate = port_validate o.validate = port_validate
---- UDP Redir Ports ---- UDP Redir Ports
o = s:option(Value, "udp_redir_ports", translate("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:value("1:65535", translate("All"))
o.default = o.keylist[1]
o.validate = port_validate o.validate = port_validate
o = s:option(DummyValue, "tips", " ") 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" CACHE_PATH = TMP_PATH .. "_tmp"
S_TMP_PATH = "/tmp/etc/" .. s_config S_TMP_PATH = "/tmp/etc/" .. s_config
TMP_IFACE_PATH = TMP_PATH .. "/iface" TMP_IFACE_PATH = TMP_PATH .. "/iface"
TMP_ACL_PATH = TMP_PATH .. "/acl"
local lang = uci:get("luci", "main", "lang") or "auto" local lang = uci:get("luci", "main", "lang") or "auto"
if lang == "auto" then if lang == "auto" then
@@ -201,9 +202,10 @@ function get_cache_var(key)
return val return val
end 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)" 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 end
function exec_call(cmd) function exec_call(cmd)
@@ -613,7 +615,7 @@ function get_valid_nodes()
end end
end end
local port = e.port or e.hysteria_hop or e.hysteria2_hop 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 if (port and e.address) or is_realm then
local address = e.address local address = e.address
if is_ip(address) or datatypes.hostname(address) or is_realm then if is_ip(address) or datatypes.hostname(address) or is_realm then
@@ -739,7 +741,7 @@ function get_node_remarks(n)
end end
type_name = type_name .. " " .. protocol type_name = type_name .. " " .. protocol
end 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" type_name = type_name .. " Realm"
end end
remarks = trim("%s:[%s]" % {type_name, n.remarks}) 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" return "https://github.com/Openwrt-Passwall/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-pre-release-api.json"
end 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"] = { _M["sing-box"] = {
name = "Sing-Box", name = "Sing-Box",
repo = "SagerNet/sing-box", repo = "SagerNet/sing-box",
@@ -169,13 +169,6 @@ local function start()
config = require(require_dir .. "util_sing-box").gen_config_server(server) config = require(require_dir .. "util_sing-box").gen_config_server(server)
end end
bin = ln_run(api.get_app_path("sing-box"), "sing-box", "run -c " .. config_file, log_path) 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 end
if next(config) then 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$/); const m = cbid.match(/\.node$/);
if (m) { 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>' 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_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box") local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray") 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 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 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 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 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) local current_node = map:get(section)
-%> -%>
@@ -21,7 +20,6 @@ local current_node = map:get(section)
<script type="text/javascript">//<![CDATA[ <script type="text/javascript">//<![CDATA[
let has_singbox = "<%=has_singbox%>" let has_singbox = "<%=has_singbox%>"
let has_xray = "<%=has_xray%>" let has_xray = "<%=has_xray%>"
let has_hysteria2 = "<%=has_hysteria2%>"
let ss_type = "<%=ss_type%>" let ss_type = "<%=ss_type%>"
let trojan_type = "<%=trojan_type%>" let trojan_type = "<%=trojan_type%>"
let vmess_type = "<%=vmess_type%>" let vmess_type = "<%=vmess_type%>"
@@ -585,7 +583,7 @@ local current_node = map:get(section)
params = params.substring(1); params = params.substring(1);
} }
url += params; 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" protocol = "hysteria2"
var v_port = opt.get(dom_prefix + "port"); var v_port = opt.get(dom_prefix + "port");
var params = ""; var params = "";
@@ -595,36 +593,20 @@ local current_node = map:get(section)
params += opt.query("pcs", dom_prefix + "tls_pinSHA256"); params += opt.query("pcs", dom_prefix + "tls_pinSHA256");
params += opt.query("vcn", dom_prefix + "tls_CertByName"); params += opt.query("vcn", dom_prefix + "tls_CertByName");
var v_password = null; var v_password = opt.get(dom_prefix + "hysteria2_auth_password");
var dom_obfs_type = opt.get(dom_prefix + "hysteria2_obfs_type");
if (v_type === "Hysteria2") { if (dom_obfs_type && dom_obfs_type.value != "") {
v_password = opt.get("hysteria2_auth_password"); params += opt.query("obfs", dom_prefix + "hysteria2_obfs_type");
var dom_obfs_type = opt.get("hysteria2_obfs_type"); params += opt.query("obfs-password", dom_prefix + "hysteria2_obfs_password");
if (dom_obfs_type && dom_obfs_type.value != "") { if (dom_obfs_type.value === "gecko") {
params += opt.query("obfs", "hysteria2_obfs_type"); params += opt.query("minPacketSize", dom_prefix + "hysteria2_obfs_MinPacketSize");
params += opt.query("obfs-password", "hysteria2_obfs_password"); params += opt.query("maxPacketSize", dom_prefix + "hysteria2_obfs_MaxPacketSize");
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");
} }
} }
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(/^&/, ""); params = params.replace(/^&/, "");
url = url =
_address + ":" + _address + ":" +
@@ -1640,19 +1622,6 @@ local current_node = map:get(section)
opt.set(dom_prefix + 'hysteria2_hop', queryParam.mport || ""); opt.set(dom_prefix + 'hysteria2_hop', queryParam.mport || "");
opt.set(dom_prefix + 'use_finalmask', !!queryParam.fm); opt.set(dom_prefix + 'use_finalmask', !!queryParam.fm);
opt.set(dom_prefix + '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)); opt.set(dom_prefix + 'address', unbracketIP(m.hostname));
@@ -329,15 +329,19 @@ table td, .table .td {
var shunt_rule_list = result var shunt_rule_list = result
var group_shunt_rules = {} var group_shunt_rules = {}
for (let i = 0; i < shunt_rule_list.length; i++) { if (shunt_rule_list.length > 0) {
let _shunt_rule = shunt_rule_list[i] for (let i = 0; i < shunt_rule_list.length; i++) {
if (!_shunt_rule.group || _shunt_rule.group === "") { let _shunt_rule = shunt_rule_list[i]
_shunt_rule.group = "default" 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]) { } else {
group_shunt_rules[_shunt_rule.group] = [] group_shunt_rules["default"] = [];
}
group_shunt_rules[_shunt_rule.group].push(_shunt_rule)
} }
var tab_ul_li_html = ''; var tab_ul_li_html = '';
+2 -2
View File
@@ -2147,8 +2147,8 @@ msgstr "پروکسی نکردن همه %s"
msgid "Use the %s node [%s]" msgid "Use the %s node [%s]"
msgstr "استفاده از گره %s [%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." msgid "DNS will redirected to the dedicated DNS server [%s]."
msgstr "استفاده از گره‌ای متفاوت از پیکربندی سراسری، DNS به اجبار به سرور DNS اختصاصی هدایت شده است." msgstr "DNS به سرور DNS اختصاصی [%s] هدایت خواهد شد."
msgid "Add direct DNS to %s: %s" msgid "Add direct DNS to %s: %s"
msgstr "افزودن DNS مستقیم به %s: %s" msgstr "افزودن DNS مستقیم به %s: %s"
+2 -2
View File
@@ -2148,8 +2148,8 @@ msgstr "не прокси все %s"
msgid "Use the %s node [%s]" msgid "Use the %s node [%s]"
msgstr "Использовать %s сервер [%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." msgid "DNS will redirected to the dedicated DNS server [%s]."
msgstr "Используется сервер, отличный от глобальной настройки: DNS принудительно перенаправлен на выделенный DNS-сервер." msgstr "DNS будет перенаправлен на выделенный DNS-сервер [%s]."
msgid "Add direct DNS to %s: %s" msgid "Add direct DNS to %s: %s"
msgstr "Добавление прямого DNS в %s: %s" msgstr "Добавление прямого DNS в %s: %s"
+2 -2
View File
@@ -2133,8 +2133,8 @@ msgstr "不代理所有 %s"
msgid "Use the %s node [%s]" msgid "Use the %s node [%s]"
msgstr "使用 %s 节点[%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." msgid "DNS will redirected to the dedicated DNS server [%s]."
msgstr "使用与全局配置不相同节点,已将DNS强制重定向到专用 DNS 服务器。" msgstr "DNS 将重定向到专用 DNS 服务器 [%s]。"
msgid "Add direct DNS to %s: %s" msgid "Add direct DNS to %s: %s"
msgstr "追加直连 DNS 到 %s: %s" msgstr "追加直连 DNS 到 %s: %s"
+2 -2
View File
@@ -2139,8 +2139,8 @@ msgstr "不代理所有 %s"
msgid "Use the %s node [%s]" msgid "Use the %s node [%s]"
msgstr "使用 %s 節點[%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." msgid "DNS will redirected to the dedicated DNS server [%s]."
msgstr "使用与全局配置不相同節點,已將DNS強制重定向到專用 DNS 服務器。" msgstr "DNS 將重定向到專用 DNS 服務器 [%s]。"
msgid "Add direct DNS to %s: %s" msgid "Add direct DNS to %s: %s"
msgstr "追加直連 DNS 到 %s: %s" msgstr "追加直連 DNS 到 %s: %s"
@@ -30,45 +30,10 @@ else
fi fi
uci commit firewall uci commit firewall
[ ! -s "/etc/config/passwall2" ] && cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2 [ ! -s "/etc/config/passwall2" ] && cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2
chmod +x /usr/share/passwall2/*.sh 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 -f /tmp/luci-indexcache /tmp/luci-indexcache.*
rm -rf /tmp/luci-modulecache/ rm -rf /tmp/luci-modulecache/
killall -HUP rpcd 2>/dev/null killall -HUP rpcd 2>/dev/null
@@ -25,8 +25,6 @@ config global_delay
option start_delay '60' option start_delay '60'
config global_forwarding config global_forwarding
option tcp_no_redir_ports 'disable'
option udp_no_redir_ports 'disable'
option tcp_redir_ports '1:65535' option tcp_redir_ports '1:65535'
option udp_redir_ports '1:65535' option udp_redir_ports '1:65535'
option accept_icmp '0' option accept_icmp '0'
@@ -45,13 +43,12 @@ config global_rules
option geosite_update '1' option geosite_update '1'
option geoip_update '1' option geoip_update '1'
option v2ray_location_asset '/usr/share/v2ray/' 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' option geosite_url 'https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat'
config global_app config global_app
option geoview_file '/usr/bin/geoview' option geoview_file '/usr/bin/geoview'
option xray_file '/usr/bin/xray' option xray_file '/usr/bin/xray'
option hysteria_file '/usr/bin/hysteria'
option sing_box_file '/usr/bin/sing-box' option sing_box_file '/usr/bin/sing-box'
config global_subscribe config global_subscribe
+115 -375
View File
@@ -7,17 +7,15 @@
. /usr/share/libubox/jshn.sh . /usr/share/libubox/jshn.sh
. /usr/share/passwall2/utils.sh . /usr/share/passwall2/utils.sh
GLOBAL_ACL_PATH=${TMP_ACL_PATH}/default
LUA_UTIL_PATH=/usr/lib/lua/luci/passwall2 LUA_UTIL_PATH=/usr/lib/lua/luci/passwall2
UTIL_SINGBOX=$LUA_UTIL_PATH/util_sing-box.lua UTIL_SINGBOX=$LUA_UTIL_PATH/util_sing-box.lua
UTIL_SS=$LUA_UTIL_PATH/util_shadowsocks.lua UTIL_SS=$LUA_UTIL_PATH/util_shadowsocks.lua
UTIL_XRAY=$LUA_UTIL_PATH/util_xray.lua UTIL_XRAY=$LUA_UTIL_PATH/util_xray.lua
UTIL_HYSTERIA2=$LUA_UTIL_PATH/util_hysteria2.lua SINGBOX_BIN=$(first_type $(config_n_get @global_app[0] sing_box_file) sing-box)
SINGBOX_BIN=$(first_type $(config_t_get global_app sing_box_file) sing-box) XRAY_BIN=$(first_type $(config_n_get @global_app[0] xray_file) xray)
XRAY_BIN=$(first_type $(config_t_get global_app xray_file) xray)
check_run_environment() { 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_info=$(dnsmasq -v 2>/dev/null)
local dnsmasq_ver=$(echo "$dnsmasq_info" | sed -n '1s/.*version \([0-9.]*\).*/\1/p') 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") # local dnsmasq_opts=$(echo "$dnsmasq_info" | grep -i "Compile time options")
@@ -70,13 +68,13 @@ check_run_environment() {
} }
run_xray() { 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 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 local loglevel log_file config_file
eval_set_val $@ eval_set_val $@
node_protocol=$(config_n_get $node protocol) node_protocol=$(config_n_get $node protocol)
[ -n "$log_file" ] || local log_file="/dev/null" [ -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_init
json_add_string "loglevel" "${loglevel}" json_add_string "loglevel" "${loglevel}"
@@ -106,9 +104,8 @@ run_xray() {
[ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}" [ -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) [ "${node_protocol}" = "_shunt" ] && local write_ipset_direct=$(config_n_get $node write_ipset_direct 0)
[ "${write_ipset_direct}" = "1" ] && { [ "${write_ipset_direct}" = "1" ] && {
direct_dnsmasq_listen_port=$(get_new_port $(expr $dns_listen_port + 1) udp) direct_dnsmasq_listen_port=$(get_new_port auto)
local direct_ipset_conf=${GLOBAL_ACL_PATH}/dns_${flag}_direct.conf local direct_ipset_conf=${TMP_ACL_PATH}/dns_${flag}_direct.conf
[ -n "$(echo ${flag} | grep '^acl')" ] && direct_ipset_conf=${TMP_ACL_PATH}/${sid}/dns_${flag}_direct.conf
if [ "${nftflag}" = "1" ]; then if [ "${nftflag}" = "1" ]; then
local direct_nftset4="psw2_${node}_white" local direct_nftset4="psw2_${node}_white"
local direct_nftset6="psw2_${node}_white6" local direct_nftset6="psw2_${node}_white6"
@@ -178,7 +175,7 @@ run_xray() {
[ -n "${redir_port}" ] && { [ -n "${redir_port}" ] && {
json_add_string "redir_port" "${redir_port}" json_add_string "redir_port" "${redir_port}"
set_cache_var "node_${node}_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}" json_add_string "node" "${node}"
@@ -199,7 +196,7 @@ run_xray() {
} }
run_singbox() { 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 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 local loglevel log_file config_file
eval_set_val $@ eval_set_val $@
@@ -207,7 +204,7 @@ run_singbox() {
[ -z "$type" ] && return 1 [ -z "$type" ] && return 1
node_protocol=$(config_n_get $node protocol) node_protocol=$(config_n_get $node protocol)
[ -n "$log_file" ] || local log_file="/dev/null" [ -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}') local singbox_tag=$($SINGBOX_BIN version | grep 'Tags:' | awk '{print $2}')
json_init json_init
@@ -244,9 +241,8 @@ run_singbox() {
[ -n "$dns_listen_port" ] && { [ -n "$dns_listen_port" ] && {
[ "${node_protocol}" = "_shunt" ] && local write_ipset_direct=$(config_n_get $node write_ipset_direct 0) [ "${node_protocol}" = "_shunt" ] && local write_ipset_direct=$(config_n_get $node write_ipset_direct 0)
[ "${write_ipset_direct}" = "1" ] && { [ "${write_ipset_direct}" = "1" ] && {
direct_dnsmasq_listen_port=$(get_new_port $(expr $dns_listen_port + 1) udp) direct_dnsmasq_listen_port=$(get_new_port auto)
local direct_ipset_conf=${GLOBAL_ACL_PATH}/dns_${flag}_direct.conf local direct_ipset_conf=${TMP_ACL_PATH}/dns_${flag}_direct.conf
[ -n "$(echo ${flag} | grep '^acl')" ] && direct_ipset_conf=${TMP_ACL_PATH}/${sid}/dns_${flag}_direct.conf
if [ "${nftflag}" = "1" ]; then if [ "${nftflag}" = "1" ]; then
local direct_nftset4="psw2_${node}_white" local direct_nftset4="psw2_${node}_white"
local direct_nftset6="psw2_${node}_white6" local direct_nftset6="psw2_${node}_white6"
@@ -325,7 +321,7 @@ run_singbox() {
[ -n "${redir_port}" ] && { [ -n "${redir_port}" ] && {
json_add_string "redir_port" "${redir_port}" json_add_string "redir_port" "${redir_port}"
set_cache_var "node_${node}_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}" json_add_string "node" "${node}"
@@ -411,7 +407,7 @@ run_socks() {
json_add_null "server_port" json_add_null "server_port"
} }
[ "${log_file}" != "/dev/null" ] && { [ "${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 "log" "1"
json_add_string "loglevel" "${loglevel}" json_add_string "loglevel" "${loglevel}"
json_add_string "logfile" "${log_file}" json_add_string "logfile" "${log_file}"
@@ -439,7 +435,7 @@ run_socks() {
json_add_null "server_port" json_add_null "server_port"
} }
[ "${log_file}" != "/dev/null" ] && { [ "${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 "log" "1"
json_add_string "loglevel" "${loglevel}" json_add_string "loglevel" "${loglevel}"
} }
@@ -478,19 +474,6 @@ run_socks() {
lua $UTIL_SS gen_config "${_json_arg}" > $config_file 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 [ -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 esac
# http to socks # 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() { start_socks() {
[ "$SOCKS_ENABLED" = "1" ] && { [ "$SOCKS_ENABLED" = "1" ] && {
local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
@@ -746,7 +589,7 @@ clean_crontab() {
start_crontab() { start_crontab() {
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then 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 & } [ "$start_daemon" = "1" ] && { $APP_PATH/monitor.sh > /dev/null 2>&1 & }
fi fi
@@ -763,8 +606,8 @@ start_crontab() {
return return
} }
stop_week_mode=$(config_t_get global_delay stop_week_mode) stop_week_mode=$(config_n_get @global_delay[0] stop_week_mode)
stop_time_mode=$(config_t_get global_delay stop_time_mode) stop_time_mode=$(config_n_get @global_delay[0] stop_time_mode)
if [ -n "$stop_week_mode" ]; then if [ -n "$stop_week_mode" ]; then
stop_time_hh=$(echo $stop_time_mode | awk -F ':' '{print $1}') stop_time_hh=$(echo $stop_time_mode | awk -F ':' '{print $1}')
stop_time_mm=$(echo $stop_time_mode | awk -F ':' '{print $2}') 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." log_i18n 0 "Scheduled tasks: Auto stop service."
fi fi
start_week_mode=$(config_t_get global_delay start_week_mode) start_week_mode=$(config_n_get @global_delay[0] start_week_mode)
start_time_mode=$(config_t_get global_delay start_time_mode) start_time_mode=$(config_n_get @global_delay[0] start_time_mode)
if [ -n "$start_week_mode" ]; then if [ -n "$start_week_mode" ]; then
start_time_hh=$(echo $start_time_mode | awk -F ':' '{print $1}') start_time_hh=$(echo $start_time_mode | awk -F ':' '{print $1}')
start_time_mm=$(echo $start_time_mode | awk -F ':' '{print $2}') 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." log_i18n 0 "Scheduled tasks: Auto start service."
fi fi
restart_week_mode=$(config_t_get global_delay restart_week_mode) restart_week_mode=$(config_n_get @global_delay[0] restart_week_mode)
restart_time_mode=$(config_t_get global_delay restart_time_mode) restart_time_mode=$(config_n_get @global_delay[0] restart_time_mode)
if [ -n "$restart_week_mode" ]; then if [ -n "$restart_week_mode" ]; then
restart_time_hh=$(echo $restart_time_mode | awk -F ':' '{print $1}') restart_time_hh=$(echo $restart_time_mode | awk -F ':' '{print $1}')
restart_time_mm=$(echo $restart_time_mode | awk -F ':' '{print $2}') 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." log_i18n 0 "Scheduled tasks: Auto restart service."
fi fi
rules_update_week_mode=$(config_t_get global_rules update_week_mode) rules_update_week_mode=$(config_n_get @global_rules[0] update_week_mode)
rules_update_time_mode=$(config_t_get global_rules update_time_mode) rules_update_time_mode=$(config_n_get @global_rules[0] update_time_mode)
if [ -n "$rules_update_week_mode" ]; then if [ -n "$rules_update_week_mode" ]; then
rules_update_time_hh=$(echo $rules_update_time_mode | awk -F ':' '{print $1}') 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}') rules_update_time_mm=$(echo $rules_update_time_mode | awk -F ':' '{print $2}')
@@ -865,7 +708,7 @@ stop_crontab() {
} }
start_haproxy() { 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_path=$TMP_PATH/haproxy
haproxy_conf="config.cfg" haproxy_conf="config.cfg"
lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf} lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf}
@@ -875,8 +718,9 @@ start_haproxy() {
run_copy_dnsmasq() { run_copy_dnsmasq() {
local flag listen_port local_dns tun_dns default_dns local flag listen_port local_dns tun_dns default_dns
eval_set_val $@ eval_set_val $@
local dnsmasq_conf=$TMP_ACL_PATH/$flag/dnsmasq.conf local dnsmasq_conf="${TMP_ACL_PATH}/${flag}_dnsmasq.conf"
local dnsmasq_conf_path=$TMP_ACL_PATH/$flag/dnsmasq.d local dnsmasq_conf_path="${TMP_ACL_PATH}/${flag}_dnsmasq.d"
local dnsmasq_pid="${TMP_ACL_PATH}/${flag}_dnsmasq.pid"
mkdir -p $dnsmasq_conf_path mkdir -p $dnsmasq_conf_path
json_init json_init
@@ -895,7 +739,7 @@ run_copy_dnsmasq() {
json_add_string "NO_LOGIC_LOG" "${NO_LOGIC_LOG:-0}" json_add_string "NO_LOGIC_LOG" "${NO_LOGIC_LOG:-0}"
lua $APP_PATH/helper_dnsmasq.lua add_rule "$(json_dump)" 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}" 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 ln_run 0 "$(first_type dnsmasq)" "dnsmasq" "/dev/null" -C $config_file
} }
acl_app() { acl_node() {
local items=$(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1) local run_func
if [ -z "$items" ]; then [ -n "${XRAY_BIN}" ] && run_func="run_xray"
ENABLED_ACLS=0 [ -n "${SINGBOX_BIN}" ] && run_func="run_singbox"
return local acl_node_num=0
else for nid in $(jsonfilter -s "${acl_json}" -e '$.node_order[*]'); do
local has_enabled [ ! -f ${TMP_ACL_PATH}/acl_node_${nid} ] && continue
local index=0 acl_node_num=$(expr $acl_node_num + 1)
local sid local _var=$(cat ${TMP_ACL_PATH}/acl_node_${nid} 2>/dev/null)
local redir_port dns_port dnsmasq_port socks_port eval local ${_var}
local ipt_tmp msg msg2 local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
redir_port=11200 [ -n "${type}" ] || continue
socks_port=11600 if [ "${type}" = "xray" ] && [ -n "${XRAY_BIN}" ]; then
dns_port=11300 run_func="run_xray"
dnsmasq_port=${GLOBAL_DNSMASQ_PORT:-11400} elif [ "${type}" = "sing-box" ] && [ -n "${SINGBOX_BIN}" ]; then
for sid in $items; do run_func="run_singbox"
index=$(expr $index + 1) fi
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 ${run_func} ${_var}
local _ip _mac _iprange _ipset _ip_or_mac source_list config_file local status=$?
[ "$(config_n_get $sid enabled)" = "1" ] || continue if [ "$status" != 0 ]; then
has_enabled=1 log_i18n 2 "[%s] process %s error, skip this transparent proxy!" "${node}" "${config_file}"
eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-) 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 json_init
for s in $sources; do json_add_string "LOG" "1"
local s2 lua $APP_PATH/helper_dnsmasq.lua logic_restart "$(json_dump)"
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
else 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 fi
else
local acl_path=${TMP_ACL_PATH}/$sid dnsmasq_port=$(get_new_port auto)
mkdir -p ${acl_path} 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}"
[ -n "${source_list}" ] && echo -e "${source_list}" | sed '/^$/d' > ${acl_path}/source_list #dhcp.leases to hostsMore actions
$APP_PATH/lease2hosts.sh > /dev/null 2>&1 &
log=${log:-0} fi
loglevel=${loglevel:-warn} rm -f ${TMP_ACL_PATH}/acl_node_${nid}
log_file="/dev/null" done
[ "${log}" = "1" ] && log_file="${acl_path}/node.log" [ ! -f ${TMP_ACL_PATH}/acl_node_default ] && ENABLED_DEFAULT_ACL=0
[ "${acl_node_num}" == 0 ] && ENABLED_ACLS=0 && ENABLED_DEFAULT_ACL=0
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
} }
start() { 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 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 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 XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET
export ENABLE_DEPRECATED_GEOSITE=true export ENABLE_DEPRECATED_GEOSITE=true
export ENABLE_DEPRECATED_GEOIP=true export ENABLE_DEPRECATED_GEOIP=true
@@ -1129,21 +892,16 @@ start() {
nftflag=0 nftflag=0
USE_TABLES="" USE_TABLES=""
check_run_environment check_run_environment
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then [ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" == "1" ] && {
[ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" == "1" ] && { uci -q set ${CONFIG}.@global[0].dnsmasq_dns_redirect='1'
uci -q set ${CONFIG}.@global[0].dnsmasq_dns_redirect='1' uci -q commit ${CONFIG}
uci -q commit ${CONFIG} uci -q set dhcp.@dnsmasq[0].dns_redirect='0'
uci -q set dhcp.@dnsmasq[0].dns_redirect='0' uci -q commit dhcp
uci -q commit dhcp
json_init json_init
json_add_string "LOG" "0" json_add_string "LOG" "0"
lua $APP_PATH/helper_dnsmasq.lua restart "$(json_dump)" lua $APP_PATH/helper_dnsmasq.lua restart "$(json_dump)"
} }
fi
mkdir -p ${GLOBAL_ACL_PATH}
[ "$ENABLED_DEFAULT_ACL" == 1 ] && run_global
run_global_dnsmasq
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start
set_cache_var "USE_TABLES" "$USE_TABLES" set_cache_var "USE_TABLES" "$USE_TABLES"
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
@@ -1200,7 +958,7 @@ stop() {
rm -rf $GLOBAL_DNSMASQ_CONF_PATH rm -rf $GLOBAL_DNSMASQ_CONF_PATH
[ "1" = "1" ] && { [ "1" = "1" ] && {
#restore logic #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}" ] && { [ -n "${bak_dnsmasq_dns_redirect}" ] && {
uci -q set dhcp.@dnsmasq[0].dns_redirect="${bak_dnsmasq_dns_redirect}" uci -q set dhcp.@dnsmasq[0].dns_redirect="${bak_dnsmasq_dns_redirect}"
uci -q commit dhcp uci -q commit dhcp
@@ -1247,32 +1005,14 @@ get_direct_dns() {
get_config() { get_config() {
ENABLED_DEFAULT_ACL=0 ENABLED_DEFAULT_ACL=0
ENABLED=$(config_t_get global enabled 0) ENABLED=$(config_n_get @global[0] enabled 0)
NODE=$(config_t_get global node) NODE=$(config_n_get @global[0] node)
[ "$ENABLED" == 1 ] && { [ "$ENABLED" == 1 ] && [ -n "$NODE" ] && [ "$(config_get_type $NODE)" == "nodes" ] && ENABLED_DEFAULT_ACL=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)
ENABLED_ACLS=$(config_t_get global acl_enable 0) TCP_PROXY_WAY=$(config_n_get @global_forwarding[0] tcp_proxy_way redirect)
SOCKS_ENABLED=$(config_t_get global socks_enabled 0) PROXY_IPV6=$(config_n_get @global_forwarding[0] ipv6_tproxy 0)
REDIR_PORT=$(echo $(get_new_port 1041 tcp,udp)) DIRECT_DNS_QUERY_STRATEGY=$(config_n_get @global[0] direct_dns_query_strategy UseIP)
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)
get_direct_dns get_direct_dns
@@ -1288,7 +1028,7 @@ get_config() {
fi fi
fi fi
set_cache_var GLOBAL_DNSMASQ_CONF ${DNSMASQ_CONF_DIR}/dnsmasq-${CONFIG}.conf 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 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" ] && { [ -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 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 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_LIST4}" ] && eval ${shunt_list4_var_name}=\"${_SHUNT_LIST4}\"
[ -n "${_SHUNT_LIST6}" ] && eval ${shunt_list6_var_name}=\"${_SHUNT_LIST6}\" [ -n "${_SHUNT_LIST6}" ] && eval ${shunt_list6_var_name}=\"${_SHUNT_LIST6}\"
set_cache_var "${node}_gen_shunt_list" "1"
} }
add_shunt_t_rule() { add_shunt_t_rule() {
@@ -255,45 +256,21 @@ add_shunt_t_rule() {
} }
load_acl() { load_acl() {
acl_json=$(lua $APP_PATH/app_acl.lua)
acl_node
log_i18n 1 "Access Control:" log_i18n 1 "Access Control:"
[ "$ENABLED_ACLS" == 1 ] && { for sid in $(jsonfilter -s "${acl_json}" -e '$.acl[*].flag'); do
acl_app eval local $(cat "${TMP_ACL_PATH}/${sid}/var")
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-)
mode=${mode:-0} [ -z "$(get_cache_var "${node}_gen_shunt_list")" ] && [ -n "${node}" ] && gen_shunt_list "${node}" shunt_list4 shunt_list6
tcp_no_redir_ports=${tcp_no_redir_ports:-default} [ -n "${use}" ] && local dns_redirect_port=$(get_cache_var "ACL_${use}_dns_port")
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
[ -n "$(get_cache_var "ACL_${sid}_node")" ] && node=$(get_cache_var "ACL_${sid}_node") local ipt_tmp=$ipt_n
[ -n "$(get_cache_var "ACL_${sid}_redir_port")" ] && redir_port=$(get_cache_var "ACL_${sid}_redir_port") [ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m
[ -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 [ "${client_proxy}" = "1" ] && {
shunt_list4=${SHUNT_LIST4} msg1="$(i18n "[%s]," "${remarks}")"
shunt_list6=${SHUNT_LIST6} for i in $(cat ${TMP_ACL_PATH}/${sid}/source_list); do
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
local _ipt_source _ipv4 local _ipt_source _ipv4
local msg local msg
if [ -n "${interface}" ]; then if [ -n "${interface}" ]; then
@@ -344,41 +321,39 @@ load_acl() {
else else
continue continue
fi fi
msg="$(i18n "[%s]," "${remarks}")${msg}"
ipt_tmp=$ipt_n msg="${msg1}${msg}"
[ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m
[ -n "$tcp_no_redir_ports" ] && {
[ "$tcp_no_redir_ports" != "disable" ] && {
if ! has_1_65535 "$tcp_no_redir_ports"; then 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 [ "$_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" 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}")" log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${tcp_no_redir_ports}")"
else else
# It will return when it ends, so no extra rules are needed. # 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")" log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
fi fi
} }
[ "$udp_no_redir_ports" != "disable" ] && { [ -n "$udp_no_redir_ports" ] && {
if ! has_1_65535 "$udp_no_redir_ports"; then 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 [ "$_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" 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}")" log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${udp_no_redir_ports}")"
else else
# It will return when it ends, so no extra rules are needed. # 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")" log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
fi 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 $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 $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 $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 $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 else
$ipt_n -A PSW2_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN $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 $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 $ip6t_n -A PSW2_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null
fi fi
[ "$tcp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && { [ -z "$no_tcp_proxy" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remark}")" msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remarks}")"
if [ -n "${is_tproxy}" ]; then if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${redir_port})" msg2="${msg2}(TPROXY:${redir_port})"
ipt_j="-j PSW2_RULE" ipt_j="-j PSW2_RULE"
@@ -424,8 +399,8 @@ load_acl() {
$ipt_tmp -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp -j RETURN $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 [ "$_ipv4" != "1" ] && $ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp -j RETURN 2>/dev/null
[ "$udp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && { [ -z "$no_tcp_proxy" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remark}")(TPROXY:${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 $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 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 $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 [ "$_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 done
unset enabled sid remarks sources tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node interface unset msg1
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
} }
[ "${local_proxy}" = "1" ] && {
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && { msg="$(i18n "[Local],")"
add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" [ -n "$tcp_no_redir_ports" ] && {
add_port_rules "$ipt_tmp -A PSW2 $(comment "${comment_d}") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" add_port_rules "$ipt_tmp -A PSW2_OUTPUT -p tcp" $tcp_no_redir_ports "-j RETURN"
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then add_port_rules "$ip6t_m -A PSW2_OUTPUT -p tcp" $tcp_no_redir_ports "-j RETURN"
log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")" if ! has_1_65535 "$tcp_no_redir_ports"; then
else log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${tcp_no_redir_ports}")"
UDP_PROXY_MODE="disable" else
log 2 "${msg}$(i18n "not proxy all %s" "UDP")" no_tcp_local_proxy="1"
fi log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
} 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
} }
fi [ -n "$udp_no_redir_ports" ] && {
add_port_rules "$ipt_m -A PSW2_OUTPUT -p udp" $udp_no_redir_ports "-j RETURN"
if [ "$TCP_PROXY_MODE" != "disable" ] && [ -n "$NODE" ]; then add_port_rules "$ip6t_m -A PSW2_OUTPUT -p udp" $udp_no_redir_ports "-j RETURN"
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "$(config_n_get $NODE remarks)")" if ! has_1_65535 "$udp_no_redir_ports"; then
if [ -n "${is_tproxy}" ]; then log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${udp_no_redir_ports}")"
msg2="${msg2}(TPROXY:${REDIR_PORT})" else
ipt_j="-j PSW2_RULE" no_udp_local_proxy="1"
else log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
msg2="${msg2}(REDIRECT:${REDIR_PORT})" fi
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)
} }
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && { if [ -n "$node" ] && ([ -z "$no_tcp_local_proxy" ] || [ -z "$no_udp_local_proxy" ]); then
$ip6t_n -A PSW2 $(comment "${comment_d}") -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT) [ -n "$dns_redirect_port" ] && {
add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_n -A PSW2 $(comment "${comment_d}") -p ipv6-icmp" "$(REDIRECT)" $ipt_n -A OUTPUT $(comment "PSW2_DNS") -p udp -o lo --dport 53 -j REDIRECT --to-ports $dns_redirect_port
$ip6t_n -A PSW2 $(comment "${comment_d}") -p ipv6-icmp $(REDIRECT) $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} local comment_l="$(i18n "Local")"
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)
[ "$PROXY_IPV6" == "1" ] && { # Loading local router proxy TCP
$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp -d $FAKE_IP_6 -j PSW2_RULE if [ -n "$node" ] && [ -z "$no_tcp_local_proxy" ]; then
add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp" "-j PSW2_RULE" $TCP_REDIR_PORTS [ "$accept_icmp" = "1" ] && {
add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp" $TCP_REDIR_PORTS "-j PSW2_RULE" $ipt_n -A OUTPUT $(dst $IPSET_DIRECT !) -p icmp -j PSW2_OUTPUT
$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp $(REDIRECT $REDIR_PORT TPROXY) $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}" [ "$accept_icmpv6" = "1" ] && {
fi $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]" "TCP" "${node_remarks}")"
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "$(config_n_get $NODE remarks)")(TPROXY:${REDIR_PORT})" 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 $ipt_tmp -A PSW2_OUTPUT -p tcp -d $FAKE_IP ${ipt_j}
add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_m -A PSW2 $(comment "${comment_d}") -p udp" "-j PSW2_RULE" $UDP_REDIR_PORTS add_shunt_t_rule "${shunt_list4}" "$ipt_tmp -A PSW2_OUTPUT -p tcp" "${ipt_j}" $tcp_redir_ports
add_port_rules "$ipt_m -A PSW2 $(comment "${comment_d}") -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE" add_port_rules "$ipt_tmp -A PSW2_OUTPUT -p tcp" $tcp_redir_ports "${ipt_j}"
$ipt_m -A PSW2 $(comment "${comment_d}") -p udp $(REDIRECT $REDIR_PORT TPROXY) [ -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" ] && { [ "$PROXY_IPV6" == "1" ] && {
$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp -d $FAKE_IP_6 -j PSW2_RULE $ip6t_m -A PSW2_OUTPUT -p tcp -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_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 $(comment "${comment_d}") -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE" add_port_rules "$ip6t_m -A PSW2_OUTPUT -p tcp" $tcp_redir_ports "-j PSW2_RULE"
$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp $(REDIRECT $REDIR_PORT TPROXY) $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}" [ -d "${TMP_IFACE_PATH}" ] && {
fi 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() { filter_haproxy() {
@@ -684,15 +697,12 @@ add_firewall_rule() {
done done
} }
# Shunt rules IP list (import when use shunt node)
gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6
# Filter all node IPs # Filter all node IPs
filter_vpsip > /dev/null 2>&1 & filter_vpsip > /dev/null 2>&1 &
filter_haproxy > /dev/null 2>&1 & filter_haproxy > /dev/null 2>&1 &
accept_icmp=$(config_t_get global_forwarding accept_icmp 0) accept_icmp=$(config_n_get @global_forwarding[0] accept_icmp 0)
accept_icmpv6=$(config_t_get global_forwarding accept_icmpv6 0) accept_icmpv6=$(config_n_get @global_forwarding[0] accept_icmpv6 0)
if [ "${TCP_PROXY_WAY}" = "redirect" ]; then if [ "${TCP_PROXY_WAY}" = "redirect" ]; then
unset is_tproxy unset is_tproxy
@@ -720,7 +730,7 @@ add_firewall_rule() {
$ipt_n -A PSW2_OUTPUT -m mark --mark 255 -j RETURN $ipt_n -A PSW2_OUTPUT -m mark --mark 255 -j RETURN
$ipt_n -N PSW2_DNS $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 #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 $ipt_n -I PREROUTING -m set --match-set $IPSET_DIRECT src $(dst $IPSET_LOCAL) -j PSW2_DNS
else else
@@ -763,7 +773,7 @@ add_firewall_rule() {
} }
$ip6t_n -N PSW2_DNS $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 #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 $ip6t_n -I PREROUTING -m set --match-set $IPSET_DIRECT6 src $(dst $IPSET_LOCAL6) -j PSW2_DNS
else else
@@ -809,134 +819,6 @@ add_firewall_rule() {
ip -6 rule add fwmark ${FWMARK} table 999 priority 999 ip -6 rule add fwmark ${FWMARK} table 999 priority 999
ip -6 route add local ::/0 dev lo table 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 load_acl
filter_direct_node_list > /dev/null 2>&1 & filter_direct_node_list > /dev/null 2>&1 &
@@ -1062,7 +944,7 @@ start() {
stop() { stop() {
[ -z "$(command -v log_i18n)" ] && . "$UTILS_PATH" [ -z "$(command -v log_i18n)" ] && . "$UTILS_PATH"
del_firewall_rule 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 delete ${CONFIG}.@global[0].flush_set
uci -q commit ${CONFIG} uci -q commit ${CONFIG}
flush_ipset flush_ipset
@@ -3,9 +3,9 @@
. /usr/share/passwall2/utils.sh . /usr/share/passwall2/utils.sh
LOCK_FILE=${LOCK_PATH}/${CONFIG}_monitor.lock 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" != 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 [ "$ENABLED" != 1 ] && return 1
sleep 58s sleep 58s
while [ "$ENABLED" -eq 1 ]; do while [ "$ENABLED" -eq 1 ]; do
@@ -252,7 +252,7 @@ gen_shunt_list() {
[ -n "$_geoip_code" ] && { [ -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 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" 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_LIST4}" ] && eval ${shunt_list4_var_name}=\"${_SHUNT_LIST4}\"
[ -n "${_SHUNT_LIST6}" ] && eval ${shunt_list6_var_name}=\"${_SHUNT_LIST6}\" [ -n "${_SHUNT_LIST6}" ] && eval ${shunt_list6_var_name}=\"${_SHUNT_LIST6}\"
set_cache_var "${node}_gen_shunt_list" "1"
} }
add_shunt_t_rule() { add_shunt_t_rule() {
@@ -293,45 +294,18 @@ add_shunt_t_rule() {
} }
load_acl() { load_acl() {
[ "$ENABLED_ACLS" == 1 ] && { acl_json=$(lua $APP_PATH/app_acl.lua)
log_i18n 1 "Access Control:" acl_node
acl_app log_i18n 1 "Access Control:"
for sid in $(ls -F ${TMP_ACL_PATH} | grep '/$' | awk -F '/' '{print $1}' | grep -v 'default'); do for sid in $(jsonfilter -s "${acl_json}" -e '$.acl[*].flag'); do
eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-) eval $(cat "${TMP_ACL_PATH}/${sid}/var")
mode=${mode:-0} [ -z "$(get_cache_var "${node}_gen_shunt_list")" ] && [ -n "${node}" ] && gen_shunt_list "${node}" shunt_list4 shunt_list6
tcp_no_redir_ports=${tcp_no_redir_ports:-default} [ -n "${use}" ] && local dns_redirect_port=$(get_cache_var "ACL_${use}_dns_port")
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
[ -n "$(get_cache_var "ACL_${sid}_node")" ] && node=$(get_cache_var "ACL_${sid}_node") [ "${client_proxy}" = "1" ] && {
[ -n "$(get_cache_var "ACL_${sid}_redir_port")" ] && redir_port=$(get_cache_var "ACL_${sid}_redir_port") msg1="$(i18n "[%s]," "${remarks}")"
[ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port") for i in $(cat ${TMP_ACL_PATH}/${sid}/source_list); do
[ -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
local _ipt_source _ipv4 local _ipt_source _ipv4
local msg local msg
if [ -n "${interface}" ]; then if [ -n "${interface}" ]; then
@@ -375,40 +349,38 @@ load_acl() {
else else
continue continue
fi 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 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\"" 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\"" [ "$_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}")" log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${tcp_no_redir_ports}")"
else else
# It will return when it ends, so no extra rules are needed. # 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")" log 2 "${msg}$(i18n "not proxy all %s" "TCP")"
fi fi
} }
[ "$udp_no_redir_ports" != "disable" ] && { [ -n "$udp_no_redir_ports" ] && {
if ! has_1_65535 "$udp_no_redir_ports"; then 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\"" 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 [ "$_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}")" log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${udp_no_redir_ports}")"
else else
# It will return when it ends, so no extra rules are needed. # 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")" log 2 "${msg}$(i18n "not proxy all %s" "UDP")"
fi 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
[ -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 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 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 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\""
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}")"
[ -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.")"
}
else 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 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\"" 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\"" nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\""
fi fi
[ "$tcp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && { [ -z "$no_tcp_proxy" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remark}")" msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remarks}")"
if [ -n "${is_tproxy}" ]; then if [ -n "${is_tproxy}" ]; then
msg2="${msg2}(TPROXY:${redir_port})" msg2="${msg2}(TPROXY:${redir_port})"
nft_chain="PSW2_MANGLE" 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\"" 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 [ "$_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" ] && { [ -z "$no_tcp_proxy" ] && [ -n "$redir_port" ] && {
msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remark}")(TPROXY:${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\"" 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" 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\"" 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 [ "$_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 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 msg1
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
} }
[ "${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" ] && { if [ -n "$node" ] && ([ -z "$no_tcp_local_proxy" ] || [ -z "$no_udp_local_proxy" ]); then
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"${comment}\"" [ -n "$dns_redirect_port" ] && {
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"${comment}\"" nft "add rule $NFTABLE_NAME nat_output ip protocol udp oif lo udp dport 53 counter redirect to :$dns_redirect_port comment \"PSW2_DNS\""
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then nft "add rule $NFTABLE_NAME nat_output ip protocol tcp oif lo tcp dport 53 counter redirect to :$dns_redirect_port comment \"PSW2_DNS\""
log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")" nft "add rule $NFTABLE_NAME nat_output meta l4proto udp oif lo udp dport 53 counter redirect to :$dns_redirect_port comment \"PSW2_DNS\""
else nft "add rule $NFTABLE_NAME nat_output meta l4proto tcp oif lo tcp dport 53 counter redirect to :$dns_redirect_port comment \"PSW2_DNS\""
UDP_PROXY_MODE="disable" log 2 "${msg}$(i18n "DNS will redirected to the dedicated DNS server [%s]." "${dns_redirect_port}")"
log 2 "${msg}$(i18n "not proxy all %s" "UDP")" }
fi 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
} }
unset dns_redirect_port
if ([ "$TCP_PROXY_MODE" != "disable" ] || [ "$UDP_PROXY_MODE" != "disable" ]) && [ -n "$NODE" ]; then unset $(cat "${TMP_ACL_PATH}/${sid}/var" | awk -F '=' '{print $1}' | tr "\n" " ")
[ -n "$DNS_REDIRECT_PORT" ] && { done
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
}
} }
filter_haproxy() { filter_haproxy() {
@@ -746,9 +750,6 @@ add_firewall_rule() {
done done
} }
# Shunt rules IP list (import when use shunt node)
gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6
# Filter all node IPs # Filter all node IPs
filter_vpsip > /dev/null 2>&1 & filter_vpsip > /dev/null 2>&1 &
filter_haproxy > /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 address) > /dev/null 2>&1 &
filter_vps_addr $(config_n_get $NODE download_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_icmp=$(config_n_get @global_forwarding[0] accept_icmp 0)
accept_icmpv6=$(config_t_get global_forwarding accept_icmpv6 0) accept_icmpv6=$(config_n_get @global_forwarding[0] accept_icmpv6 0)
if [ "${TCP_PROXY_WAY}" = "redirect" ]; then if [ "${TCP_PROXY_WAY}" = "redirect" ]; then
unset is_tproxy unset is_tproxy
@@ -771,7 +772,7 @@ add_firewall_rule() {
nft "add chain $NFTABLE_NAME PSW2_DNS" nft "add chain $NFTABLE_NAME PSW2_DNS"
nft "flush 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 #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 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" 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 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 load_acl
filter_direct_node_list > /dev/null 2>&1 & filter_direct_node_list > /dev/null 2>&1 &
@@ -1093,7 +972,7 @@ start() {
stop() { stop() {
[ -z "$(command -v log_i18n)" ] && . "$UTILS_PATH" [ -z "$(command -v log_i18n)" ] && . "$UTILS_PATH"
del_firewall_rule 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 delete ${CONFIG}.@global[0].flush_set
uci -q commit ${CONFIG} uci -q commit ${CONFIG}
#flush_table #flush_table
@@ -75,7 +75,7 @@ test_node() {
local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ -n "${_type}" ] && { [ -n "${_type}" ] && {
check_process 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 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 sleep 2s
local curlx="socks5h://127.0.0.1:${_tmp_port}" 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_ssr = api.is_finded("ssr-local") and api.is_finded("ssr-redir")
local has_singbox = api.finded_com("sing-box") local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray") local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria")
local DEFAULT_ALLOWINSECURE = true local DEFAULT_ALLOWINSECURE = true
local DEFAULT_FILTER_KEYWORD_MODE = uci_get("@global_subscribe[0]", "filter_keyword_mode") or "0" 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 {} 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_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_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_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 = { local core_has = {
["xray"] = has_xray, ["xray"] = has_xray,
["sing-box"] = has_singbox, ["sing-box"] = has_singbox,
["shadowsocks-rust"] = has_ss_rust, ["shadowsocks-rust"] = has_ss_rust,
["hysteria2"] = has_hysteria2
} }
-- Determine whether to filter node keywords -- Determine whether to filter node keywords
local function is_filter_keyword(sub_cfg, value) 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.protocol = "hysteria2"
result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil 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 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 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")) 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 return nil
@@ -17,8 +17,8 @@ do
if [ "$CFG_UPDATE_INT" -ne 0 ]; then if [ "$CFG_UPDATE_INT" -ne 0 ]; then
restart_week_mode=$(config_t_get global_delay restart_week_mode) restart_week_mode=$(config_n_get @global_delay[0] restart_week_mode)
restart_interval_mode=$(config_t_get global_delay restart_interval_mode) restart_interval_mode=$(config_n_get @global_delay[0] restart_interval_mode)
restart_interval_mode=$(expr "$restart_interval_mode" \* 60) restart_interval_mode=$(expr "$restart_interval_mode" \* 60)
if [ -n "$restart_week_mode" ]; then if [ -n "$restart_week_mode" ]; then
[ "$restart_week_mode" = "8" ] && { [ "$restart_week_mode" = "8" ] && {
@@ -26,8 +26,8 @@ do
} }
fi fi
rules_update_week_mode=$(config_t_get global_rules update_week_mode) rules_update_week_mode=$(config_n_get @global_rules[0] update_week_mode)
rules_update_interval_mode=$(config_t_get global_rules update_interval_mode) rules_update_interval_mode=$(config_n_get @global_rules[0] update_interval_mode)
rules_update_interval_mode=$(expr "$rules_update_interval_mode" \* 60) rules_update_interval_mode=$(expr "$rules_update_interval_mode" \* 60)
if [ -n "$rules_update_week_mode" ]; then if [ -n "$rules_update_week_mode" ]; then
[ "$rules_update_week_mode" = "8" ] && { [ "$rules_update_week_mode" = "8" ] && {
@@ -46,11 +46,11 @@ url_test_node() {
local node_id=$1 local node_id=$1
local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ -n "${_type}" ] && { [ -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 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 sleep 2s
local curlx="socks5h://127.0.0.1:${_tmp_port}" 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}") 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 # End the SS plugin process
local pid_file="${TMP_PATH}/url_test_${node_id}_plugin.pid" local pid_file="${TMP_PATH}/url_test_${node_id}_plugin.pid"
@@ -33,11 +33,6 @@ config_t_get() {
echo "${ret:=${3}}" 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() { eval_set_val() {
for i in $@; do for i in $@; do
for j in $i; do for j in $i; do
@@ -157,9 +152,9 @@ get_geoip() {
local geoip_type_flag="" local geoip_type_flag=""
local output_path="${geo_output_path}/geoip-${geoip_code}-$2" local output_path="${geo_output_path}/geoip-${geoip_code}-$2"
[ ! -s "${output_path}" ] && { [ ! -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" 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; } [ -n "$bin" ] && [ -s "$geoip_path" ] || { echo ""; return; }
case "$2" in case "$2" in
"ipv4") geoip_type_flag="-ipv6=false" ;; "ipv4") geoip_type_flag="-ipv6=false" ;;
@@ -299,7 +294,7 @@ get_new_port() {
local default_start_port=2001 local default_start_port=2001
local min_port=1025 local min_port=1025
local max_port=49151 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 local last_get_new_port_auto
if [ "$1" == "auto" ]; then if [ "$1" == "auto" ]; then
last_get_new_port_auto=$(get_cache_var "last_get_new_port_auto") 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 [ "$port" -lt $min_port -o "$port" -gt $max_port ] && port=$default_start_port
local protocol=$(echo $2 | tr 'A-Z' 'a-z') local protocol=$(echo $2 | tr 'A-Z' 'a-z')
local result=$(check_port_exists $port $protocol) 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 if [ "$result" != 0 ]; then
local temp= local temp=
if [ "$port" -lt $max_port ]; then 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) temp=$(expr $port + 1)
elif [ "$port" -gt $min_port ]; then 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) temp=$(expr $port - 1)
else else
# Otherwise, reassign the default starting port.
temp=$default_start_port temp=$default_start_port
fi fi
# Recursion, until it obtains an unused port.
get_new_port $temp $protocol get_new_port $temp $protocol
else 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" [ "$1" == "auto" ] && set_cache_var "last_get_new_port_auto" "$port"
echo $port echo $port
fi fi