From 449b511fa268b30c763cedbb60bda3cbb23bfa75 Mon Sep 17 00:00:00 2001 From: sbwml Date: Wed, 28 Aug 2024 01:00:12 +0800 Subject: [PATCH] luci-app-passwall2: sync upstream last commit: https://github.com/xiaorouji/openwrt-passwall2/commit/3118247934ef2995ae6298f6a615f0674b6b95a9 --- luci-app-passwall2/Makefile | 2 +- .../luasrc/controller/passwall2.lua | 4 +- .../model/cbi/passwall2/client/global.lua | 2 - .../model/cbi/passwall2/client/haproxy.lua | 16 +- .../model/cbi/passwall2/client/type/ray.lua | 14 +- .../cbi/passwall2/client/type/sing-box.lua | 8 +- .../passwall2/node_list/link_share_man.htm | 345 ++++++++++--- .../root/usr/share/passwall2/app.sh | 4 +- .../root/usr/share/passwall2/haproxy.lua | 8 + .../root/usr/share/passwall2/haproxy_check.sh | 12 +- .../usr/share/passwall2/helper_dnsmasq.sh | 4 +- .../root/usr/share/passwall2/nftables.sh | 465 +++++++++--------- .../root/usr/share/passwall2/subscribe.lua | 94 +++- 13 files changed, 645 insertions(+), 333 deletions(-) mode change 100644 => 100755 luci-app-passwall2/root/usr/share/passwall2/app.sh diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile index 2f24ea6aa..3be1733d1 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:=1.30-3 +PKG_VERSION:=1.31-1 PKG_RELEASE:= PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall2/luasrc/controller/passwall2.lua b/luci-app-passwall2/luasrc/controller/passwall2.lua index ed5d250d0..0f4b00371 100644 --- a/luci-app-passwall2/luasrc/controller/passwall2.lua +++ b/luci-app-passwall2/luasrc/controller/passwall2.lua @@ -22,9 +22,9 @@ function index() entry({"admin", "services", appname, "hide"}, call("hide_menu")).leaf = true local e if uci:get(appname, "@global[0]", "hide_from_luci") ~= "1" then - e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), _("PassWall 2"), -1) + e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), _("PassWall 2"), 0) else - e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), nil, -1) + e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), nil, 0) end e.dependent = true e.acl_depends = { "luci-app-passwall2" } diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua index cc3654602..6e3ea5c9f 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua @@ -337,8 +337,6 @@ for k, v in pairs(nodes_table) do s.fields["remote_dns_client_ip"]:depends({ node = v.id, remote_dns_protocol = "tcp" }) s.fields["remote_dns_client_ip"]:depends({ node = v.id, remote_dns_protocol = "doh" }) s.fields["dns_hosts"]:depends({ node = v.id }) - elseif v.type == "sing-box" then - s.fields["direct_dns_query_strategy"]:depends({ node = v.id }) end end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/haproxy.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/haproxy.lua index be9cfbc07..1fc9806c3 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/haproxy.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/haproxy.lua @@ -19,7 +19,7 @@ m = Map(appname) api.set_apply_on_parse(m) -- [[ Haproxy Settings ]]-- -s = m:section(TypedSection, "global_haproxy") +s = m:section(TypedSection, "global_haproxy", translate("Basic Settings")) s.anonymous = true s:append(Template(appname .. "/haproxy/status")) @@ -57,6 +57,18 @@ o:value("tcp", "TCP") o:value("passwall_logic", translate("URL Test") .. string.format("(passwall %s)", translate("Inner implement"))) o:depends("balancing_enable", true) +---- Passwall Inner implement Probe URL +o = s:option(Value, "health_probe_url", translate("Probe URL")) +o.default = "https://www.google.com/generate_204" +o:value("https://cp.cloudflare.com/", "Cloudflare") +o:value("https://www.gstatic.com/generate_204", "Gstatic") +o:value("https://www.google.com/generate_204", "Google") +o:value("https://www.youtube.com/generate_204", "YouTube") +o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") +o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") +o.description = translate("The URL used to detect the connection status.") +o:depends("health_check_type", "passwall_logic") + ---- Health Check Inter o = s:option(Value, "health_check_inter", translate("Health Check Inter"), translate("Units:seconds")) o.default = "60" @@ -70,7 +82,7 @@ end o:depends("health_check_type", "passwall_logic") -- [[ Balancing Settings ]]-- -s = m:section(TypedSection, "haproxy_config", "", +s = m:section(TypedSection, "haproxy_config", translate("Node List"), "" .. translate("Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group.") .. "\n" .. translate("Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!") .. 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 bb4aea440..32f72bde4 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 @@ -17,7 +17,7 @@ local function option_name(name) return option_prefix .. name end -local x_ss_encrypt_method_list = { +local ss_method_list = { "aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" } @@ -298,16 +298,16 @@ o.default = "none" o:value("none") o:depends({ [option_name("protocol")] = "vless" }) -o = s:option(ListValue, option_name("x_ss_encrypt_method"), translate("Encrypt Method")) +o = s:option(ListValue, option_name("ss_method"), translate("Encrypt Method")) o.rewrite_option = "method" -for a, t in ipairs(x_ss_encrypt_method_list) do o:value(t) end +for a, t in ipairs(ss_method_list) do o:value(t) end o:depends({ [option_name("protocol")] = "shadowsocks" }) o = s:option(Flag, option_name("iv_check"), translate("IV Check")) -o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "aes-128-gcm" }) -o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "aes-256-gcm" }) -o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "chacha20-poly1305" }) -o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "xchacha20-poly1305" }) +o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "aes-128-gcm" }) +o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "aes-256-gcm" }) +o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "chacha20-poly1305" }) +o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "xchacha20-poly1305" }) o = s:option(Flag, option_name("uot"), translate("UDP over TCP")) o:depends({ [option_name("protocol")] = "shadowsocks" }) 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 cc0f31f49..d47f7a267 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 @@ -372,13 +372,17 @@ o:depends({ [option_name("protocol")] = "vmess" }) o:depends({ [option_name("protocol")] = "vless" }) o:depends({ [option_name("protocol")] = "http" }) o:depends({ [option_name("protocol")] = "trojan" }) +o:depends({ [option_name("protocol")] = "shadowsocks" }) o = s:option(ListValue, option_name("alpn"), translate("alpn")) o.default = "default" o:value("default", translate("Default")) -o:value("h2,http/1.1") +o:value("h3") o:value("h2") +o:value("h3,h2") o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") o:depends({ [option_name("tls")] = true }) o = s:option(Value, option_name("tls_serverName"), translate("Domain")) @@ -386,6 +390,7 @@ o:depends({ [option_name("tls")] = true }) o:depends({ [option_name("protocol")] = "hysteria"}) o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [option_name("protocol")] = "hysteria2" }) +o:depends({ [option_name("protocol")] = "shadowsocks" }) o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) o.default = "0" @@ -393,6 +398,7 @@ o:depends({ [option_name("tls")] = true }) o:depends({ [option_name("protocol")] = "hysteria"}) o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [option_name("protocol")] = "hysteria2" }) +o:depends({ [option_name("protocol")] = "shadowsocks" }) if singbox_tags:find("with_ech") then o = s:option(Flag, option_name("ech"), translate("ECH")) diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_list/link_share_man.htm b/luci-app-passwall2/luasrc/view/passwall2/node_list/link_share_man.htm index 8297c5968..4026b2f71 100644 --- a/luci-app-passwall2/luasrc/view/passwall2/node_list/link_share_man.htm +++ b/luci-app-passwall2/luasrc/view/passwall2/node_list/link_share_man.htm @@ -197,6 +197,63 @@ local api = require "luci.passwall2.api" } params += "&plugin=" + encodeURIComponent(v_plugin); } + } else { + var v_transport = opt.get(dom_prefix + "transport").value; + if (v_transport === "ws") { + params += opt.query("host", dom_prefix + "ws_host"); + params += opt.query("path", dom_prefix + "ws_path"); + if (v_type == "sing-box" && opt.get(dom_prefix + "ws_enableEarlyData").checked) { + var ws_maxEarlyData = opt.get(dom_prefix + "ws_maxEarlyData").value; + params += "?ed=" + ws_maxEarlyData; + } + } else if (v_transport === "h2") { + v_transport = "http"; + params += opt.query("host", dom_prefix + "h2_host"); + params += opt.query("path", dom_prefix + "h2_path"); + } else if (v_transport === "tcp") { + params += opt.query("headerType", dom_prefix + "tcp_guise"); + params += opt.query("host", dom_prefix + "tcp_guise_http_host"); + params += opt.query("path", dom_prefix + "tcp_guise_http_path"); + } else if (v_transport === "mkcp") { + v_transport = "kcp"; + params += opt.query("headerType", dom_prefix + "mkcp_guise"); + } else if (v_transport === "quic") { + params += opt.query("headerType", dom_prefix + "quic_guise"); + params += opt.query("key", dom_prefix + "quic_key"); + params += opt.query("quicSecurity", dom_prefix + "quic_security"); + } else if (v_transport === "grpc") { + params += opt.query("path", dom_prefix + "grpc_serviceName"); + params += opt.query("serviceName", dom_prefix + "grpc_serviceName"); + params += opt.query("mode", dom_prefix + "grpc_mode"); + } + params += "&type=" + v_transport; + + params += opt.query("encryption", dom_prefix + "encryption"); + + if (opt.get(dom_prefix + "tls").checked) { + var v_security = "tls"; + if (opt.get(dom_prefix + "fingerprint") && opt.get(dom_prefix + "fingerprint").value != "") { + let v_fp = opt.get(dom_prefix + "fingerprint").value; + params += "&fp=" + v_fp; + } + if (opt.get(dom_prefix + "reality") && opt.get(dom_prefix + "reality").checked) { + v_security = "reality"; + if (opt.get(dom_prefix + "fingerprint") && opt.get(dom_prefix + "fingerprint").value != "") { + let v_fp = opt.get(dom_prefix + "fingerprint").value; + params += "&fp=" + v_fp; + } + params += opt.query("pbk", dom_prefix + "reality_publicKey"); + params += opt.query("sid", dom_prefix + "reality_shortId"); + params += opt.query("spx", dom_prefix + "reality_spiderX"); + } + if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) { + let v_flow = opt.get(dom_prefix + "flow").value; + params += "&flow=" + v_flow; + } + params += "&security=" + v_security; + params += opt.query("alpn", dom_prefix + "alpn"); + params += opt.query("sni", dom_prefix + "tls_serverName"); + } } params += "&group=" params += "#" + encodeURIComponent(v_alias.value); @@ -350,38 +407,61 @@ local api = require "luci.passwall2.api" "@" + _address + ":" + v_port.value + "/?"; var params = ""; - if (opt.get(dom_prefix + "tls").checked) { - params += opt.query("sni", dom_prefix + "tls_serverName"); - params += "&security=tls" - params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure"); + var v_transport = opt.get(dom_prefix + "transport").value; + if (v_transport === "ws") { + params += opt.query("host", dom_prefix + "ws_host"); + params += opt.query("path", dom_prefix + "ws_path"); + if (v_type == "sing-box" && opt.get(dom_prefix + "ws_enableEarlyData").checked) { + var ws_maxEarlyData = opt.get(dom_prefix + "ws_maxEarlyData").value; + params += "?ed=" + ws_maxEarlyData; + } + } else if (v_transport === "h2") { + v_transport = "http"; + params += opt.query("host", dom_prefix + "h2_host"); + params += opt.query("path", dom_prefix + "h2_path"); + } else if (v_transport === "tcp") { + params += opt.query("headerType", dom_prefix + "tcp_guise"); + params += opt.query("host", dom_prefix + "tcp_guise_http_host"); + params += opt.query("path", dom_prefix + "tcp_guise_http_path"); + } else if (v_transport === "mkcp") { + v_transport = "kcp"; + params += opt.query("headerType", dom_prefix + "mkcp_guise"); + } else if (v_transport === "quic") { + params += opt.query("headerType", dom_prefix + "quic_guise"); + params += opt.query("key", dom_prefix + "quic_key"); + params += opt.query("quicSecurity", dom_prefix + "quic_security"); + } else if (v_transport === "grpc") { + params += opt.query("path", dom_prefix + "grpc_serviceName"); + params += opt.query("serviceName", dom_prefix + "grpc_serviceName"); + params += opt.query("mode", dom_prefix + "grpc_mode"); } - // 获取transport参数并设置type - var transport = opt.get(dom_prefix + "transport").value || ""; - switch (transport.toLowerCase()) { - case 'tcp': - params += "&type=tcp"; - break; - case 'ws': - params += "&type=ws"; - break; - case 'kcp': - params += "&type=kcp"; - break; - case 'mkcp': - params += "&type=kcp"; - break; - case 'http': - params += "&type=http"; - break; - case 'h2': - params += "&type=h2"; - break; - case 'grpc': - params += "&type=grpc"; - break; - default: - // 默认不添加type参数 - break; + params += "&type=" + v_transport; + + params += opt.query("encryption", dom_prefix + "encryption"); + + if (opt.get(dom_prefix + "tls").checked) { + var v_security = "tls"; + if (opt.get(dom_prefix + "fingerprint") && opt.get(dom_prefix + "fingerprint").value != "") { + let v_fp = opt.get(dom_prefix + "fingerprint").value; + params += "&fp=" + v_fp; + } + if (opt.get(dom_prefix + "reality") && opt.get(dom_prefix + "reality").checked) { + v_security = "reality"; + if (opt.get(dom_prefix + "fingerprint") && opt.get(dom_prefix + "fingerprint").value != "") { + let v_fp = opt.get(dom_prefix + "fingerprint").value; + params += "&fp=" + v_fp; + } + params += opt.query("pbk", dom_prefix + "reality_publicKey"); + params += opt.query("sid", dom_prefix + "reality_shortId"); + params += opt.query("spx", dom_prefix + "reality_spiderX"); + } + if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) { + let v_flow = opt.get(dom_prefix + "flow").value; + params += "&flow=" + v_flow; + } + params += "&security=" + v_security; + params += opt.query("alpn", dom_prefix + "alpn"); + params += opt.query("sni", dom_prefix + "tls_serverName"); } params += "#" + encodeURI(v_alias.value); if (params[0] == "&") { @@ -621,17 +701,26 @@ local api = require "luci.passwall2.api" if (sipIndex !== -1) { // SIP002 var userInfo = b64decsafe(url0.substr(0, sipIndex)); - var temp = url0.substr(sipIndex + 1).split("/?"); + var temp = url0.substr(sipIndex + 1).replace('/?', '?').split('?'); var serverInfo = temp[0].split(":"); var server = serverInfo[0]; var port = serverInfo[1]; var method, password, plugin, pluginOpts; + var queryParam = {}; if (temp[1]) { - var pluginInfo = decodeURIComponent(temp[1]); - var pluginIndex = pluginInfo.indexOf(";"); - var pluginNameInfo = pluginInfo.substr(0, pluginIndex); - plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1) - pluginOpts = pluginInfo.substr(pluginIndex + 1).split("&")[0]; + var queryArray = temp[1].split('&'); + var params; + for (var i = 0; i < queryArray.length; i++) { + params = queryArray[i].split('='); + queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || ''); + } + if (queryParam.plugin) { + var pluginInfo = decodeURIComponent(temp[1]); + var pluginIndex = pluginInfo.indexOf(";"); + var pluginNameInfo = pluginInfo.substr(0, pluginIndex); + plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1) + pluginOpts = pluginInfo.substr(pluginIndex + 1).split("&")[0]; + } } var userInfoSplitIndex = userInfo.indexOf(":"); if (userInfoSplitIndex !== -1) { @@ -659,12 +748,94 @@ local api = require "luci.passwall2.api" opt.set(dom_prefix + 'port', port); opt.set(dom_prefix + 'password', password || ""); opt.set(dom_prefix + 'method', method || ""); + opt.set(dom_prefix + 'ss_method', method || ""); opt.set(dom_prefix + 'plugin', plugin || "none"); if (plugin && plugin != "none") { opt.set(dom_prefix + 'plugin_opts', pluginOpts || ""); + opt.set(dom_prefix + 'plugin_enabled', true); } if (param !== undefined) { - opt.set('remarks', decodeURI(param)); + opt.set('remarks', decodeURIComponent(param)); + } + if (!queryParam.plugin && (dom_prefix == "singbox_" || dom_prefix == "xray_")) { + opt.set(dom_prefix + 'encryption', queryParam.encryption); + if (queryParam.security) { + if (queryParam.security == "tls") { + opt.set(dom_prefix + 'tls', true); + opt.set(dom_prefix + 'reality', false) + opt.set(dom_prefix + 'flow', queryParam.flow || ''); + opt.set(dom_prefix + 'alpn', queryParam.alpn || ''); + opt.set(dom_prefix + 'tls_serverName', queryParam.sni || ''); + opt.set(dom_prefix + 'tls_allowInsecure', true); + if (queryParam.allowinsecure === '0') { + opt.set(dom_prefix + 'tls_allowInsecure', false); + } + if (queryParam.fp && queryParam.fp.trim() != "") { + opt.set(dom_prefix + 'fingerprint', queryParam.fp); + } + } + + if (queryParam.security == "reality") { + opt.set(dom_prefix + 'tls', true); + opt.set(dom_prefix + 'reality', true) + opt.set(dom_prefix + 'flow', queryParam.flow || ''); + opt.set(dom_prefix + 'tls_serverName', queryParam.sni || ''); + if (queryParam.fp && queryParam.fp.trim() != "") { + opt.set(dom_prefix + 'fingerprint', queryParam.fp); + } + opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || ''); + opt.set(dom_prefix + 'reality_shortId', queryParam.sid || ''); + opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || ''); + } + + } + + queryParam.type = queryParam.type.toLowerCase(); + if (queryParam.type === "kcp" || queryParam.type === "mkcp") + queryParam.type = "mkcp" + if (queryParam.type === "h2" || queryParam.type === "http") + queryParam.type = "h2" + opt.set(dom_prefix + 'transport', queryParam.type); + if (queryParam.type === "tcp") { + opt.set(dom_prefix + 'tcp_guise', queryParam.headerType || "none"); + if (queryParam.headerType && queryParam.headerType != "none") { + opt.set(dom_prefix + 'tcp_guise_http_host', queryParam.host || ""); + opt.set(dom_prefix + 'tcp_guise_http_path', queryParam.path || ""); + } + } else if (queryParam.type === "ws") { + opt.set(dom_prefix + 'ws_host', queryParam.host || ""); + opt.set(dom_prefix + 'ws_path', queryParam.path || ""); + if (dom_prefix == "singbox_" && queryParam.path && queryParam.path.length > 1) { + var ws_path_params = {}; + var ws_path_dat = queryParam.path.split('?'); + var ws_path = ws_path_dat[0]; + var ws_path_params = {}; + var ws_path_params_array = (ws_path_dat[1] || '').split('&'); + for (i = 0; i < ws_path_params_array.length; i++) { + var kv = ws_path_params_array[i].split('='); + ws_path_params[decodeURIComponent(kv[0]).toLowerCase()] = decodeURIComponent(kv[1] || ''); + } + + if (ws_path_params.ed) { + opt.set(dom_prefix + 'ws_path', ws_path); + opt.set(dom_prefix + 'ws_enableEarlyData', true); + opt.set(dom_prefix + 'ws_maxEarlyData', ws_path_params.ed); + opt.set(dom_prefix + 'ws_earlyDataHeaderName', 'Sec-WebSocket-Protocol'); + } + } + } else if (queryParam.type === "h2" || queryParam.type === "http") { + opt.set(dom_prefix + 'h2_host', queryParam.host || ""); + opt.set(dom_prefix + 'h2_path', queryParam.path || ""); + } else if (queryParam.type === "quic") { + opt.set(dom_prefix + 'quic_guise', queryParam.headerType || "none"); + opt.set(dom_prefix + 'quic_security', queryParam.quicSecurity); + opt.set(dom_prefix + 'quic_key', queryParam.key); + } else if (queryParam.type === "kcp" || queryParam.type === "mkcp") { + opt.set(dom_prefix + 'mkcp_guise', queryParam.headerType || "none"); + } else if (queryParam.type === "grpc") { + opt.set(dom_prefix + 'grpc_serviceName', (queryParam.serviceName || queryParam.path) || ""); + opt.set(dom_prefix + 'grpc_mode', queryParam.mode); + } } } else { var sstr = b64decsafe(url0); @@ -689,10 +860,11 @@ local api = require "luci.passwall2.api" opt.set(dom_prefix + 'port', part2[1]); opt.set(dom_prefix + 'password', part1[1]); opt.set(dom_prefix + 'method', part1[0]); + opt.set(dom_prefix + 'ss_method', part1[0]); opt.set(dom_prefix + 'plugin', "none"); //opt.set(dom_prefix + 'plugin_opts', ""); if (param !== undefined) { - opt.set('remarks', decodeURI(param)); + opt.set('remarks', decodeURIComponent(param)); } } } @@ -705,7 +877,7 @@ local api = require "luci.passwall2.api" } var queryParam = {}; if (m.search.length > 1) { - var query = m.search.split('?'); + var query = m.search.replace('/?', '?').split('?'); var queryParams = query[1]; var queryArray = queryParams.split('&'); var params; @@ -721,43 +893,62 @@ local api = require "luci.passwall2.api" dom_prefix = "xray_" opt.set('type', "Xray"); } + opt.set(dom_prefix + 'mux', queryParam.mux === '1'); opt.set(dom_prefix + 'protocol', "trojan"); opt.set(dom_prefix + 'address', m.hostname); opt.set(dom_prefix + 'port', m.port || "443"); opt.set(dom_prefix + 'password', decodeURIComponent(password)); - opt.set(dom_prefix + 'tls', queryParam.security === "tls" ? "1" : "0"); - opt.set(dom_prefix + 'tls_serverName', queryParam.peer || queryParam.sni || ''); - opt.set(dom_prefix + 'tls_allowInsecure', queryParam.allowinsecure === '1'); - opt.set(dom_prefix + 'mux', queryParam.mux === '1'); - // 根据type参数设置transport - var transportType = queryParam.type || ""; - switch (transportType.toLowerCase()) { - case 'tcp': - opt.set(dom_prefix + 'transport', 'tcp'); - break; - case 'ws': - opt.set(dom_prefix + 'transport', 'ws'); - break; - case 'kcp': - opt.set(dom_prefix + 'transport', 'mkcp'); - break; - case 'mkcp': - opt.set(dom_prefix + 'transport', 'mkcp'); - break; - case 'http': - opt.set(dom_prefix + 'transport', 'http'); - break; - case 'h2': - opt.set(dom_prefix + 'transport', 'h2'); - break; - case 'grpc': - opt.set(dom_prefix + 'transport', 'grpc'); - break; - default: - opt.set(dom_prefix + 'transport', ''); // 默认清空transport + + queryParam.type = queryParam.type.toLowerCase(); + if (queryParam.type === "kcp" || queryParam.type === "mkcp") + queryParam.type = "mkcp" + if (queryParam.type === "h2" || queryParam.type === "http") + queryParam.type = "h2" + opt.set(dom_prefix + 'transport', queryParam.type); + if (queryParam.type === "tcp") { + opt.set(dom_prefix + 'tcp_guise', queryParam.headerType || "none"); + if (queryParam.headerType && queryParam.headerType != "none") { + opt.set(dom_prefix + 'tcp_guise_http_host', queryParam.host || ""); + opt.set(dom_prefix + 'tcp_guise_http_path', queryParam.path || ""); + } + } else if (queryParam.type === "ws") { + opt.set(dom_prefix + 'ws_host', queryParam.host || ""); + opt.set(dom_prefix + 'ws_path', queryParam.path || ""); + if (dom_prefix == "singbox_" && queryParam.path && queryParam.path.length > 1) { + var ws_path_params = {}; + var ws_path_dat = queryParam.path.split('?'); + var ws_path = ws_path_dat[0]; + var ws_path_params = {}; + var ws_path_params_array = (ws_path_dat[1] || '').split('&'); + for (i = 0; i < ws_path_params_array.length; i++) { + var kv = ws_path_params_array[i].split('='); + ws_path_params[decodeURIComponent(kv[0]).toLowerCase()] = decodeURIComponent(kv[1] || ''); + } + + if (ws_path_params.ed) { + opt.set(dom_prefix + 'ws_path', ws_path); + opt.set(dom_prefix + 'ws_enableEarlyData', true); + opt.set(dom_prefix + 'ws_maxEarlyData', ws_path_params.ed); + opt.set(dom_prefix + 'ws_earlyDataHeaderName', 'Sec-WebSocket-Protocol'); + } + } + } else if (queryParam.type === "h2" || queryParam.type === "http") { + opt.set(dom_prefix + 'h2_host', queryParam.host || ""); + opt.set(dom_prefix + 'h2_path', queryParam.path || ""); + } else if (queryParam.type === "quic") { + opt.set(dom_prefix + 'quic_guise', queryParam.headerType || "none"); + opt.set(dom_prefix + 'quic_security', queryParam.quicSecurity); + opt.set(dom_prefix + 'quic_key', queryParam.key); + } else if (queryParam.type === "kcp" || queryParam.type === "mkcp") { + opt.set(dom_prefix + 'mkcp_guise', queryParam.headerType || "none"); + } else if (queryParam.type === "grpc") { + opt.set(dom_prefix + 'grpc_serviceName', (queryParam.serviceName || queryParam.path) || ""); + opt.set(dom_prefix + 'grpc_mode', queryParam.mode); } + + opt.set(dom_prefix + 'mux', queryParam.mux === '1'); if (m.hash) { - opt.set('remarks', decodeURI(m.hash.substr(1))); + opt.set('remarks', decodeURIComponent(m.hash.substr(1))); } } if (ssu[0] === "vmess") { @@ -808,7 +999,7 @@ local api = require "luci.passwall2.api" var ws_path_dat = ssm.path.split('?'); var ws_path = ws_path_dat[0]; var ws_path_params = {}; - var ws_path_params_array = ws_path_dat[1].split('&'); + var ws_path_params_array = (ws_path_dat[1] || '').split('&'); for (i = 0; i < ws_path_params_array.length; i++) { var kv = ws_path_params_array[i].split('='); ws_path_params[decodeURIComponent(kv[0]).toLowerCase()] = decodeURIComponent(kv[1] || ''); @@ -854,7 +1045,7 @@ local api = require "luci.passwall2.api" opt.set(dom_prefix + 'port', m.port || "443"); var queryParam = {}; if (m.search.length > 1) { - var query = m.search.split('?'); + var query = m.search.replace('/?', '?').split('?') var queryParams = query[1]; var queryArray = queryParams.split('&'); var params; @@ -916,7 +1107,7 @@ local api = require "luci.passwall2.api" var ws_path_dat = queryParam.path.split('?'); var ws_path = ws_path_dat[0]; var ws_path_params = {}; - var ws_path_params_array = ws_path_dat[1].split('&'); + var ws_path_params_array = (ws_path_dat[1] || '').split('&'); for (i = 0; i < ws_path_params_array.length; i++) { var kv = ws_path_params_array[i].split('='); ws_path_params[decodeURIComponent(kv[0]).toLowerCase()] = decodeURIComponent(kv[1] || ''); @@ -947,7 +1138,7 @@ local api = require "luci.passwall2.api" } if (m.hash) { - opt.set('remarks', decodeURI(m.hash.substr(1))); + opt.set('remarks', decodeURIComponent(m.hash.substr(1))); } } if (ssu[0] === "hysteria2" || ssu[0] === "hy2") { @@ -959,7 +1150,7 @@ local api = require "luci.passwall2.api" } var queryParam = {}; if (m.search.length > 1) { - var query = m.search.split('?'); + var query = m.search.replace('/?', '?').split('?') var queryParams = query[1]; var queryArray = queryParams.split('&'); var params; @@ -998,7 +1189,7 @@ local api = require "luci.passwall2.api" opt.set(dom_prefix + 'tls_allowInsecure', true); } if (m.hash) { - opt.set('remarks', decodeURI(m.hash.substr(1))); + opt.set('remarks', decodeURIComponent(m.hash.substr(1))); } } if (ssu[0] === "tuic") { diff --git a/luci-app-passwall2/root/usr/share/passwall2/app.sh b/luci-app-passwall2/root/usr/share/passwall2/app.sh old mode 100644 new mode 100755 index 3b41dbc8d..485d1518e --- a/luci-app-passwall2/root/usr/share/passwall2/app.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/app.sh @@ -327,7 +327,7 @@ run_xray() { set_flag=$(echo ${flag} | awk -F '_' '{print $2}') } if [ "${nftflag}" = "1" ]; then - local direct_nftset="4#inet#fw4#passwall2_${set_flag}_whitelist,6#inet#fw4#passwall2_${set_flag}_whitelist6" + local direct_nftset="4#inet#passwall2#passwall2_${set_flag}_whitelist,6#inet#passwall2#passwall2_${set_flag}_whitelist6" else local direct_ipset="passwall2_${set_flag}_whitelist,passwall2_${set_flag}_whitelist6" fi @@ -439,7 +439,7 @@ run_singbox() { set_flag=$(echo ${flag} | awk -F '_' '{print $2}') } if [ "${nftflag}" = "1" ]; then - local direct_nftset="4#inet#fw4#passwall2_${set_flag}_whitelist,6#inet#fw4#passwall2_${set_flag}_whitelist6" + local direct_nftset="4#inet#passwall2#passwall2_${set_flag}_whitelist,6#inet#passwall2#passwall2_${set_flag}_whitelist6" else local direct_ipset="passwall2_${set_flag}_whitelist,passwall2_${set_flag}_whitelist6" fi diff --git a/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua b/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua index 6eb3fd673..ca16a8ada 100644 --- a/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua @@ -220,3 +220,11 @@ f_out:write("\n" .. string.format(str, console_port, (console_user and console_u log(string.format(" * 控制台端口:%s", console_port)) f_out:close() + +--内置健康检查URL +if health_check_type == "passwall_logic" then + local probeUrl = uci:get(appname, "@global_haproxy[0]", "health_probe_url") or "https://www.google.com/generate_204" + local f_url = io.open(haproxy_path .. "/Probe_URL", "w") + f_url:write(probeUrl) + f_url:close() +end diff --git a/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh b/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh index 870ffb575..53a43cc5d 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh @@ -4,7 +4,17 @@ listen_address=$1 listen_port=$2 server_address=$3 server_port=$4 -status=$(/usr/bin/curl -I -o /dev/null -skL -x socks5h://${server_address}:${server_port} --connect-timeout 3 --retry 3 -w %{http_code} "https://www.google.com/generate_204") + +probe_file="/tmp/etc/passwall2/haproxy/Probe_URL" +probeUrl="https://www.google.com/generate_204" +if [ -f "$probe_file" ]; then + firstLine=$(head -n 1 "$probe_file" | tr -d ' \t') + if [ -n "$firstLine" ]; then + probeUrl="$firstLine" + fi +fi + +status=$(/usr/bin/curl -I -o /dev/null -skL -x socks5h://${server_address}:${server_port} --connect-timeout 3 --retry 3 -w %{http_code} "${probeUrl}") case "$status" in 204|\ 200) diff --git a/luci-app-passwall2/root/usr/share/passwall2/helper_dnsmasq.sh b/luci-app-passwall2/root/usr/share/passwall2/helper_dnsmasq.sh index 6a4e6be1b..c81d9f942 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/helper_dnsmasq.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/helper_dnsmasq.sh @@ -95,8 +95,8 @@ add() { local set_type="ipset" [ "${NFTFLAG}" = "1" ] && { set_type="nftset" - local setflag_4="4#inet#fw4#" - local setflag_6="6#inet#fw4#" + local setflag_4="4#inet#passwall2#" + local setflag_6="6#inet#passwall2#" } #始终用国内DNS解析节点域名 diff --git a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh index 98736c402..419f7c7f4 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh @@ -2,6 +2,7 @@ DIR="$(cd "$(dirname "$0")" && pwd)" MY_PATH=$DIR/nftables.sh +NFTABLE_NAME="inet passwall2" NFTSET_LANLIST="passwall2_lanlist" NFTSET_VPSLIST="passwall2_vpslist" @@ -107,11 +108,37 @@ REDIRECT() { destroy_nftset() { for i in "$@"; do - nft flush set inet fw4 $i 2>/dev/null - nft delete set inet fw4 $i 2>/dev/null + nft flush set $NFTABLE_NAME $i 2>/dev/null + nft delete set $NFTABLE_NAME $i 2>/dev/null done } +gen_nft_tables() { + if [ -z "$(nft list tables | grep 'inet passwall2')" ]; then + local nft_table_file="$TMP_PATH/PSW2_TABLE.nft" + # Set the correct priority to fit fw4 + cat > "$nft_table_file" <<-EOF + table $NFTABLE_NAME { + chain dstnat { + type nat hook prerouting priority dstnat - 1; policy accept; + } + chain mangle_prerouting { + type filter hook prerouting priority mangle - 1; policy accept; + } + chain mangle_output { + type route hook output priority mangle - 1; policy accept; + } + chain nat_output { + type nat hook output priority -1; policy accept; + } + } + EOF + + nft -f "$nft_table_file" + rm -rf "$nft_table_file" + fi +} + insert_nftset() { local nftset_name="${1}"; shift local timeout_argument="${1}"; shift @@ -129,7 +156,7 @@ insert_nftset() { mkdir -p $TMP_PATH2/nftset cat > "$TMP_PATH2/nftset/$nftset_name" <<-EOF define $nftset_name = {$nftset_elements} - add element inet fw4 $nftset_name \$$nftset_name + add element $NFTABLE_NAME $nftset_name \$$nftset_name EOF nft -f "$TMP_PATH2/nftset/$nftset_name" rm -rf "$TMP_PATH2/nftset" @@ -145,12 +172,12 @@ gen_nftset() { # -1 - follow the set's timeout parameters local timeout_argument_element="${1}"; shift - nft "list set inet fw4 $nftset_name" &>/dev/null + nft "list set $NFTABLE_NAME $nftset_name" &>/dev/null if [ $? -ne 0 ]; then if [ "$timeout_argument_set" == "0" ]; then - nft "add set inet fw4 $nftset_name { type $ip_type; flags interval, timeout; auto-merge; }" + nft "add set $NFTABLE_NAME $nftset_name { type $ip_type; flags interval, timeout; auto-merge; }" else - nft "add set inet fw4 $nftset_name { type $ip_type; flags interval, timeout; timeout $timeout_argument_set; gc-interval $timeout_argument_set; auto-merge; }" + nft "add set $NFTABLE_NAME $nftset_name { type $ip_type; flags interval, timeout; timeout $timeout_argument_set; gc-interval $timeout_argument_set; auto-merge; }" fi fi [ -n "${1}" ] && insert_nftset $nftset_name $timeout_argument_element $@ @@ -272,8 +299,8 @@ load_acl() { [ "$tcp_no_redir_ports" != "disable" ] && { if [ "$tcp_no_redir_ports" != "1:65535" ]; then - nft "add rule inet fw4 $nft_prerouting_chain ${_ipt_source} ip protocol tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 ${_ipt_source} meta l4proto 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\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ${_ipt_source} meta l4proto tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\"" echolog " - ${msg}不代理 TCP 端口[${tcp_no_redir_ports}]" else #结束时会return,无需加多余的规则。 @@ -284,8 +311,8 @@ load_acl() { [ "$udp_no_redir_ports" != "disable" ] && { if [ "$udp_no_redir_ports" != "1:65535" ]; then - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\"" 2>/dev/null + 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_V6 meta l4proto udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\"" 2>/dev/null echolog " - ${msg}不代理 UDP 端口[${udp_no_redir_ports}]" else #结束时会return,无需加多余的规则。 @@ -295,7 +322,7 @@ load_acl() { } [ "$tcp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && { - [ -s "${TMP_ACL_PATH}/${sid}/var_redirect_dns_port" ] && nft "add rule inet fw4 PSW2_REDIRECT ip protocol udp ${_ipt_source} udp dport 53 counter redirect to $(cat ${TMP_ACL_PATH}/${sid}/var_redirect_dns_port) comment \"$remarks\"" + [ -s "${TMP_ACL_PATH}/${sid}/var_redirect_dns_port" ] && nft "add rule $NFTABLE_NAME PSW2_REDIRECT ip protocol udp ${_ipt_source} udp dport 53 counter redirect to $(cat ${TMP_ACL_PATH}/${sid}/var_redirect_dns_port) comment \"$remarks\"" msg2="${msg}使用 TCP 节点[$node_remark]" if [ -n "${is_tproxy}" ]; then msg2="${msg2}(TPROXY:${redir_port})" @@ -303,59 +330,59 @@ load_acl() { msg2="${msg2}(REDIRECT:${redir_port})" fi - [ "${write_ipset_direct}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule inet fw4 PSW2_NAT ip protocol tcp ${_ipt_source} ip daddr @$nftset_whitelist counter return comment \"$remarks\"" - [ "${write_ipset_direct}" = "1" ] && [ -n "${is_tproxy}" ] && nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp ${_ipt_source} ip daddr @$nftset_whitelist counter return comment \"$remarks\"" + [ "${write_ipset_direct}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ${_ipt_source} ip daddr @$nftset_whitelist counter return comment \"$remarks\"" + [ "${write_ipset_direct}" = "1" ] && [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ${_ipt_source} ip daddr @$nftset_whitelist counter return comment \"$remarks\"" [ "$accept_icmp" = "1" ] && { - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr $FAKE_IP $(REDIRECT) comment \"$remarks\"" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} $(REDIRECT) comment \"$remarks\"" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr $FAKE_IP $(REDIRECT) comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} $(REDIRECT) comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} return comment \"$remarks\"" } [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && { - nft "add rule inet fw4 PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"$remarks\"" 2>/dev/null - nft "add rule inet fw4 PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} $(REDIRECT) comment \"$remarks\"" 2>/dev/null - nft "add rule inet fw4 PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} return comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} $(REDIRECT) comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} return comment \"$remarks\"" 2>/dev/null } if [ -z "${is_tproxy}" ]; then - nft "add rule inet fw4 PSW2_NAT ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP $(REDIRECT $redir_port) comment \"$remarks\"" - nft "add rule inet fw4 PSW2_NAT ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") $(REDIRECT $redir_port) comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP $(REDIRECT $redir_port) comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") $(REDIRECT $redir_port) comment \"$remarks\"" else - nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP counter jump PSW2_RULE comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") counter jump PSW2_RULE comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY4) comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP counter jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") counter jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY4) comment \"$remarks\"" fi [ "$PROXY_IPV6" == "1" ] && { - [ "${write_ipset_direct}" = "1" ] && nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr @$nftset_whitelist6 counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW2_RULE comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") jump PSW2_RULE comment \"$remarks\"" 2>/dev/null - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY) comment \"$remarks\"" 2>/dev/null + [ "${write_ipset_direct}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr @$nftset_whitelist6 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") jump PSW2_RULE comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY) comment \"$remarks\"" 2>/dev/null } echolog " - ${msg2}" } - nft "add rule inet fw4 $nft_prerouting_chain ip protocol tcp ${_ipt_source} counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null [ "$udp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && { msg2="${msg}使用 UDP 节点[$node_remark](TPROXY:${redir_port})" - [ "${write_ipset_direct}" = "1" ] && nft "add rule inet fw4 PSW2_MANGLE ip protocol udp ${_ipt_source} ip daddr @$nftset_whitelist counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp ${_ipt_source} ip daddr $FAKE_IP counter jump PSW2_RULE comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") jump PSW2_RULE comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp ${_ipt_source} $(REDIRECT $redir_port TPROXY4) comment \"$remarks\"" + [ "${write_ipset_direct}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} ip daddr @$nftset_whitelist counter return comment \"$remarks\"" + 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} $(factor $udp_redir_ports "udp dport") jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(REDIRECT $redir_port TPROXY4) comment \"$remarks\"" [ "$PROXY_IPV6" == "1" ] && [ "$PROXY_IPV6_UDP" == "1" ] && { - [ "${write_ipset_direct}" = "1" ] && nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} ip6 daddr @$nftset_whitelist6 counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW2_RULE comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") counter jump PSW2_RULE comment \"$remarks\"" 2>/dev/null - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(REDIRECT $redir_port TPROXY) comment \"$remarks\"" 2>/dev/null + [ "${write_ipset_direct}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} ip6 daddr @$nftset_whitelist6 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") counter jump PSW2_RULE comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(REDIRECT $redir_port TPROXY) comment \"$remarks\"" 2>/dev/null } echolog " - ${msg2}" } - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp ${_ipt_source} counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null 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 unset _ip _mac _iprange _ipset _ip_or_mac rule_list redir_port node_remark @@ -368,8 +395,8 @@ load_acl() { msg="【默认】," [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { - nft add rule inet fw4 $nft_prerouting_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\" - nft add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\" + nft add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\" + nft add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\" if [ "$TCP_NO_REDIR_PORTS" != "1:65535" ]; then echolog " - ${msg}不代理 TCP 端口[${TCP_NO_REDIR_PORTS}]" else @@ -379,8 +406,8 @@ load_acl() { } [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { - nft "add inet fw4 PSW2_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"默认\"" - nft "add inet fw4 PSW2_MANGLE_V6 counter meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"默认\"" + nft "add $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"默认\"" + nft "add $NFTABLE_NAME PSW2_MANGLE_V6 counter meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"默认\"" if [ "$UDP_NO_REDIR_PORTS" != "1:65535" ]; then echolog " - ${msg}不代理 UDP 端口[${UDP_NO_REDIR_PORTS}]" else @@ -397,35 +424,35 @@ load_acl() { msg2="${msg2}(REDIRECT:${REDIR_PORT})" fi - [ "${WRITE_IPSET_DIRECT}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule inet fw4 PSW2_NAT ip protocol tcp ip daddr @$nftset_global_whitelist counter return comment \"$remarks\"" - [ "${WRITE_IPSET_DIRECT}" = "1" ] && [ -n "${is_tproxy}" ] && nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp ip daddr @$nftset_global_whitelist counter return comment \"$remarks\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ip daddr @$nftset_global_whitelist counter return comment \"$remarks\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ip daddr @$nftset_global_whitelist counter return comment \"$remarks\"" [ "$accept_icmp" = "1" ] && { - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip protocol icmp ip daddr $FAKE_IP $(REDIRECT) comment \"默认\"" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip protocol icmp $(REDIRECT) comment \"默认\"" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip protocol icmp return comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ip daddr $FAKE_IP $(REDIRECT) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp $(REDIRECT) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp return comment \"默认\"" } [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && { - nft "add rule inet fw4 PSW2_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"默认\"" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT meta l4proto icmpv6 $(REDIRECT) comment \"默认\"" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT meta l4proto icmpv6 return comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 $(REDIRECT) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 return comment \"默认\"" } if [ -z "${is_tproxy}" ]; then - nft "add rule inet fw4 PSW2_NAT ip protocol tcp ip daddr $FAKE_IP $(REDIRECT $REDIR_PORT) comment \"默认\"" - nft "add rule inet fw4 PSW2_NAT ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") $(REDIRECT $REDIR_PORT) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ip daddr $FAKE_IP $(REDIRECT $REDIR_PORT) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") $(REDIRECT $REDIR_PORT) comment \"默认\"" else - nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp ip daddr $FAKE_IP counter jump PSW2_RULE comment \"默认\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE comment \"默认\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp $(REDIRECT $REDIR_PORT TPROXY4) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ip daddr $FAKE_IP counter jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp $(REDIRECT $REDIR_PORT TPROXY4) comment \"默认\"" fi [ "$PROXY_IPV6" == "1" ] && { - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr @$nftset_global_whitelist6 counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"默认\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE comment \"默认\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp $(REDIRECT $REDIR_PORT TPROXY) comment \"默认\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr @$nftset_global_whitelist6 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(REDIRECT $REDIR_PORT TPROXY) comment \"默认\"" } echolog "${msg2}" @@ -434,16 +461,16 @@ load_acl() { if [ "$UDP_PROXY_MODE" != "disable" ] && [ "$NODE" != "nil" ]; then msg2="${msg}使用 UDP 节点[$(config_n_get $NODE remarks)](TPROXY:${REDIR_PORT})" - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule inet fw4 PSW2_MANGLE ip protocol udp ip daddr @$nftset_global_whitelist counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE comment \"默认\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE comment \"默认\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp $(REDIRECT $REDIR_PORT TPROXY4) comment \"默认\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ip daddr @$nftset_global_whitelist counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(REDIRECT $REDIR_PORT TPROXY4) comment \"默认\"" [ "$PROXY_IPV6" == "1" ] && [ "$PROXY_IPV6_UDP" == "1" ] && { - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp ip6 daddr @$nftset_global_whitelist6 counter return comment \"$remarks\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"默认\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE comment \"默认\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp $(REDIRECT $REDIR_PORT TPROXY) comment \"默认\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ip6 daddr @$nftset_global_whitelist6 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(REDIRECT $REDIR_PORT TPROXY) comment \"默认\"" } echolog "${msg2}" @@ -507,7 +534,7 @@ filter_node() { 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 inet fw4 $nft_output_chain" 2>/dev/null | grep -q "${address}:${port}" + nft "list chain $NFTABLE_NAME $nft_output_chain" 2>/dev/null | grep -q "${address}:${port}" if [ $? -ne 0 ]; then unset dst_rule local dst_rule="jump PSW2_RULE" @@ -517,11 +544,11 @@ filter_node() { msg2="套娃使用(${msg}:${port} -> ${_port})" } [ -n "$_proxy" ] && [ "$_proxy" == "1" ] && [ -n "$_port" ] || { - ADD_INDEX=$(RULE_LAST_INDEX "inet fw4" $nft_output_chain $_set_name $FORCE_INDEX) + ADD_INDEX=$(RULE_LAST_INDEX "$NFTABLE_NAME" $nft_output_chain $_set_name $FORCE_INDEX) dst_rule="return" msg2="直连代理" } - nft "insert rule inet fw4 $nft_output_chain position $ADD_INDEX meta l4proto $stream $_ip_type daddr $address $stream dport $port $dst_rule comment \"${address}:${port}\"" 2>/dev/null + 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 @@ -578,12 +605,24 @@ filter_node() { } dns_hijack() { - nft "add rule inet fw4 dstnat meta l4proto udp ip dport 53 redirect to 53" - echolog "强制转发本机DNS端口 UDP/53 的请求[$?]" + [ $(config_t_get global dns_redirect "0") = "1" ] && { + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp udp dport 53 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp tcp dport 53 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp udp dport 53 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp tcp dport 53 counter return" + nft insert rule $NFTABLE_NAME dstnat position 0 tcp dport 53 counter redirect to :53 comment \"PSW2_DNS_Hijack\" 2>/dev/null + nft insert rule $NFTABLE_NAME dstnat position 0 udp dport 53 counter redirect to :53 comment \"PSW2_DNS_Hijack\" 2>/dev/null + nft insert rule $NFTABLE_NAME dstnat position 0 meta nfproto {ipv6} tcp dport 53 counter redirect to :53 comment \"PSW2_DNS_Hijack\" 2>/dev/null + nft insert rule $NFTABLE_NAME dstnat position 0 meta nfproto {ipv6} udp dport 53 counter redirect to :53 comment \"PSW2_DNS_Hijack\" 2>/dev/null + uci -q set dhcp.@dnsmasq[0].dns_redirect='0' 2>/dev/null + uci commit dhcp 2>/dev/null + echolog " - 开启 DNS 重定向" + } } add_firewall_rule() { echolog "开始加载防火墙规则..." + gen_nft_tables gen_nftset $NFTSET_LANLIST ipv4_addr 0 "-1" $(gen_lanlist) gen_nftset $NFTSET_VPSLIST ipv4_addr 0 0 @@ -644,89 +683,87 @@ add_firewall_rule() { nft_output_chain="PSW2_OUTPUT_MANGLE" fi - [ -z "$(nft list chain inet fw4 nat_output 2>/dev/null)" ] && nft "add chain inet fw4 nat_output { type nat hook output priority -1; }" + nft "add chain $NFTABLE_NAME PSW2_DIVERT" + nft "flush chain $NFTABLE_NAME PSW2_DIVERT" + nft "add rule $NFTABLE_NAME PSW2_DIVERT meta l4proto tcp socket transparent 1 mark set 1 counter accept" - nft "add chain inet fw4 PSW2_DIVERT" - nft "flush chain inet fw4 PSW2_DIVERT" - nft "add rule inet fw4 PSW2_DIVERT meta l4proto tcp socket transparent 1 mark set 1 counter accept" - - nft "add chain inet fw4 PSW2_REDIRECT" - nft "flush chain inet fw4 PSW2_REDIRECT" - nft "add rule inet fw4 dstnat jump PSW2_REDIRECT" + nft "add chain $NFTABLE_NAME PSW2_REDIRECT" + nft "flush chain $NFTABLE_NAME PSW2_REDIRECT" + nft "add rule $NFTABLE_NAME dstnat jump PSW2_REDIRECT" # for ipv4 ipv6 tproxy mark - nft "add chain inet fw4 PSW2_RULE" - nft "flush chain inet fw4 PSW2_RULE" - nft "add rule inet fw4 PSW2_RULE meta mark set ct mark counter" - nft "add rule inet fw4 PSW2_RULE meta mark 1 counter return" - nft "add rule inet fw4 PSW2_RULE tcp flags &(fin|syn|rst|ack) == syn meta mark set mark and 0x0 xor 0x1 counter" - nft "add rule inet fw4 PSW2_RULE meta l4proto udp ct state new meta mark set mark and 0x0 xor 0x1 counter" - nft "add rule inet fw4 PSW2_RULE ct mark set mark counter" + nft "add chain $NFTABLE_NAME PSW2_RULE" + nft "flush chain $NFTABLE_NAME PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_RULE meta mark set ct mark counter" + nft "add rule $NFTABLE_NAME PSW2_RULE meta mark 1 counter return" + nft "add rule $NFTABLE_NAME PSW2_RULE tcp flags &(fin|syn|rst|ack) == syn meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW2_RULE meta l4proto udp ct state new meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW2_RULE ct mark set mark counter" #ipv4 tproxy mode and udp - nft "add chain inet fw4 PSW2_MANGLE" - nft "flush chain inet fw4 PSW2_MANGLE" - nft "add rule inet fw4 PSW2_MANGLE ip daddr @$NFTSET_LANLIST counter return" - nft "add rule inet fw4 PSW2_MANGLE ip daddr @$NFTSET_VPSLIST counter return" + nft "add chain $NFTABLE_NAME PSW2_MANGLE" + nft "flush chain $NFTABLE_NAME PSW2_MANGLE" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr @$NFTSET_LANLIST counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr @$NFTSET_VPSLIST counter return" - nft "add chain inet fw4 PSW2_OUTPUT_MANGLE" - nft "flush chain inet fw4 PSW2_OUTPUT_MANGLE" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_LANLIST counter return" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_VPSLIST counter return" + nft "add chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE" + nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_LANLIST counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_VPSLIST counter return" [ -n "$AUTO_DNS" ] && { for auto_dns in $(echo $AUTO_DNS | tr ',' ' '); do local dns_address=$(echo $auto_dns | awk -F '#' '{print $1}') local dns_port=$(echo $auto_dns | awk -F '#' '{print $2}') - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE ip protocol udp ip daddr ${dns_address} $(factor ${dns_port:-53} "udp dport") counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp ip daddr ${dns_address} $(factor ${dns_port:-53} "udp dport") counter return" echolog " - [$?]追加直连DNS到nftables:${dns_address}:${dns_port:-53}" done } - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule inet fw4 PSW2_OUTPUT_MANGLE ip daddr @$nftset_global_whitelist counter return" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE meta mark 0xff counter return" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip daddr @$nftset_global_whitelist counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE meta mark 0xff counter return" # jump chains - nft "add rule inet fw4 mangle_prerouting ip protocol udp counter jump PSW2_MANGLE" - [ -n "${is_tproxy}" ] && nft "add rule inet fw4 mangle_prerouting ip protocol tcp counter jump PSW2_MANGLE" - insert_rule_before "inet fw4" "mangle_prerouting" "PSW2_MANGLE" "counter jump PSW2_DIVERT" + nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol udp counter jump PSW2_MANGLE" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol tcp counter jump PSW2_MANGLE" + insert_rule_before "$NFTABLE_NAME" "mangle_prerouting" "PSW2_MANGLE" "counter jump PSW2_DIVERT" #ipv4 tcp redirect mode [ -z "${is_tproxy}" ] && { - nft "add chain inet fw4 PSW2_NAT" - nft "flush chain inet fw4 PSW2_NAT" - nft "add rule inet fw4 PSW2_NAT ip daddr @$NFTSET_LANLIST counter return" - nft "add rule inet fw4 PSW2_NAT ip daddr @$NFTSET_VPSLIST counter return" - nft "add rule inet fw4 dstnat ip protocol tcp counter jump PSW2_NAT" + nft "add chain $NFTABLE_NAME PSW2_NAT" + nft "flush chain $NFTABLE_NAME PSW2_NAT" + nft "add rule $NFTABLE_NAME PSW2_NAT ip daddr @$NFTSET_LANLIST counter return" + nft "add rule $NFTABLE_NAME PSW2_NAT ip daddr @$NFTSET_VPSLIST counter return" + nft "add rule $NFTABLE_NAME dstnat ip protocol tcp counter jump PSW2_NAT" - nft "add chain inet fw4 PSW2_OUTPUT_NAT" - nft "flush chain inet fw4 PSW2_OUTPUT_NAT" - nft "add rule inet fw4 PSW2_OUTPUT_NAT ip daddr @$NFTSET_LANLIST counter return" - nft "add rule inet fw4 PSW2_OUTPUT_NAT ip daddr @$NFTSET_VPSLIST counter return" - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule inet fw4 PSW2_OUTPUT_NAT ip daddr @$nftset_global_whitelist counter return" - nft "add rule inet fw4 PSW2_OUTPUT_NAT meta mark 0xff counter return" + nft "add chain $NFTABLE_NAME PSW2_OUTPUT_NAT" + nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_NAT" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT ip daddr @$NFTSET_LANLIST counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT ip daddr @$NFTSET_VPSLIST counter return" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT ip daddr @$nftset_global_whitelist counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT meta mark 0xff counter return" } #icmp ipv6-icmp redirect if [ "$accept_icmp" = "1" ]; then - nft "add chain inet fw4 PSW2_ICMP_REDIRECT" - nft "flush chain inet fw4 PSW2_ICMP_REDIRECT" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip daddr @$NFTSET_LANLIST counter return" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip daddr @$NFTSET_VPSLIST counter return" - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip daddr @$nftset_global_whitelist counter return" + nft "add chain $NFTABLE_NAME PSW2_ICMP_REDIRECT" + nft "flush chain $NFTABLE_NAME PSW2_ICMP_REDIRECT" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip daddr @$NFTSET_LANLIST counter return" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip daddr @$NFTSET_VPSLIST counter return" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip daddr @$nftset_global_whitelist counter return" [ "$accept_icmpv6" = "1" ] && { - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip6 daddr @$NFTSET_LANLIST6 counter return" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip6 daddr @$NFTSET_VPSLIST6 counter return" - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule inet fw4 PSW2_ICMP_REDIRECT ip6 daddr @$nftset_global_whitelist6 counter return" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip6 daddr @$NFTSET_LANLIST6 counter return" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip6 daddr @$NFTSET_VPSLIST6 counter return" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip6 daddr @$nftset_global_whitelist6 counter return" } - nft "add rule inet fw4 dstnat meta l4proto {icmp,icmpv6} counter jump PSW2_ICMP_REDIRECT" - nft "add rule inet fw4 nat_output meta l4proto {icmp,icmpv6} counter jump PSW2_ICMP_REDIRECT" + nft "add rule $NFTABLE_NAME dstnat meta l4proto {icmp,icmpv6} counter jump PSW2_ICMP_REDIRECT" + nft "add rule $NFTABLE_NAME nat_output meta l4proto {icmp,icmpv6} counter jump PSW2_ICMP_REDIRECT" fi WAN_IP=$(get_wan_ip) if [ -n "${WAN_IP}" ]; then - nft "add rule inet fw4 PSW2_MANGLE ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\"" - [ -z "${is_tproxy}" ] && nft "add rule inet fw4 PSW2_NAT ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\"" + [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_NAT ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\"" fi unset WAN_IP @@ -734,26 +771,26 @@ add_firewall_rule() { ip route add local 0.0.0.0/0 dev lo table 100 #ipv6 tproxy mode and udp - nft "add chain inet fw4 PSW2_MANGLE_V6" - nft "flush chain inet fw4 PSW2_MANGLE_V6" - nft "add rule inet fw4 PSW2_MANGLE_V6 ip6 daddr @$NFTSET_LANLIST6 counter return" - nft "add rule inet fw4 PSW2_MANGLE_V6 ip6 daddr @$NFTSET_VPSLIST6 counter return" - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule inet fw4 PSW2_MANGLE_V6 ip6 daddr @$nftset_global_whitelist6 counter return" + nft "add chain $NFTABLE_NAME PSW2_MANGLE_V6" + nft "flush chain $NFTABLE_NAME PSW2_MANGLE_V6" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$NFTSET_LANLIST6 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$NFTSET_VPSLIST6 counter return" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$nftset_global_whitelist6 counter return" - nft "add chain inet fw4 PSW2_OUTPUT_MANGLE_V6" - nft "flush chain inet fw4 PSW2_OUTPUT_MANGLE_V6" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_LANLIST6 counter return" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_VPSLIST6 counter return" - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$nftset_global_whitelist6 counter return" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 meta mark 0xff counter return" + nft "add chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6" + nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_LANLIST6 counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_VPSLIST6 counter return" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$nftset_global_whitelist6 counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta mark 0xff counter return" # jump chains [ "$PROXY_IPV6" == "1" ] && { - nft "add rule inet fw4 mangle_prerouting meta nfproto {ipv6} counter jump PSW2_MANGLE_V6" - nft "add rule inet fw4 mangle_output meta nfproto {ipv6} counter jump PSW2_OUTPUT_MANGLE_V6 comment \"PSW2_OUTPUT_MANGLE\"" + nft "add rule $NFTABLE_NAME mangle_prerouting meta nfproto {ipv6} counter jump PSW2_MANGLE_V6" + nft "add rule $NFTABLE_NAME mangle_output meta nfproto {ipv6} counter jump PSW2_OUTPUT_MANGLE_V6 comment \"PSW2_OUTPUT_MANGLE\"" WAN6_IP=$(get_wan6_ip) - [ -n "${WAN6_IP}" ] && nft "add rule inet fw4 PSW2_MANGLE_V6 ip6 daddr ${WAN6_IP} counter return comment \"WAN6_IP_RETURN\"" + [ -n "${WAN6_IP}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr ${WAN6_IP} counter return comment \"WAN6_IP_RETURN\"" unset WAN6_IP ip -6 rule add fwmark 1 table 100 @@ -791,8 +828,8 @@ add_firewall_rule() { msg="【路由器本机】," [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { - nft "add rule inet fw4 $nft_output_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return" + 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 [ "$TCP_NO_REDIR_PORTS" != "1:65535" ]; then echolog " - ${msg}不代理 TCP 端口[${TCP_NO_REDIR_PORTS}]" else @@ -802,8 +839,8 @@ add_firewall_rule() { } [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { - nft add rule inet fw4 PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return - nft add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return + 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 [ "$UDP_NO_REDIR_PORTS" != "1:65535" ]; then echolog " - ${msg}不代理 UDP 端口[${UDP_NO_REDIR_PORTS}]" else @@ -815,68 +852,68 @@ add_firewall_rule() { # 加载路由器自身代理 TCP if [ "$NODE" != "nil" ] && [ "$TCP_LOCALHOST_PROXY" = "1" ]; then [ "$accept_icmp" = "1" ] && { - nft "add rule inet fw4 PSW2_ICMP_REDIRECT oif lo ip protocol icmp ip daddr $FAKE_IP counter redirect" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT oif lo ip protocol icmp counter redirect" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT oif lo ip protocol icmp counter return" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp ip daddr $FAKE_IP 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 inet fw4 PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 counter redirect" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter redirect" - nft "add rule inet fw4 PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter return" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 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 [ -z "${is_tproxy}" ]; then - nft "add rule inet fw4 PSW2_OUTPUT_NAT ip protocol tcp ip daddr $FAKE_IP $(REDIRECT $REDIR_PORT)" - nft "add rule inet fw4 PSW2_OUTPUT_NAT ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") $(REDIRECT $REDIR_PORT)" - nft "add rule inet fw4 nat_output ip protocol tcp counter jump PSW2_OUTPUT_NAT" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT ip protocol tcp ip daddr $FAKE_IP $(REDIRECT $REDIR_PORT)" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") $(REDIRECT $REDIR_PORT)" + nft "add rule $NFTABLE_NAME nat_output ip protocol tcp counter jump PSW2_OUTPUT_NAT" else - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE ip protocol tcp ip daddr $FAKE_IP counter jump PSW2_RULE" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE" - nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"本机\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol tcp iif lo counter return comment \"本机\"" - nft "add rule inet fw4 mangle_output ip protocol tcp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol tcp ip daddr $FAKE_IP counter jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"本机\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo counter return comment \"本机\"" + nft "add rule $NFTABLE_NAME mangle_output ip protocol tcp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" fi [ "$PROXY_IPV6" == "1" ] && { - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp iif lo $(REDIRECT $REDIR_PORT TPROXY) comment \"本机\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto tcp iif lo counter return comment \"本机\"" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo $(REDIRECT $REDIR_PORT TPROXY) comment \"本机\"" + 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 inet fw4 $nft_output_chain ip protocol tcp oif $iface counter return" - nft "insert rule inet fw4 PSW2_OUTPUT_MANGLE_V6 ip protocol tcp oif $iface counter return" + 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 if [ "$NODE" != "nil" ] && [ "$UDP_LOCALHOST_PROXY" = "1" ]; then - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE" - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"本机\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp iif lo counter return comment \"本机\"" - nft "add rule inet fw4 mangle_output ip protocol udp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"本机\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo counter return comment \"本机\"" + nft "add rule $NFTABLE_NAME mangle_output ip protocol udp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" if [ "$PROXY_IPV6_UDP" == "1" ]; then - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE" - nft "add rule inet fw4 PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp iif lo $(REDIRECT $REDIR_PORT TPROXY) comment \"本机\"" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp iif lo counter return comment \"本机\"" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo $(REDIRECT $REDIR_PORT TPROXY) comment \"本机\"" + 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 inet fw4 $nft_output_chain ip protocol udp oif $iface counter return" - nft "insert rule inet fw4 PSW2_OUTPUT_MANGLE_V6 ip protocol udp oif $iface counter return" + 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 inet fw4 mangle_output oif lo counter return comment \"PSW2_OUTPUT_MANGLE\"" - nft "add rule inet fw4 mangle_output meta mark 1 counter return comment \"PSW2_OUTPUT_MANGLE\"" + nft "add rule $NFTABLE_NAME mangle_output oif lo counter return comment \"PSW2_OUTPUT_MANGLE\"" + nft "add rule $NFTABLE_NAME mangle_output meta mark 1 counter return comment \"PSW2_OUTPUT_MANGLE\"" - nft "add rule inet fw4 PSW2_MANGLE ip protocol udp udp dport 53 counter return" - nft "add rule inet fw4 PSW2_MANGLE_V6 meta l4proto udp udp dport 53 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp udp dport 53 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp udp dport 53 counter return" } # 加载ACLS @@ -896,19 +933,19 @@ add_firewall_rule() { } del_firewall_rule() { - for nft in "forward" "dstnat" "srcnat" "nat_output" "mangle_prerouting" "mangle_output"; do - local handles=$(nft -a list chain inet fw4 ${nft} 2>/dev/null | grep -E "PSW2_" | awk -F '# handle ' '{print$2}') + for nft in "dstnat" "srcnat" "nat_output" "mangle_prerouting" "mangle_output"; do + local handles=$(nft -a list chain $NFTABLE_NAME ${nft} 2>/dev/null | grep -E "PSW2_" | awk -F '# handle ' '{print$2}') for handle in $handles; do - nft delete rule inet fw4 ${nft} handle ${handle} 2>/dev/null + nft delete rule $NFTABLE_NAME ${nft} handle ${handle} 2>/dev/null done done for handle in $(nft -a list chains | grep -E "chain PSW2_" | grep -v "PSW2_RULE" | awk -F '# handle ' '{print$2}'); do - nft delete chain inet fw4 handle ${handle} 2>/dev/null + nft delete chain $NFTABLE_NAME handle ${handle} 2>/dev/null done # Need to be removed at the end, otherwise it will show "Resource busy" - nft delete chain inet fw4 handle $(nft -a list chains | grep -E "PSW2_RULE" | awk -F '# handle ' '{print$2}') 2>/dev/null + nft delete chain $NFTABLE_NAME handle $(nft -a list chains | grep -E "PSW2_RULE" | awk -F '# handle ' '{print$2}') 2>/dev/null ip rule del fwmark 1 lookup 100 2>/dev/null ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null @@ -932,9 +969,14 @@ flush_nftset() { done } +flush_table() { + nft flush table $NFTABLE_NAME + nft delete table $NFTABLE_NAME +} + flush_nftset_reload() { del_firewall_rule - flush_nftset + flush_table rm -rf /tmp/singbox_passwall2_* /etc/init.d/passwall2 reload } @@ -946,68 +988,33 @@ flush_include() { gen_include() { flush_include local nft_chain_file=$TMP_PATH/PSW2_RULE.nft - local nft_set_file=$TMP_PATH/PSW2_SETS.nft echo '#!/usr/sbin/nft -f' > $nft_chain_file - echo '#!/usr/sbin/nft -f' > $nft_set_file - for chain in $(nft -a list chains | grep -E "chain PSW2_" | awk -F ' ' '{print$2}'); do - nft list chain inet fw4 ${chain} >> $nft_chain_file - done - - for set_name in $(nft -a list sets | grep -E "set passwall2_" | awk -F ' ' '{print$2}'); do - nft list set inet fw4 ${set_name} >> $nft_set_file - done + nft list table $NFTABLE_NAME >> $nft_chain_file local __nft=" " __nft=$(cat <<- EOF - - [ -z "\$(nft list sets 2>/dev/null | grep "passwall2_")" ] && nft -f ${nft_set_file} - [ -z "\$(nft list chain inet fw4 nat_output 2>/dev/null)" ] && nft "add chain inet fw4 nat_output { type nat hook output priority -1; }" - nft -f ${nft_chain_file} - - nft "add rule inet fw4 dstnat jump PSW2_REDIRECT" - - [ "$accept_icmp" == "1" ] && { - nft "add rule inet fw4 dstnat meta l4proto {icmp,icmpv6} counter jump PSW2_ICMP_REDIRECT" - nft "add rule inet fw4 nat_output meta l4proto {icmp,icmpv6} counter jump PSW2_ICMP_REDIRECT" - } - + [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW2_DIVERT)" ] && nft -f ${nft_chain_file} [ -z "${is_tproxy}" ] && { - PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "inet fw4" PSW2_NAT WAN_IP_RETURN -1) + PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "$NFTABLE_NAME" PSW2_NAT WAN_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then WAN_IP=\$(sh ${MY_PATH} get_wan_ip) - [ ! -z "\${WAN_IP}" ] && nft "replace rule inet fw4 PSW2_NAT handle \$PR_INDEX ip daddr "\${WAN_IP}" counter return comment \"WAN_IP_RETURN\"" + [ ! -z "\${WAN_IP}" ] && nft "replace rule $NFTABLE_NAME PSW2_NAT handle \$PR_INDEX ip daddr "\${WAN_IP}" counter return comment \"WAN_IP_RETURN\"" fi - nft "add rule inet fw4 dstnat ip protocol tcp counter jump PSW2_NAT" - nft "add rule inet fw4 nat_output ip protocol tcp counter jump PSW2_OUTPUT_NAT" } - - PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "inet fw4" PSW2_MANGLE WAN_IP_RETURN -1) + + PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "$NFTABLE_NAME" PSW2_MANGLE WAN_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then WAN_IP=\$(sh ${MY_PATH} get_wan_ip) - [ ! -z "\${WAN_IP}" ] && nft "replace rule inet fw4 PSW2_MANGLE handle \$PR_INDEX ip daddr "\${WAN_IP}" counter return comment \"WAN_IP_RETURN\"" + [ ! -z "\${WAN_IP}" ] && nft "replace rule $NFTABLE_NAME PSW2_MANGLE handle \$PR_INDEX ip daddr "\${WAN_IP}" counter return comment \"WAN_IP_RETURN\"" fi - nft "add rule inet fw4 mangle_prerouting ip protocol udp counter jump PSW2_MANGLE" - - [ -n "${is_tproxy}" ] && { - nft "add rule inet fw4 mangle_prerouting ip protocol tcp counter jump PSW2_MANGLE" - nft "add rule inet fw4 mangle_output ip protocol tcp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" - } - \$(sh ${MY_PATH} insert_rule_before "inet fw4" "mangle_prerouting" "PSW2_MANGLE" "counter jump PSW2_DIVERT") - - [ "$UDP_NODE" != "nil" -o "$TCP_UDP" = "1" ] && nft "add rule inet fw4 mangle_output ip protocol udp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" [ "$PROXY_IPV6" == "1" ] && { - PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "inet fw4" PSW2_MANGLE_V6 WAN6_IP_RETURN -1) + PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "$NFTABLE_NAME" PSW2_MANGLE_V6 WAN6_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then WAN6_IP=\$(sh ${MY_PATH} get_wan6_ip) - [ ! -z "\${WAN_IP}" ] && nft "replace rule inet fw4 PSW2_MANGLE_V6 handle \$PR_INDEX ip6 daddr "\${WAN6_IP}" counter return comment \"WAN6_IP_RETURN\"" + [ ! -z "\${WAN_IP}" ] && nft "replace rule $NFTABLE_NAME PSW2_MANGLE_V6 handle \$PR_INDEX ip6 daddr "\${WAN6_IP}" counter return comment \"WAN6_IP_RETURN\"" fi - nft "add rule inet fw4 mangle_prerouting meta nfproto {ipv6} counter jump PSW2_MANGLE_V6" - nft "add rule inet fw4 mangle_output meta nfproto {ipv6} counter jump PSW2_OUTPUT_MANGLE_V6 comment \"PSW2_OUTPUT_MANGLE\"" } - - nft "add rule inet fw4 mangle_output oif lo counter return comment \"PSW2_OUTPUT_MANGLE\"" - nft "add rule inet fw4 mangle_output meta mark 1 counter return comment \"PSW2_OUTPUT_MANGLE\"" EOF ) diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua index 58018462c..a1a8900b3 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -506,6 +506,7 @@ local function processData(szType, content, add_mode, add_from) --ss://cmM0LW1kNTpwYXNzd2Q@192.168.100.1:8888/?plugin=obfs-local%3Bobfs%3Dhttp#Example2 --ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888#Example3 --ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888/?plugin=v2ray-plugin%3Bserver#Example3 + --ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTp0ZXN0@xxxxxx.com:443?type=ws&path=%2Ftestpath&host=xxxxxx.com&security=tls&fp=&alpn=h3%2Ch2%2Chttp%2F1.1&sni=xxxxxx.com#test-1%40ss local idx_sp = 0 local alias = "" @@ -514,17 +515,17 @@ local function processData(szType, content, add_mode, add_from) alias = content:sub(idx_sp + 1, -1) end result.remarks = UrlDecode(alias) - local info = content:sub(1, idx_sp - 1) - if info:find("/%?") then - local find_index = info:find("/%?") - local query = split(info, "/%?") - local params = {} + local info = content:sub(1, idx_sp - 1):gsub("/%?", "?") + local params = {} + if info:find("?") then + local find_index = info:find("?") + local query = split(info, "?") for _, v in pairs(split(query[2], '&')) do local t = split(v, '=') - params[t[1]] = t[2] + params[t[1]] = UrlDecode(t[2]) end if params.plugin then - local plugin_info = UrlDecode(params.plugin) + local plugin_info = params.plugin local idx_pn = plugin_info:find(";") if idx_pn then result.plugin = plugin_info:sub(1, idx_pn - 1) @@ -617,6 +618,85 @@ local function processData(szType, content, add_mode, add_from) result.error_msg = "shadowsocks-libev 不支持2022加密." end end + + if params.type then + params.type = string.lower(params.type) + result.transport = params.type + if result.type ~= "SS-Rust" and result.type ~= "SS" then + if params.type == 'ws' then + result.ws_host = params.host + result.ws_path = params.path + if result.type == "sing-box" and params.path then + local ws_path_dat = split(params.path, "?") + local ws_path = ws_path_dat[1] + local ws_path_params = {} + for _, v in pairs(split(ws_path_dat[2], '&')) do + local t = split(v, '=') + ws_path_params[t[1]] = t[2] + end + if ws_path_params.ed and tonumber(ws_path_params.ed) then + result.ws_path = ws_path + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_path_params.ed) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + end + end + end + if params.type == 'h2' or params.type == 'http' then + if result.type == "sing-box" then + result.transport = "http" + result.http_host = params.host + result.http_path = params.path + elseif result.type == "xray" then + result.transport = "h2" + result.h2_host = params.host + result.h2_path = params.path + end + end + if params.type == 'tcp' then + result.tcp_guise = params.headerType or "none" + result.tcp_guise_http_host = params.host + result.tcp_guise_http_path = params.path + end + if params.type == 'kcp' or params.type == 'mkcp' then + result.transport = "mkcp" + result.mkcp_guise = params.headerType or "none" + result.mkcp_mtu = 1350 + result.mkcp_tti = 50 + result.mkcp_uplinkCapacity = 5 + result.mkcp_downlinkCapacity = 20 + result.mkcp_readBufferSize = 2 + result.mkcp_writeBufferSize = 2 + result.mkcp_seed = params.seed + end + if params.type == 'quic' then + result.quic_guise = params.headerType or "none" + result.quic_key = params.key + result.quic_security = params.quicSecurity or "none" + end + if params.type == 'grpc' then + if params.path then result.grpc_serviceName = params.path end + if params.serviceName then result.grpc_serviceName = params.serviceName end + result.grpc_mode = params.mode + end + result.tls = "0" + if params.security == "tls" or params.security == "reality" then + result.tls = "1" + result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host + result.alpn = params.alpn + result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome" + if params.security == "reality" then + result.reality = "1" + result.reality_publicKey = params.pbk or nil + result.reality_shortId = params.sid or nil + result.reality_spiderX = params.spx or nil + end + end + result.tls_allowInsecure = allowInsecure_default and "1" or "0" + else + result.error_msg = "请更换Xray或Sing-Box来支持SS更多的传输方式." + end + end end elseif szType == "trojan" then if trojan_type_default == "sing-box" and has_singbox then