diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile
index a3e86ced5..0f9cb501d 100644
--- a/luci-app-passwall2/Makefile
+++ b/luci-app-passwall2/Makefile
@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2
-PKG_VERSION:=24.12.14
+PKG_VERSION:=24.12.16
PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \
diff --git a/luci-app-passwall2/luasrc/controller/passwall2.lua b/luci-app-passwall2/luasrc/controller/passwall2.lua
index 5521ece0f..3c6a951c6 100644
--- a/luci-app-passwall2/luasrc/controller/passwall2.lua
+++ b/luci-app-passwall2/luasrc/controller/passwall2.lua
@@ -158,9 +158,9 @@ end
function get_now_use_node()
local e = {}
- local data, code, msg = nixio.fs.readfile("/tmp/etc/passwall2/acl/default/global.id")
- if data then
- e["global"] = util.trim(data)
+ local node = api.get_cache_var("GLOBAL_node")
+ if node then
+ e["global"] = node
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
@@ -328,7 +328,7 @@ function clear_all_nodes()
uci:delete(appname, t[".name"])
end)
uci:foreach(appname, "acl_rule", function(t)
- uci:set(appname, t[".name"], "node", "default")
+ uci:set(appname, t[".name"], "node", "nil")
end)
uci:foreach(appname, "nodes", function(node)
uci:delete(appname, node['.name'])
@@ -363,7 +363,17 @@ function delete_select_nodes()
end)
uci:foreach(appname, "acl_rule", function(t)
if t["node"] == w then
- uci:set(appname, t[".name"], "node", "default")
+ uci:set(appname, t[".name"], "node", "nil")
+ end
+ end)
+ uci:foreach(appname, "nodes", function(t)
+ if t["preproxy_node"] == w then
+ uci:delete(appname, t[".name"], "preproxy_node")
+ uci:delete(appname, t[".name"], "chain_proxy")
+ end
+ if t["to_node"] == w then
+ uci:delete(appname, t[".name"], "to_node")
+ uci:delete(appname, t[".name"], "chain_proxy")
end
end)
uci:delete(appname, w)
diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/socks_config.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/socks_config.lua
index 09352ed14..d47cea1e8 100644
--- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/socks_config.lua
+++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/socks_config.lua
@@ -22,9 +22,8 @@ o.default = 1
o.rmempty = false
local auto_switch_tip
-local current_node_file = string.format("/tmp/etc/%s/id/socks_%s", appname, arg[1])
-local current_node = luci.sys.exec(string.format("[ -f '%s' ] && echo -n $(cat %s)", current_node_file, current_node_file))
-if current_node and current_node ~= "" and current_node ~= "nil" then
+local current_node = api.get_cache_var("socks_" .. arg[1])
+if current_node then
local n = uci:get_all(appname, current_node)
if n then
if tonumber(m:get(arg[1], "enable_autoswitch") or 0) == 1 then
diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua
index e98ad96cf..53686de88 100644
--- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua
+++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua
@@ -647,12 +647,26 @@ o.default = 0
o = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay")
o.default = 0
-o = s:option(ListValue, option_name("to_node"), translate("Landing node"), translate("Only support a layer of proxy."))
-o.default = ""
+o = s:option(ListValue, option_name("chain_proxy"), translate("Chain Proxy"))
o:value("", translate("Close(Not use)"))
+o:value("1", translate("Preproxy Node"))
+o:value("2", translate("Landing Node"))
+for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
+ if not v:find("_") then
+ o:depends({ [option_name("protocol")] = v })
+ end
+end
+
+o = s:option(ListValue, option_name("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
+o:depends({ [option_name("chain_proxy")] = "1" })
+
+o = s:option(ListValue, option_name("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
+o:depends({ [option_name("chain_proxy")] = "2" })
+
for k, v in pairs(nodes_table) do
- if v.type == "Xray" then
- o:value(v.id, v.remark)
+ if v.type == "Xray" and v.id ~= arg[1] then
+ s.fields[option_name("preproxy_node")]:value(v.id, v.remark)
+ s.fields[option_name("to_node")]:value(v.id, v.remark)
end
end
@@ -660,7 +674,7 @@ for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
if not v:find("_") then
s.fields[option_name("tcpMptcp")]:depends({ [option_name("protocol")] = v })
s.fields[option_name("tcpNoDelay")]:depends({ [option_name("protocol")] = v })
- s.fields[option_name("to_node")]:depends({ [option_name("protocol")] = v })
+ s.fields[option_name("chain_proxy")]:depends({ [option_name("protocol")] = v })
end
end
diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua
index ce424b751..dd1aa88a3 100644
--- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua
+++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua
@@ -684,18 +684,27 @@ o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" })
-o = s:option(ListValue, option_name("to_node"), translate("Landing node"), translate("Only support a layer of proxy."))
-o.default = ""
+o = s:option(ListValue, option_name("chain_proxy"), translate("Chain Proxy"))
o:value("", translate("Close(Not use)"))
-for k, v in pairs(nodes_table) do
- if v.type == "sing-box" then
- o:value(v.id, v.remark)
- end
-end
+o:value("1", translate("Preproxy Node"))
+o:value("2", translate("Landing Node"))
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
if not v:find("_") then
o:depends({ [option_name("protocol")] = v })
end
end
+o = s:option(ListValue, option_name("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
+o:depends({ [option_name("chain_proxy")] = "1" })
+
+o = s:option(ListValue, option_name("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
+o:depends({ [option_name("chain_proxy")] = "2" })
+
+for k, v in pairs(nodes_table) do
+ if v.type == "sing-box" and v.id ~= arg[1] then
+ s.fields[option_name("preproxy_node")]:value(v.id, v.remark)
+ s.fields[option_name("to_node")]:value(v.id, v.remark)
+ end
+end
+
api.luci_types(arg[1], m, s, type_name, option_prefix)
diff --git a/luci-app-passwall2/luasrc/passwall2/api.lua b/luci-app-passwall2/luasrc/passwall2/api.lua
index 9491c885f..ddd5ca4a4 100644
--- a/luci-app-passwall2/luasrc/passwall2/api.lua
+++ b/luci-app-passwall2/luasrc/passwall2/api.lua
@@ -17,6 +17,8 @@ DISTRIB_ARCH = nil
LOG_FILE = "/tmp/log/passwall2.log"
CACHE_PATH = "/tmp/etc/passwall2_tmp"
+TMP_PATH = "/tmp/etc/" .. appname
+TMP_IFACE_PATH = TMP_PATH .. "/iface"
function log(...)
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
@@ -27,6 +29,15 @@ function log(...)
end
end
+function set_cache_var(key, val)
+ sys.call(string.format('/usr/share/passwall2/app.sh set_cache_var %s "%s"', key, val))
+end
+function get_cache_var(key)
+ local val = sys.exec(string.format('echo -n $(/usr/share/passwall2/app.sh get_cache_var %s)', key))
+ if val == "" then val = nil end
+ return val
+end
+
function exec_call(cmd)
local process = io.popen(cmd .. '; echo -e "\n$?"')
local lines = {}
@@ -96,8 +107,8 @@ end
function curl_proxy(url, file, args)
--使用代理
- local socks_server = luci.sys.exec("[ -f /tmp/etc/passwall2/acl/default/SOCKS_server ] && echo -n $(cat /tmp/etc/passwall2/acl/default/SOCKS_server) || echo -n ''")
- if socks_server ~= "" then
+ local socks_server = get_cache_var("GLOBAL_SOCKS_server")
+ if socks_server and socks_server ~= "" then
if not args then args = {} end
local tmp_args = clone(args)
tmp_args[#tmp_args + 1] = "-x socks5h://" .. socks_server
diff --git a/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua
index 254485783..9d0bf93f1 100644
--- a/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua
+++ b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua
@@ -685,7 +685,7 @@ function gen_config_server(node)
bind_interface = node.outbound_node_iface,
routing_mark = 255,
}
- sys.call("mkdir -p /tmp/etc/passwall2/iface && touch /tmp/etc/passwall2/iface/" .. node.outbound_node_iface)
+ sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface))
else
local outbound_node_t = uci:get_all("passwall2", node.outbound_node)
if node.outbound_node == "_socks" or node.outbound_node == "_http" then
@@ -871,6 +871,7 @@ function gen_config(var)
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
if not node or not outbound or not outbounds_table then return nil end
local default_outTag = outbound.tag
+ local last_insert_outbound
if node.shadowtls == "1" then
local _node = {
@@ -887,14 +888,31 @@ function gen_config(var)
}
local shadowtls_outbound = gen_outbound(nil, _node, outbound.tag .. "_shadowtls")
if shadowtls_outbound then
- table.insert(outbounds_table, shadowtls_outbound)
+ last_insert_outbound = shadowtls_outbound
outbound.detour = outbound.tag .. "_shadowtls"
outbound.server = nil
outbound.server_port = nil
end
end
- if node.to_node then
+ if node.chain_proxy == "1" and node.preproxy_node then
+ if outbound["_flag_proxy_tag"] and outbound["_flag_proxy_tag"] ~= "nil" then
+ --Ignore
+ else
+ local preproxy_node = uci:get_all(appname, node.preproxy_node)
+ if preproxy_node then
+ local preproxy_outbound = gen_outbound(nil, preproxy_node)
+ if preproxy_outbound then
+ preproxy_outbound.tag = preproxy_node[".name"] .. ":" .. preproxy_node.remarks
+ outbound.tag = preproxy_outbound.tag .. " -> " .. outbound.tag
+ outbound.detour = preproxy_outbound.tag
+ last_insert_outbound = preproxy_outbound
+ default_outTag = outbound.tag
+ end
+ end
+ end
+ end
+ if node.chain_proxy == "2" and node.to_node then
local to_node = uci:get_all(appname, node.to_node)
if to_node then
local to_outbound = gen_outbound(nil, to_node)
@@ -912,7 +930,7 @@ function gen_config(var)
end
end
end
- return default_outTag
+ return default_outTag, last_insert_outbound
end
if node.protocol == "_shunt" then
@@ -997,8 +1015,11 @@ function gen_config(var)
local _outbound = gen_outbound(flag, _node, rule_name, { tag = use_proxy and preproxy_tag or nil })
if _outbound then
_outbound.tag = _outbound.tag .. ":" .. _node.remarks
- rule_outboundTag = set_outbound_detour(_node, _outbound, outbounds, rule_name)
+ rule_outboundTag, last_insert_outbound = set_outbound_detour(_node, _outbound, outbounds, rule_name)
table.insert(outbounds, _outbound)
+ if last_insert_outbound then
+ table.insert(outbounds, last_insert_outbound)
+ end
end
end
elseif _node.protocol == "_iface" then
@@ -1011,7 +1032,7 @@ function gen_config(var)
}
table.insert(outbounds, _outbound)
rule_outboundTag = _outbound.tag
- sys.call("touch /tmp/etc/passwall2/iface/" .. _node.iface)
+ sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, _node.iface))
end
end
end
@@ -1186,14 +1207,17 @@ function gen_config(var)
}
table.insert(outbounds, outbound)
COMMON.default_outbound_tag = outbound.tag
- sys.call("touch /tmp/etc/passwall2/iface/" .. node.iface)
+ sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface))
end
else
local outbound = gen_outbound(flag, node)
if outbound then
outbound.tag = outbound.tag .. ":" .. node.remarks
- COMMON.default_outbound_tag = set_outbound_detour(node, outbound, outbounds)
+ COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds)
table.insert(outbounds, outbound)
+ if last_insert_outbound then
+ table.insert(outbounds, last_insert_outbound)
+ end
end
end
end
@@ -1444,6 +1468,9 @@ function gen_config(var)
tag = "block"
})
for index, value in ipairs(config.outbounds) do
+ if (not value["_flag_proxy_tag"] or value["_flag_proxy_tag"] == "nil") and not value.detour and value["_id"] and value.server and value.server_port then
+ sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list"))
+ end
for k, v in pairs(config.outbounds[index]) do
if k:find("_") == 1 then
config.outbounds[index][k] = nil
diff --git a/luci-app-passwall2/luasrc/passwall2/util_xray.lua b/luci-app-passwall2/luasrc/passwall2/util_xray.lua
index b480b16bc..5f9118096 100644
--- a/luci-app-passwall2/luasrc/passwall2/util_xray.lua
+++ b/luci-app-passwall2/luasrc/passwall2/util_xray.lua
@@ -416,7 +416,7 @@ function gen_config_server(node)
}
}
}
- sys.call("mkdir -p /tmp/etc/passwall2/iface && touch /tmp/etc/passwall2/iface/" .. node.outbound_node_iface)
+ sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface))
else
local outbound_node_t = uci:get_all("passwall2", node.outbound_node)
if node.outbound_node == "_socks" or node.outbound_node == "_http" then
@@ -782,8 +782,29 @@ function gen_config(var)
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
if not node or not outbound or not outbounds_table then return nil end
local default_outTag = outbound.tag
+ local last_insert_outbound
- if node.to_node then
+ if node.chain_proxy == "1" and node.preproxy_node then
+ if outbound["_flag_proxy_tag"] and outbound["_flag_proxy_tag"] ~= "nil" then
+ --Ignore
+ else
+ local preproxy_node = uci:get_all(appname, node.preproxy_node)
+ if preproxy_node then
+ local preproxy_outbound = gen_outbound(nil, preproxy_node)
+ if preproxy_outbound then
+ preproxy_outbound.tag = preproxy_node[".name"] .. ":" .. preproxy_node.remarks
+ outbound.tag = preproxy_outbound.tag .. " -> " .. outbound.tag
+ outbound.proxySettings = {
+ tag = preproxy_outbound.tag,
+ transportLayer = true
+ }
+ last_insert_outbound = preproxy_outbound
+ default_outTag = outbound.tag
+ end
+ end
+ end
+ end
+ if node.chain_proxy == "2" and node.to_node then
local to_node = uci:get_all(appname, node.to_node)
if to_node then
local to_outbound = gen_outbound(nil, to_node)
@@ -804,7 +825,7 @@ function gen_config(var)
end
end
end
- return default_outTag
+ return default_outTag, last_insert_outbound
end
if node then
@@ -906,12 +927,15 @@ function gen_config(var)
local outbound_tag
if outbound then
outbound.tag = outbound.tag .. ":" .. _node.remarks
- outbound_tag = set_outbound_detour(_node, outbound, outbounds, rule_name)
+ outbound_tag, last_insert_outbound = set_outbound_detour(_node, outbound, outbounds, rule_name)
if rule_name == "default" then
table.insert(outbounds, 1, outbound)
else
table.insert(outbounds, outbound)
end
+ if last_insert_outbound then
+ table.insert(outbounds, last_insert_outbound)
+ end
end
return outbound_tag, nil
end
@@ -932,7 +956,7 @@ function gen_config(var)
}
outbound_tag = outbound.tag
table.insert(outbounds, outbound)
- sys.call("touch /tmp/etc/passwall2/iface/" .. _node.iface)
+ sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, _node.iface))
end
return outbound_tag, nil
end
@@ -1098,14 +1122,17 @@ function gen_config(var)
}
table.insert(outbounds, outbound)
COMMON.default_outbound_tag = outbound.tag
- sys.call("touch /tmp/etc/passwall2/iface/" .. node.iface)
+ sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface))
end
else
local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.fragment == "1" or nil })
if outbound then
outbound.tag = outbound.tag .. ":" .. node.remarks
- COMMON.default_outbound_tag = set_outbound_detour(node, outbound, outbounds)
+ COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds)
table.insert(outbounds, outbound)
+ if last_insert_outbound then
+ table.insert(outbounds, last_insert_outbound)
+ end
routing = {
domainStrategy = "AsIs",
domainMatcher = "hybrid",
@@ -1523,6 +1550,9 @@ function gen_config(var)
end
for index, value in ipairs(config.outbounds) do
+ if (not value["_flag_proxy_tag"] or value["_flag_proxy_tag"] == "nil") and value["_id"] and value.server and value.server_port then
+ sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list"))
+ end
for k, v in pairs(config.outbounds[index]) do
if k:find("_") == 1 then
config.outbounds[index][k] = nil
diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm b/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm
index 5f222ecfe..8d5e0abe9 100644
--- a/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm
+++ b/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm
@@ -223,22 +223,18 @@ table td, .table .td {
function get_now_use_node() {
XHR.get('<%=api.url("get_now_use_node")%>', null,
function(x, result) {
- var id = result["TCP"];
+ var id = result["global"];
if (id) {
var dom = document.getElementById("cbi-passwall2-" + id);
if (dom) {
dom.classList.add("_now_use");
- dom.title = "当前TCP节点";
- //var v = "当前TCP节点:" + document.getElementById("cbid.passwall2." + id + ".remarks").value;
+ dom.title = "当前节点";
+ //var v = "当前节点:" + document.getElementById("cbid.passwall2." + id + ".remarks").value;
//document.getElementById("cbi-passwall2-" + id + "-remarks").innerHTML = v;
- }
- }
- id = result["UDP"];
- if (id) {
- var dom = document.getElementById("cbi-passwall2-" + id);
- if (dom) {
- dom.classList.add("_now_use");
- dom.title = "当前UDP节点";
+ var tds = dom.getElementsByTagName("td")
+ for (var j = 0; j < tds.length; j++) {
+ tds[j].classList.add("_now_use");
+ }
}
}
}
@@ -305,9 +301,7 @@ table td, .table .td {
);
}
}
-
- get_now_use_node();
-
+
/* 自动Ping */
if (auto_detection_time == "icmp" || auto_detection_time == "tcping") {
var nodes = [];
@@ -427,7 +421,9 @@ table td, .table .td {
console.error(err);
}
}
-
+
+ get_now_use_node();
+
if (true) {
var str = "";
for (var add_from in node_list) {
diff --git a/luci-app-passwall2/po/zh-cn/passwall2.po b/luci-app-passwall2/po/zh-cn/passwall2.po
index 67f48a1a7..0be850e18 100644
--- a/luci-app-passwall2/po/zh-cn/passwall2.po
+++ b/luci-app-passwall2/po/zh-cn/passwall2.po
@@ -1570,7 +1570,10 @@ msgstr "延迟(ms)"
msgid "If is domain name, The requested domain name will be resolved to IP before connect."
msgstr "如果是域名,域名将在请求发出之前解析为 IP。"
-msgid "Landing node"
+msgid "Chain Proxy"
+msgstr "链式代理"
+
+msgid "Landing Node"
msgstr "落地节点"
msgid "Only support a layer of proxy."
diff --git a/luci-app-passwall2/root/usr/share/passwall2/app.sh b/luci-app-passwall2/root/usr/share/passwall2/app.sh
index 7f555fd9a..cc7c1a2ca 100755
--- a/luci-app-passwall2/root/usr/share/passwall2/app.sh
+++ b/luci-app-passwall2/root/usr/share/passwall2/app.sh
@@ -8,7 +8,6 @@ CONFIG=passwall2
TMP_PATH=/tmp/etc/$CONFIG
TMP_BIN_PATH=$TMP_PATH/bin
TMP_SCRIPT_FUNC_PATH=$TMP_PATH/script_func
-TMP_ID_PATH=$TMP_PATH/id
TMP_ROUTE_PATH=$TMP_PATH/route
TMP_ACL_PATH=$TMP_PATH/acl
TMP_IFACE_PATH=$TMP_PATH/iface
@@ -324,6 +323,19 @@ get_singbox_geoip() {
fi
}
+set_cache_var() {
+ local key="${1}"
+ shift 1
+ local val="$@"
+ [ -n "${key}" ] && [ -n "${val}" ] && echo "${key}=\"${val}\"" >> $TMP_PATH/var
+}
+get_cache_var() {
+ local key="${1}"
+ [ -n "${key}" ] && [ -s "$TMP_PATH/var" ] && {
+ echo $(cat $TMP_PATH/var | grep "^${key}=" | awk -F '=' '{print $2}' | tail -n 1 | awk -F'"' '{print $2}')
+ }
+}
+
run_xray() {
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 write_ipset_direct
@@ -654,6 +666,8 @@ run_socks() {
fi
}
unset http_flag
+
+ [ "${server_host}" != "127.0.0.1" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list
}
socks_node_switch() {
@@ -680,7 +694,9 @@ socks_node_switch() {
local http_config_file="HTTP2SOCKS_${flag}.json"
LOG_FILE="/dev/null"
run_socks flag=$flag node=$new_node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
- echo $new_node > $TMP_ID_PATH/socks_${flag}
+ set_cache_var "socks_${flag}" "$new_node"
+ local USE_TABLES=$(get_cache_var "USE_TABLES")
+ [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh filter_direct_node_list
}
}
@@ -689,7 +705,7 @@ run_global() {
TYPE=$(echo $(config_n_get $NODE type nil) | tr 'A-Z' 'a-z')
[ "$TYPE" = "nil" ] && return 1
mkdir -p $TMP_ACL_PATH/default
- echo $NODE > $TMP_ACL_PATH/default/global.id
+ set_cache_var "GLOBAL_node" "$NODE"
if [ $PROXY_IPV6 == "1" ]; then
echolog "开启实验性IPv6透明代理(TProxy),请确认您的节点及类型支持IPv6!"
@@ -737,7 +753,7 @@ run_global() {
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}"
- echo "127.0.0.1:$node_socks_port" > $TMP_ACL_PATH/default/SOCKS_server
+ 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}"
@@ -781,7 +797,7 @@ start_socks() {
local http_port=$(config_n_get $id http_port 0)
local http_config_file="HTTP2SOCKS_${id}.json"
run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
- echo $node > $TMP_ID_PATH/socks_${id}
+ set_cache_var "socks_${id}" "$node"
#自动切换逻辑
local enable_autoswitch=$(config_n_get $id enable_autoswitch 0)
@@ -947,7 +963,7 @@ delete_ip2route() {
start_haproxy() {
[ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && return
- haproxy_path=${TMP_PATH}/haproxy
+ haproxy_path=$TMP_PATH/haproxy
haproxy_conf="config.cfg"
lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf} -dns ${LOCAL_DNS}
ln_run "$(first_type haproxy)" haproxy "/dev/null" -f "${haproxy_path}/${haproxy_conf}"
@@ -1013,7 +1029,7 @@ run_copy_dnsmasq() {
node_servers=$(uci show "${CONFIG}" | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2)
hosts_foreach "node_servers" host_from_url | grep '[a-zA-Z]$' | sort -u | grep -v "engage.cloudflareclient.com" | gen_dnsmasq_items settype="${set_type}" setnames="${setflag_4}passwall2_vpslist,${setflag_6}passwall2_vpslist6" dnss="${LOCAL_DNS:-${AUTO_DNS}}" outf="${dnsmasq_conf_path}/10-vpslist_host.conf" ipsetoutf="${dnsmasq_conf_path}/ipset.conf"
ln_run "$(first_type dnsmasq)" "dnsmasq_${flag}" "/dev/null" -C $dnsmasq_conf -x $TMP_ACL_PATH/$flag/dnsmasq.pid
- echo "${listen_port}" > $TMP_ACL_PATH/$flag/var_redirect_dns_port
+ set_cache_var "ACL_${flag}_dns_port" "${listen_port}"
}
run_ipset_chinadns_ng() {
@@ -1157,10 +1173,10 @@ acl_app() {
filter_node $node TCP > /dev/null 2>&1 &
filter_node $node UDP > /dev/null 2>&1 &
fi
- echo "${node}" > $TMP_ACL_PATH/$sid/var_node
+ set_cache_var "ACL_${sid}_node" "${node}"
}
fi
- echo "${redir_port}" > $TMP_ACL_PATH/$sid/var_port
+ set_cache_var "ACL_${sid}_redir_port" "${redir_port}"
}
unset enabled sid remarks sources interface 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
unset _ip _mac _iprange _ipset _ip_or_mac source_list config_file
@@ -1219,13 +1235,14 @@ start() {
fi
[ "$ENABLED_DEFAULT_ACL" == 1 ] && run_global
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start
+ set_cache_var "USE_TABLES" "$USE_TABLES"
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
bridge_nf_ipt=$(sysctl -e -n net.bridge.bridge-nf-call-iptables)
- echo -n $bridge_nf_ipt > $TMP_PATH/bridge_nf_ipt
+ set_cache_var "origin_bridge_nf_ipt" "$bridge_nf_ipt"
sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1
[ "$PROXY_IPV6" == "1" ] && {
bridge_nf_ip6t=$(sysctl -e -n net.bridge.bridge-nf-call-ip6tables)
- echo -n $bridge_nf_ip6t > $TMP_PATH/bridge_nf_ip6t
+ set_cache_var "origin_bridge_nf_ip6t" "$bridge_nf_ip6t"
sysctl -w net.bridge.bridge-nf-call-ip6tables=0 >/dev/null 2>&1
}
fi
@@ -1244,9 +1261,11 @@ stop() {
unset V2RAY_LOCATION_ASSET
unset XRAY_LOCATION_ASSET
stop_crontab
- [ -s "$TMP_PATH/bridge_nf_ipt" ] && sysctl -w net.bridge.bridge-nf-call-iptables=$(cat $TMP_PATH/bridge_nf_ipt) >/dev/null 2>&1
- [ -s "$TMP_PATH/bridge_nf_ip6t" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=$(cat $TMP_PATH/bridge_nf_ip6t) >/dev/null 2>&1
- rm -rf ${TMP_PATH}
+ origin_bridge_nf_ipt=$(get_cache_var "origin_bridge_nf_ipt")
+ [ -n "${origin_bridge_nf_ipt}" ] && sysctl -w net.bridge.bridge-nf-call-iptables=${origin_bridge_nf_ipt} >/dev/null 2>&1
+ origin_bridge_nf_ip6t=$(get_cache_var "origin_bridge_nf_ip6t")
+ [ -n "${origin_bridge_nf_ip6t}" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=${origin_bridge_nf_ip6t} >/dev/null 2>&1
+ rm -rf $TMP_PATH
rm -rf /tmp/lock/${CONFIG}_socks_auto_switch*
echolog "清空并关闭相关程序和缓存完成。"
exit 0
@@ -1299,7 +1318,7 @@ SINGBOX_BIN=$(first_type $(config_t_get global_app singbox_file) sing-box)
export V2RAY_LOCATION_ASSET=$(config_t_get global_rules v2ray_location_asset "/usr/share/v2ray/")
export XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET
-mkdir -p /tmp/etc $TMP_PATH $TMP_BIN_PATH $TMP_SCRIPT_FUNC_PATH $TMP_ID_PATH $TMP_ROUTE_PATH $TMP_ACL_PATH $TMP_IFACE_PATH $TMP_PATH2
+mkdir -p /tmp/etc $TMP_PATH $TMP_BIN_PATH $TMP_SCRIPT_FUNC_PATH $TMP_ROUTE_PATH $TMP_ACL_PATH $TMP_PATH2
arg1=$1
shift
@@ -1319,6 +1338,12 @@ socks_node_switch)
echolog)
echolog $@
;;
+get_cache_var)
+ get_cache_var $@
+ ;;
+set_cache_var)
+ set_cache_var $@
+ ;;
stop)
stop
;;
diff --git a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh
index 6dd34b2e8..7dc379168 100755
--- a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh
+++ b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh
@@ -292,9 +292,9 @@ load_acl() {
[ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS
node_remark=$(config_n_get $NODE remarks)
- [ -s "${TMP_ACL_PATH}/${sid}/var_node" ] && node=$(cat ${TMP_ACL_PATH}/${sid}/var_node)
- [ -s "${TMP_ACL_PATH}/${sid}/var_port" ] && redir_port=$(cat ${TMP_ACL_PATH}/${sid}/var_port)
- [ -s "${TMP_ACL_PATH}/${sid}/var_redirect_dns_port" ] && dns_redirect_port=$(cat ${TMP_ACL_PATH}/${sid}/var_redirect_dns_port)
+ [ -n $(get_cache_var "ACL_${sid}_node") ] && node=$(get_cache_var "ACL_${sid}_node")
+ [ -n $(get_cache_var "ACL_${sid}_redir_port") ] && redir_port=$(get_cache_var "ACL_${sid}_redir_port")
+ [ -n $(get_cache_var "ACL_${sid}_dns_port") ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port")
[ "$node" = "default" ] && dns_redirect_port=${DNS_REDIRECT_PORT}
[ -n "$node" ] && [ "$node" != "default" ] && node_remark=$(config_n_get $node remarks)
@@ -571,111 +571,50 @@ filter_vpsip() {
echolog " - [$?]加入所有IPv6节点到ipset[$IPSET_VPSLIST6]直连完成"
}
+filter_server_port() {
+ local address=${1}
+ local port=${2}
+ local stream=${3}
+ stream=$(echo ${3} | tr 'A-Z' 'a-z')
+ local _is_tproxy ipt_tmp
+ ipt_tmp=$ipt_n
+ _is_tproxy=${is_tproxy}
+ [ "$stream" == "udp" ] && _is_tproxy="TPROXY"
+ [ -n "${_is_tproxy}" ] && ipt_tmp=$ipt_m
+
+ for _ipt in 4 6; do
+ [ "$_ipt" == "4" ] && _ipt=$ipt_tmp
+ [ "$_ipt" == "6" ] && _ipt=$ip6t_m
+ $_ipt -n -L PSW2_OUTPUT | grep -q "${address}:${port}"
+ if [ $? -ne 0 ]; then
+ $_ipt -I PSW2_OUTPUT $(comment "${address}:${port}") -p $stream -d $address --dport $port -j RETURN 2>/dev/null
+ fi
+ done
+}
+
filter_node() {
- local proxy_node=${1}
- local stream=$(echo ${2} | tr 'A-Z' 'a-z')
- local proxy_port=${3}
-
- filter_rules() {
- local node=${1}
- local stream=${2}
- local _proxy=${3}
- local _port=${4}
- local _is_tproxy ipt_tmp msg msg2
-
- if [ -n "$node" ] && [ "$node" != "nil" ]; then
- local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
- local address=$(config_n_get $node address)
- local port=$(config_n_get $node port)
- [ -z "$address" ] && [ -z "$port" ] && {
- echolog " - 节点配置不正常,略过"
- return 1
- }
- ipt_tmp=$ipt_n
- _is_tproxy=${is_tproxy}
- [ "$stream" == "udp" ] && _is_tproxy="TPROXY"
- if [ -n "${_is_tproxy}" ]; then
- ipt_tmp=$ipt_m
- msg="TPROXY"
- else
- msg="REDIRECT"
- fi
- else
- echolog " - 节点配置不正常,略过"
+ local node=${1}
+ local stream=${2}
+ if [ -n "$node" ] && [ "$node" != "nil" ]; then
+ local address=$(config_n_get $node address)
+ local port=$(config_n_get $node port)
+ [ -z "$address" ] && [ -z "$port" ] && {
return 1
- fi
-
- local ADD_INDEX=$FORCE_INDEX
- for _ipt in 4 6; do
- [ "$_ipt" == "4" ] && _ipt=$ipt_tmp
- [ "$_ipt" == "6" ] && _ipt=$ip6t_m
- $_ipt -n -L PSW2_OUTPUT | grep -q "${address}:${port}"
- if [ $? -ne 0 ]; then
- local dst_rule="-j PSW2_RULE"
- msg2="按规则路由(${msg})"
- [ "$_ipt" == "$ipt_m" -o "$_ipt" == "$ip6t_m" ] || {
- dst_rule=$(REDIRECT $_port)
- msg2="套娃使用(${msg}:${port} -> ${_port})"
- }
- [ -n "$_proxy" ] && [ "$_proxy" == "1" ] && [ -n "$_port" ] || {
- ADD_INDEX=$(RULE_LAST_INDEX "$_ipt" PSW2_OUTPUT "$IPSET_VPSLIST" $FORCE_INDEX)
- dst_rule=" -j RETURN"
- msg2="直连代理"
- }
- $_ipt -I PSW2_OUTPUT $ADD_INDEX $(comment "${address}:${port}") -p $stream -d $address --dport $port $dst_rule 2>/dev/null
- else
- msg2="已配置过的节点,"
- fi
- done
- msg="[$?]$(echo ${2} | tr 'a-z' 'A-Z')${msg2}使用链${ADD_INDEX},节点(${type}):${address}:${port}"
- #echolog " - ${msg}"
- }
-
- local proxy_protocol=$(config_n_get $proxy_node protocol)
- local proxy_type=$(echo $(config_n_get $proxy_node type nil) | tr 'A-Z' 'a-z')
- [ "$proxy_type" == "nil" ] && echolog " - 节点配置不正常,略过!:${proxy_node}" && return 1
- if [ "$proxy_protocol" == "_balancing" ]; then
- #echolog " - 多节点负载均衡(${proxy_type})..."
- proxy_node=$(config_n_get $proxy_node balancing_node)
- for _node in $proxy_node; do
- filter_rules "$_node" "$stream"
- done
- elif [ "$proxy_protocol" == "_shunt" ]; then
- #echolog " - 按请求目的地址分流(${proxy_type})..."
- local preproxy_enabled=$(config_n_get $proxy_node preproxy_enabled 0)
- [ "$preproxy_enabled" == "1" ] && {
- local preproxy_node=$(config_n_get $proxy_node main_node nil)
- [ "$preproxy_node" != "nil" ] && {
- local preproxy_node_address=$(config_n_get $preproxy_node address)
- if [ -n "$preproxy_node_address" ]; then
- filter_rules $preproxy_node $stream
- else
- preproxy_enabled=0
- fi
- }
}
- local default_node=$(config_n_get $proxy_node default_node _direct)
- if [ "$default_node" != "_direct" ] && [ "$default_node" != "_blackhole" ]; then
- local default_proxy_tag=$(config_n_get $proxy_node default_proxy_tag nil)
- [ "$default_proxy_tag" == "main" ] && [ "$preproxy_enabled" == "0" ] && default_proxy_tag="nil"
- [ "$default_proxy_tag" == "nil" ] && filter_rules $default_node $stream
- fi
- local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
- for shunt_id in $shunt_ids; do
- local shunt_node=$(config_n_get $proxy_node "${shunt_id}" nil)
- [ "$shunt_node" == "nil" -o "$shunt_node" == "_default" -o "$shunt_node" == "_direct" -o "$shunt_node" == "_blackhole" ] && continue
- local shunt_node_address=$(config_n_get $shunt_node address)
- [ -z "$shunt_node_address" ] && continue
- local shunt_proxy_tag=$(config_n_get $proxy_node "${shunt_id}_proxy_tag" nil)
- [ "$shunt_proxy_tag" == "main" ] && [ "$preproxy_enabled" == "0" ] && shunt_proxy_tag="nil"
- [ "$shunt_proxy_tag" == "nil" ] && filter_rules $shunt_node $stream
- done
- else
- #echolog " - 普通节点(${proxy_type})..."
- filter_rules "$proxy_node" "$stream"
+ filter_server_port $address $port $stream
+ filter_server_port $address $port $stream
fi
}
+filter_direct_node_list() {
+ [ ! -s "$TMP_PATH/direct_node_list" ] && return
+ for _node_id in $(cat $TMP_PATH/direct_node_list | awk '!seen[$0]++'); do
+ filter_node "$_node_id" TCP
+ filter_node "$_node_id" UDP
+ unset _node_id
+ done
+}
+
add_firewall_rule() {
echolog "开始加载防火墙规则..."
ipset -! create $IPSET_LOCALLIST nethash maxelem 1048576
@@ -866,36 +805,13 @@ add_firewall_rule() {
ip -6 rule add fwmark 1 table 100
ip -6 route add local ::/0 dev lo table 100
-
- # 过滤Socks节点
- [ "$SOCKS_ENABLED" = "1" ] && {
- local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
- #echolog "分析 Socks 服务所使用节点..."
- local id enabled node port msg num
- for id in $ids; do
- enabled=$(config_n_get $id enabled 0)
- [ "$enabled" == "1" ] || continue
- node=$(config_n_get $id node nil)
- port=$(config_n_get $id port 0)
- msg="Socks 服务 [:${port}]"
- if [ "$node" == "nil" ] || [ "$port" == "0" ]; then
- msg="${msg} 未配置完全,略过"
- else
- filter_node $node TCP > /dev/null 2>&1 &
- filter_node $node UDP > /dev/null 2>&1 &
- fi
- #echolog " - ${msg}"
- done
- }
+
+ filter_direct_node_list
[ "$ENABLED_DEFAULT_ACL" == 1 ] && {
local ipt_tmp=$ipt_n
[ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m
- # 过滤节点
- filter_node $NODE TCP > /dev/null 2>&1 &
- filter_node $NODE UDP > /dev/null 2>&1 &
-
TCP_LOCALHOST_PROXY=$LOCALHOST_PROXY
UDP_LOCALHOST_PROXY=$LOCALHOST_PROXY
@@ -972,10 +888,12 @@ add_firewall_rule() {
insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -p tcp -j PSW2_OUTPUT"
fi
- for iface in $(ls ${TMP_IFACE_PATH}); do
- $ipt_n -I PSW2_OUTPUT -o $iface -p tcp -j RETURN
- $ipt_m -I PSW2_OUTPUT -o $iface -p tcp -j RETURN
- done
+ [ -d "${TMP_IFACE_PATH}" ] && {
+ for iface in $(ls ${TMP_IFACE_PATH}); do
+ $ipt_n -I PSW2_OUTPUT -o $iface -p tcp -j RETURN
+ $ipt_m -I PSW2_OUTPUT -o $iface -p tcp -j RETURN
+ done
+ }
fi
# 加载路由器自身代理 UDP
@@ -996,10 +914,12 @@ add_firewall_rule() {
insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -p udp -j PSW2_OUTPUT"
fi
- for iface in $(ls ${TMP_IFACE_PATH}); do
- $ipt_n -I PSW2_OUTPUT -o $iface -p udp -j RETURN
- $ipt_m -I PSW2_OUTPUT -o $iface -p udp -j RETURN
- done
+ [ -d "${TMP_IFACE_PATH}" ] && {
+ for iface in $(ls ${TMP_IFACE_PATH}); do
+ $ipt_n -I PSW2_OUTPUT -o $iface -p udp -j RETURN
+ $ipt_m -I PSW2_OUTPUT -o $iface -p udp -j RETURN
+ done
+ }
fi
$ipt_m -I OUTPUT $(comment "mangle-OUTPUT-PSW2") -o lo -j RETURN
@@ -1179,6 +1099,9 @@ get_wan_ip)
get_wan6_ip)
get_wan6_ip
;;
+filter_direct_node_list)
+ filter_direct_node_list
+ ;;
stop)
stop
;;
diff --git a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh
index 5f7f3a80e..c14c09f96 100755
--- a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh
+++ b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh
@@ -347,9 +347,9 @@ load_acl() {
[ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS
node_remark=$(config_n_get $NODE remarks)
- [ -s "${TMP_ACL_PATH}/${sid}/var_node" ] && node=$(cat ${TMP_ACL_PATH}/${sid}/var_node)
- [ -s "${TMP_ACL_PATH}/${sid}/var_port" ] && redir_port=$(cat ${TMP_ACL_PATH}/${sid}/var_port)
- [ -s "${TMP_ACL_PATH}/${sid}/var_redirect_dns_port" ] && dns_redirect_port=$(cat ${TMP_ACL_PATH}/${sid}/var_redirect_dns_port)
+ [ -n $(get_cache_var "ACL_${sid}_node") ] && node=$(get_cache_var "ACL_${sid}_node")
+ [ -n $(get_cache_var "ACL_${sid}_redir_port") ] && redir_port=$(get_cache_var "ACL_${sid}_redir_port")
+ [ -n $(get_cache_var "ACL_${sid}_dns_port") ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port")
[ "$node" = "default" ] && dns_redirect_port=${DNS_REDIRECT_PORT}
[ -n "$node" ] && [ "$node" != "default" ] && node_remark=$(config_n_get $node remarks)
@@ -634,109 +634,48 @@ filter_vpsip() {
echolog " - [$?]加入所有IPv6节点到nftset[$NFTSET_VPSLIST6]直连完成"
}
+filter_server_port() {
+ local address=${1}
+ local port=${2}
+ local stream=${3}
+ stream=$(echo ${3} | tr 'A-Z' 'a-z')
+ local _is_tproxy
+ _is_tproxy=${is_tproxy}
+ [ "$stream" == "udp" ] && _is_tproxy="TPROXY"
+
+ for _ipt in 4 6; do
+ [ "$_ipt" == "4" ] && _ip_type=ip
+ [ "$_ipt" == "6" ] && _ip_type=ip6
+ nft "list chain $NFTABLE_NAME $nft_output_chain" 2>/dev/null | grep -q "${address}:${port}"
+ if [ $? -ne 0 ]; then
+ nft "insert rule $NFTABLE_NAME $nft_output_chain meta l4proto $stream $_ip_type daddr $address $stream dport $port return comment \"${address}:${port}\"" 2>/dev/null
+ fi
+ done
+}
+
filter_node() {
- local proxy_node=${1}
- local stream=$(echo ${2} | tr 'A-Z' 'a-z')
- local proxy_port=${3}
-
- filter_rules() {
- local node=${1}
- local stream=${2}
- local _proxy=${3}
- local _port=${4}
- local _is_tproxy msg msg2
-
- if [ -n "$node" ] && [ "$node" != "nil" ]; then
- local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
- local address=$(config_n_get $node address)
- local port=$(config_n_get $node port)
- [ -z "$address" ] && [ -z "$port" ] && {
- echolog " - 节点配置不正常,略过"
- return 1
- }
- _is_tproxy=${is_tproxy}
- [ "$stream" == "udp" ] && _is_tproxy="TPROXY"
- if [ -n "${_is_tproxy}" ]; then
- msg="TPROXY"
- else
- msg="REDIRECT"
- fi
- else
- echolog " - 节点配置不正常,略过"
+ local node=${1}
+ local stream=${2}
+ if [ -n "$node" ] && [ "$node" != "nil" ]; then
+ local address=$(config_n_get $node address)
+ local port=$(config_n_get $node port)
+ [ -z "$address" ] && [ -z "$port" ] && {
return 1
- fi
-
- local ADD_INDEX=$FORCE_INDEX
- for _ipt in 4 6; do
- [ "$_ipt" == "4" ] && _ip_type=ip && _set_name=$NFTSET_VPSLIST
- [ "$_ipt" == "6" ] && _ip_type=ip6 && _set_name=$NFTSET_VPSLIST6
- nft "list chain $NFTABLE_NAME $nft_output_chain" 2>/dev/null | grep -q "${address}:${port}"
- if [ $? -ne 0 ]; then
- local dst_rule="jump PSW2_RULE"
- msg2="按规则路由(${msg})"
- [ -n "${is_tproxy}" ] || {
- dst_rule=$(REDIRECT $_port)
- msg2="套娃使用(${msg}:${port} -> ${_port})"
- }
- [ -n "$_proxy" ] && [ "$_proxy" == "1" ] && [ -n "$_port" ] || {
- ADD_INDEX=$(RULE_LAST_INDEX "$NFTABLE_NAME" $nft_output_chain $_set_name $FORCE_INDEX)
- dst_rule="return"
- msg2="直连代理"
- }
- nft "insert rule $NFTABLE_NAME $nft_output_chain position $ADD_INDEX meta l4proto $stream $_ip_type daddr $address $stream dport $port $dst_rule comment \"${address}:${port}\"" 2>/dev/null
- else
- msg2="已配置过的节点,"
- fi
- done
- msg="[$?]$(echo ${2} | tr 'a-z' 'A-Z')${msg2}使用链${ADD_INDEX},节点(${type}):${address}:${port}"
- #echolog " - ${msg}"
- }
-
- local proxy_protocol=$(config_n_get $proxy_node protocol)
- local proxy_type=$(echo $(config_n_get $proxy_node type nil) | tr 'A-Z' 'a-z')
- [ "$proxy_type" == "nil" ] && echolog " - 节点配置不正常,略过!:${proxy_node}" && return 1
- if [ "$proxy_protocol" == "_balancing" ]; then
- #echolog " - 多节点负载均衡(${proxy_type})..."
- proxy_node=$(config_n_get $proxy_node balancing_node)
- for _node in $proxy_node; do
- filter_rules "$_node" "$stream"
- done
- elif [ "$proxy_protocol" == "_shunt" ]; then
- #echolog " - 按请求目的地址分流(${proxy_type})..."
- local preproxy_enabled=$(config_n_get $proxy_node preproxy_enabled 0)
- [ "$preproxy_enabled" == "1" ] && {
- local preproxy_node=$(config_n_get $proxy_node main_node nil)
- [ "$preproxy_node" != "nil" ] && {
- local preproxy_node_address=$(config_n_get $preproxy_node address)
- if [ -n "$preproxy_node_address" ]; then
- filter_rules $preproxy_node $stream
- else
- preproxy_enabled=0
- fi
- }
}
- local default_node=$(config_n_get $proxy_node default_node _direct)
- if [ "$default_node" != "_direct" ] && [ "$default_node" != "_blackhole" ]; then
- local default_proxy_tag=$(config_n_get $proxy_node default_proxy_tag nil)
- [ "$default_proxy_tag" == "main" ] && [ "$preproxy_enabled" == "0" ] && default_proxy_tag="nil"
- [ "$default_proxy_tag" == "nil" ] && filter_rules $default_node $stream
- fi
- local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
- for shunt_id in $shunt_ids; do
- local shunt_node=$(config_n_get $proxy_node "${shunt_id}" nil)
- [ "$shunt_node" == "nil" -o "$shunt_node" == "_default" -o "$shunt_node" == "_direct" -o "$shunt_node" == "_blackhole" ] && continue
- local shunt_node_address=$(config_n_get $shunt_node address)
- [ -z "$shunt_node_address" ] && continue
- local shunt_proxy_tag=$(config_n_get $proxy_node "${shunt_id}_proxy_tag" nil)
- [ "$shunt_proxy_tag" == "main" ] && [ "$preproxy_enabled" == "0" ] && shunt_proxy_tag="nil"
- [ "$shunt_proxy_tag" == "nil" ] && filter_rules $shunt_node $stream
- done
- else
- #echolog " - 普通节点(${proxy_type})..."
- filter_rules "$proxy_node" "$stream"
+ filter_server_port $address $port $stream
+ filter_server_port $address $port $stream
fi
}
+filter_direct_node_list() {
+ [ ! -s "$TMP_PATH/direct_node_list" ] && return
+ for _node_id in $(cat $TMP_PATH/direct_node_list | awk '!seen[$0]++'); do
+ filter_node "$_node_id" TCP
+ filter_node "$_node_id" UDP
+ unset _node_id
+ done
+}
+
add_firewall_rule() {
echolog "开始加载防火墙规则..."
gen_nft_tables
@@ -922,33 +861,10 @@ add_firewall_rule() {
ip -6 rule add fwmark 1 table 100
ip -6 route add local ::/0 dev lo table 100
}
-
- # 过滤Socks节点
- [ "$SOCKS_ENABLED" = "1" ] && {
- local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
- #echolog "分析 Socks 服务所使用节点..."
- local id enabled node port msg num
- for id in $ids; do
- enabled=$(config_n_get $id enabled 0)
- [ "$enabled" == "1" ] || continue
- node=$(config_n_get $id node nil)
- port=$(config_n_get $id port 0)
- msg="Socks 服务 [:${port}]"
- if [ "$node" == "nil" ] || [ "$port" == "0" ]; then
- msg="${msg} 未配置完全,略过"
- else
- filter_node $node TCP > /dev/null 2>&1 &
- filter_node $node UDP > /dev/null 2>&1 &
- fi
- #echolog " - ${msg}"
- done
- }
+
+ filter_direct_node_list
[ "$ENABLED_DEFAULT_ACL" == 1 ] && {
- # 过滤节点
- filter_node $NODE TCP > /dev/null 2>&1 &
- filter_node $NODE UDP > /dev/null 2>&1 &
-
TCP_LOCALHOST_PROXY=$LOCALHOST_PROXY
UDP_LOCALHOST_PROXY=$LOCALHOST_PROXY
@@ -1026,10 +942,12 @@ add_firewall_rule() {
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo counter return comment \"本机\""
}
- for iface in $(ls ${TMP_IFACE_PATH}); do
- nft "insert rule $NFTABLE_NAME $nft_output_chain ip protocol tcp oif $iface counter return"
- nft "insert rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol tcp oif $iface counter return"
- done
+ [ -d "${TMP_IFACE_PATH}" ] && {
+ for iface in $(ls ${TMP_IFACE_PATH}); do
+ nft "insert rule $NFTABLE_NAME $nft_output_chain ip protocol tcp oif $iface counter return"
+ nft "insert rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol tcp oif $iface counter return"
+ done
+ }
fi
# 加载路由器自身代理 UDP
@@ -1049,10 +967,12 @@ add_firewall_rule() {
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo counter return comment \"本机\""
fi
- for iface in $(ls ${TMP_IFACE_PATH}); do
- nft "insert rule $NFTABLE_NAME $nft_output_chain ip protocol udp oif $iface counter return"
- nft "insert rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol udp oif $iface counter return"
- done
+ [ -d "${TMP_IFACE_PATH}" ] && {
+ for iface in $(ls ${TMP_IFACE_PATH}); do
+ nft "insert rule $NFTABLE_NAME $nft_output_chain ip protocol udp oif $iface counter return"
+ nft "insert rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol udp oif $iface counter return"
+ done
+ }
fi
nft "add rule $NFTABLE_NAME mangle_output oif lo counter return comment \"PSW2_OUTPUT_MANGLE\""
@@ -1065,16 +985,6 @@ add_firewall_rule() {
# 加载ACLS
load_acl
- [ -n "${is_tproxy}" -o -n "${udp_flag}" ] && {
- bridge_nf_ipt=$(sysctl -e -n net.bridge.bridge-nf-call-iptables)
- echo -n $bridge_nf_ipt > $TMP_PATH/bridge_nf_ipt
- sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1
- [ "$PROXY_IPV6" == "1" ] && {
- bridge_nf_ip6t=$(sysctl -e -n net.bridge.bridge-nf-call-ip6tables)
- echo -n $bridge_nf_ip6t > $TMP_PATH/bridge_nf_ip6t
- sysctl -w net.bridge.bridge-nf-call-ip6tables=0 >/dev/null 2>&1
- }
- }
echolog "防火墙规则加载完成!"
}
@@ -1208,6 +1118,9 @@ get_wan_ip)
get_wan6_ip)
get_wan6_ip
;;
+filter_direct_node_list)
+ filter_direct_node_list
+ ;;
stop)
stop
;;
diff --git a/luci-app-passwall2/root/usr/share/passwall2/socks_auto_switch.sh b/luci-app-passwall2/root/usr/share/passwall2/socks_auto_switch.sh
index 563bf57ea..ee4e88d8a 100755
--- a/luci-app-passwall2/root/usr/share/passwall2/socks_auto_switch.sh
+++ b/luci-app-passwall2/root/usr/share/passwall2/socks_auto_switch.sh
@@ -78,9 +78,8 @@ test_auto_switch() {
local b_nodes=$1
local now_node=$2
[ -z "$now_node" ] && {
- local f="/tmp/etc/$CONFIG/id/socks_${id}"
- if [ -f "${f}" ]; then
- now_node=$(cat ${f})
+ if [ -n $(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}") ]; then
+ now_node=$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}")
else
#echolog "自动切换检测:未知错误"
return 1
diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua
index 29e46ecc6..a52f7ba81 100755
--- a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua
+++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua
@@ -312,6 +312,23 @@ do
}
end
else
+ --前置代理节点
+ local currentNode = uci:get_all(appname, node_id) or nil
+ if currentNode and currentNode.preproxy_node then
+ CONFIG[#CONFIG + 1] = {
+ log = true,
+ id = node_id,
+ remarks = "节点[" .. node_id .. "]前置代理节点",
+ currentNode = uci:get_all(appname, currentNode.preproxy_node) or nil,
+ set = function(o, server)
+ uci:set(appname, node_id, "preproxy_node", server)
+ o.newNodeId = server
+ end,
+ delete = function(o)
+ uci:delete(appname, node_id, "preproxy_node")
+ end
+ }
+ end
--落地节点
local currentNode = uci:get_all(appname, node_id) or nil
if currentNode and currentNode.to_node then