luci-app-passwall2: sync upstream

last commit: dfb1721ee5
This commit is contained in:
actions 2024-08-12 20:30:07 +08:00
parent 1285346822
commit 391adf918f
7 changed files with 203 additions and 29 deletions

View File

@ -98,9 +98,20 @@ o.cfgvalue = function(t, n)
protocol = "VMess" protocol = "VMess"
elseif protocol == "vless" then elseif protocol == "vless" then
protocol = "VLESS" protocol = "VLESS"
elseif protocol == "shadowsocks" then
protocol = "SS"
elseif protocol == "shadowsocksr" then
protocol = "SSR"
elseif protocol == "wireguard" then
protocol = "WG"
elseif protocol == "hysteria" then
protocol = "HY"
elseif protocol == "hysteria2" then
protocol = "HY2"
else else
protocol = protocol:gsub("^%l",string.upper) protocol = protocol:gsub("^%l",string.upper)
end end
if type == "sing-box" then type = "Sing-Box" end
type = type .. " " .. protocol type = type .. " " .. protocol
end end
local address = m:get(n, "address") or "" local address = m:get(n, "address") or ""

View File

@ -193,8 +193,10 @@ if has_singbox then
o.rmempty = false o.rmempty = false
o = s:option(Value, "geoip_url", translate("Custom geoip URL")) o = s:option(Value, "geoip_url", translate("Custom geoip URL"))
o.default = "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db" o.default = "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.db"
o:value("https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db") o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.db")
o:value("https://github.com/1715173329/sing-geoip/releases/latest/download/geoip.db")
o:value("https://github.com/lyc8503/sing-box-rules/releases/latest/download/geoip.db")
o.rmempty = false o.rmempty = false
o = s:option(Value, "geosite_path", translate("Custom geosite Path")) o = s:option(Value, "geosite_path", translate("Custom geosite Path"))
@ -202,8 +204,10 @@ if has_singbox then
o.rmempty = false o.rmempty = false
o = s:option(Value, "geosite_url", translate("Custom geosite URL")) o = s:option(Value, "geosite_url", translate("Custom geosite URL"))
o.default = "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db" o.default = "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.db"
o:value("https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db") o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.db")
o:value("https://github.com/1715173329/sing-geosite/releases/latest/download/geosite.db")
o:value("https://github.com/lyc8503/sing-box-rules/releases/latest/download/geosite.db")
o.rmempty = false o.rmempty = false
o = s:option(Button, "_remove_resource", translate("Remove resource files")) o = s:option(Button, "_remove_resource", translate("Remove resource files"))

View File

@ -341,12 +341,12 @@ o:depends({ [option_name("tls")] = true, [option_name("transport")] = "grpc" })
o = s:option(ListValue, option_name("alpn"), translate("alpn")) o = s:option(ListValue, option_name("alpn"), translate("alpn"))
o.default = "default" o.default = "default"
o:value("default", translate("Default")) o:value("default", translate("Default"))
o:value("h3,h2,http/1.1")
o:value("h3,h2")
o:value("h2,http/1.1")
o:value("h3") o:value("h3")
o:value("h2") o:value("h2")
o:value("h3,h2")
o:value("http/1.1") o:value("http/1.1")
o:value("h2,http/1.1")
o:value("h3,h2,http/1.1")
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false }) o:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
-- o = s:option(Value, option_name("minversion"), translate("minversion")) -- o = s:option(Value, option_name("minversion"), translate("minversion"))

View File

@ -298,7 +298,9 @@ function get_valid_nodes()
e.id = e[".name"] e.id = e[".name"]
if e.type and e.remarks then if e.type and e.remarks then
if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then
e["remark"] = "%s[%s] " % {e.type .. " " .. i18n.translatef(e.protocol), e.remarks} local type = e.type
if type == "sing-box" then type = "Sing-Box" end
e["remark"] = "%s[%s] " % {type .. " " .. i18n.translatef(e.protocol), e.remarks}
e["node_type"] = "special" e["node_type"] = "special"
nodes[#nodes + 1] = e nodes[#nodes + 1] = e
end end
@ -312,9 +314,20 @@ function get_valid_nodes()
protocol = "VMess" protocol = "VMess"
elseif protocol == "vless" then elseif protocol == "vless" then
protocol = "VLESS" protocol = "VLESS"
elseif protocol == "shadowsocks" then
protocol = "SS"
elseif protocol == "shadowsocksr" then
protocol = "SSR"
elseif protocol == "wireguard" then
protocol = "WG"
elseif protocol == "hysteria" then
protocol = "HY"
elseif protocol == "hysteria2" then
protocol = "HY2"
else else
protocol = protocol:gsub("^%l",string.upper) protocol = protocol:gsub("^%l",string.upper)
end end
if type == "sing-box" then type = "Sing-Box" end
type = type .. " " .. protocol type = type .. " " .. protocol
end end
if is_ipv6(address) then address = get_ipv6_full(address) end if is_ipv6(address) then address = get_ipv6_full(address) end

View File

@ -307,6 +307,10 @@ local api = require "luci.passwall2.api"
params += opt.query("path", dom_prefix + "grpc_serviceName"); params += opt.query("path", dom_prefix + "grpc_serviceName");
params += opt.query("serviceName", dom_prefix + "grpc_serviceName"); params += opt.query("serviceName", dom_prefix + "grpc_serviceName");
params += opt.query("mode", dom_prefix + "grpc_mode"); params += opt.query("mode", dom_prefix + "grpc_mode");
} else if (v_transport === "splithttp") {
v_transport = "splithttp";
params += opt.query("host", dom_prefix + "splithttp_host");
params += opt.query("path", dom_prefix + "splithttp_path");
} }
params += "&type=" + v_transport; params += "&type=" + v_transport;
@ -329,6 +333,7 @@ local api = require "luci.passwall2.api"
params += "&flow=" + v_flow; params += "&flow=" + v_flow;
} }
params += "&security=" + v_security; params += "&security=" + v_security;
params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName"); params += opt.query("sni", dom_prefix + "tls_serverName");
} }
@ -347,9 +352,37 @@ local api = require "luci.passwall2.api"
var params = ""; var params = "";
if (opt.get(dom_prefix + "tls").checked) { if (opt.get(dom_prefix + "tls").checked) {
params += opt.query("sni", dom_prefix + "tls_serverName"); params += opt.query("sni", dom_prefix + "tls_serverName");
params += "&tls=1" params += "&security=tls"
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure"); params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
} }
// 获取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 += "#" + encodeURI(v_alias.value); params += "#" + encodeURI(v_alias.value);
if (params[0] == "&") { if (params[0] == "&") {
params = params.substring(1); params = params.substring(1);
@ -655,7 +688,7 @@ local api = require "luci.passwall2.api"
var queryParams = query[1]; var queryParams = query[1];
var queryArray = queryParams.split('&'); var queryArray = queryParams.split('&');
var params; var params;
for (i = 0; i < queryArray.length; i++) { for (var i = 0; i < queryArray.length; i++) {
params = queryArray[i].split('='); params = queryArray[i].split('=');
queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || ''); queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || '');
} }
@ -671,10 +704,37 @@ local api = require "luci.passwall2.api"
opt.set(dom_prefix + 'address', m.hostname); opt.set(dom_prefix + 'address', m.hostname);
opt.set(dom_prefix + 'port', m.port || "443"); opt.set(dom_prefix + 'port', m.port || "443");
opt.set(dom_prefix + 'password', decodeURIComponent(password)); opt.set(dom_prefix + 'password', decodeURIComponent(password));
opt.set(dom_prefix + 'tls', queryParam.tls === "1"); 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_serverName', queryParam.peer || queryParam.sni || '');
opt.set(dom_prefix + 'tls_allowInsecure', queryParam.allowinsecure === '1'); opt.set(dom_prefix + 'tls_allowInsecure', queryParam.allowinsecure === '1');
opt.set(dom_prefix + 'mux', queryParam.mux === '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
}
if (m.hash) { if (m.hash) {
opt.set('remarks', decodeURI(m.hash.substr(1))); opt.set('remarks', decodeURI(m.hash.substr(1)));
} }
@ -789,6 +849,7 @@ local api = require "luci.passwall2.api"
opt.set(dom_prefix + 'tls', true); opt.set(dom_prefix + 'tls', true);
opt.set(dom_prefix + 'reality', false) opt.set(dom_prefix + 'reality', false)
opt.set(dom_prefix + 'flow', queryParam.flow || ''); 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_serverName', queryParam.sni || '');
opt.set(dom_prefix + 'tls_allowInsecure', true); opt.set(dom_prefix + 'tls_allowInsecure', true);
if (queryParam.allowinsecure === '0') { if (queryParam.allowinsecure === '0') {
@ -859,6 +920,9 @@ local api = require "luci.passwall2.api"
} else if (queryParam.type === "grpc") { } else if (queryParam.type === "grpc") {
opt.set(dom_prefix + 'grpc_serviceName', (queryParam.serviceName || queryParam.path) || ""); opt.set(dom_prefix + 'grpc_serviceName', (queryParam.serviceName || queryParam.path) || "");
opt.set(dom_prefix + 'grpc_mode', queryParam.mode); opt.set(dom_prefix + 'grpc_mode', queryParam.mode);
} else if (queryParam.type === "splithttp") {
opt.set(dom_prefix + 'splithttp_host', queryParam.host || "");
opt.set(dom_prefix + 'splithttp_path', queryParam.path || "");
} }
if (m.hash) { if (m.hash) {

View File

@ -685,7 +685,8 @@ add_firewall_rule() {
nft "add rule inet fw4 PSW2_OUTPUT_MANGLE meta mark 0xff counter return" nft "add rule inet fw4 PSW2_OUTPUT_MANGLE meta mark 0xff counter return"
# jump chains # jump chains
nft "add rule inet fw4 mangle_prerouting meta nfproto {ipv4} counter jump PSW2_MANGLE" 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" insert_rule_before "inet fw4" "mangle_prerouting" "PSW2_MANGLE" "counter jump PSW2_DIVERT"
#ipv4 tcp redirect mode #ipv4 tcp redirect mode
@ -943,10 +944,11 @@ flush_include() {
} }
gen_include() { gen_include() {
flush_include
local nft_chain_file=$TMP_PATH/PSW2_RULE.nft local nft_chain_file=$TMP_PATH/PSW2_RULE.nft
local nft_set_file=$TMP_PATH/PSW2_SETS.nft local nft_set_file=$TMP_PATH/PSW2_SETS.nft
echo "#!/usr/sbin/nft -f" > $nft_chain_file echo '#!/usr/sbin/nft -f' > $nft_chain_file
echo "#!/usr/sbin/nft -f" > $nft_set_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 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 nft list chain inet fw4 ${chain} >> $nft_chain_file
done done
@ -979,13 +981,15 @@ gen_include() {
nft "add rule inet fw4 nat_output ip protocol tcp counter jump PSW2_OUTPUT_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)
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\""
fi
nft "add rule inet fw4 mangle_prerouting ip protocol udp counter jump PSW2_MANGLE"
[ -n "${is_tproxy}" ] && { [ -n "${is_tproxy}" ] && {
PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "inet fw4" PSW2_MANGLE WAN_IP_RETURN -1) nft "add rule inet fw4 mangle_prerouting ip protocol tcp counter jump PSW2_MANGLE"
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\""
fi
nft "add rule inet fw4 mangle_prerouting meta nfproto {ipv4} counter jump PSW2_MANGLE"
nft "add rule inet fw4 mangle_output ip protocol tcp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_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") \$(sh ${MY_PATH} insert_rule_before "inet fw4" "mangle_prerouting" "PSW2_MANGLE" "counter jump PSW2_DIVERT")

View File

@ -610,6 +610,12 @@ local function processData(szType, content, add_mode, add_from)
end end
end end
elseif szType == "trojan" then elseif szType == "trojan" then
if trojan_type_default == "sing-box" and has_singbox then
result.type = 'sing-box'
elseif trojan_type_default == "xray" and has_xray then
result.type = 'Xray'
end
result.protocol = 'trojan'
local alias = "" local alias = ""
if content:find("#") then if content:find("#") then
local idx_sp = content:find("#") local idx_sp = content:find("#")
@ -655,8 +661,10 @@ local function processData(szType, content, add_mode, add_from)
if sni == "" and params.wshost then sni = params.wshost end if sni == "" and params.wshost then sni = params.wshost end
end end
result.port = port result.port = port
result.tls = '1' result.tls = '1'
result.tls_serverName = peer and peer or sni result.tls_serverName = peer and peer or sni
if params.allowinsecure then if params.allowinsecure then
if params.allowinsecure == "1" or params.allowinsecure == "0" then if params.allowinsecure == "1" or params.allowinsecure == "0" then
result.tls_allowInsecure = params.allowinsecure result.tls_allowInsecure = params.allowinsecure
@ -668,12 +676,71 @@ local function processData(szType, content, add_mode, add_from)
result.tls_allowInsecure = allowInsecure_default and "1" or "0" result.tls_allowInsecure = allowInsecure_default and "1" or "0"
end end
if trojan_type_default == "sing-box" and has_singbox then if not params.type then
result.type = 'sing-box' params.type = "tcp"
elseif trojan_type_default == "xray" and has_xray then
result.type = 'Xray'
end end
result.protocol = 'trojan' params.type = string.lower(params.type)
result.transport = params.type
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.encryption = params.encryption or "none"
result.flow = params.flow or nil
end end
elseif szType == "ssd" then elseif szType == "ssd" then
result.type = "SS" result.type = "SS"
@ -757,9 +824,15 @@ local function processData(szType, content, add_mode, add_from)
end end
end end
if params.type == 'h2' or params.type == 'http' then if params.type == 'h2' or params.type == 'http' then
params.type = "h2" if result.type == "sing-box" then
result.h2_host = params.host result.transport = "http"
result.h2_path = params.path 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 end
if params.type == 'tcp' then if params.type == 'tcp' then
result.tcp_guise = params.headerType or "none" result.tcp_guise = params.headerType or "none"
@ -767,7 +840,7 @@ local function processData(szType, content, add_mode, add_from)
result.tcp_guise_http_path = params.path result.tcp_guise_http_path = params.path
end end
if params.type == 'kcp' or params.type == 'mkcp' then if params.type == 'kcp' or params.type == 'mkcp' then
params.type = "mkcp" result.transport = "mkcp"
result.mkcp_guise = params.headerType or "none" result.mkcp_guise = params.headerType or "none"
result.mkcp_mtu = 1350 result.mkcp_mtu = 1350
result.mkcp_tti = 50 result.mkcp_tti = 50
@ -786,6 +859,10 @@ local function processData(szType, content, add_mode, add_from)
if params.serviceName then result.grpc_serviceName = params.serviceName end if params.serviceName then result.grpc_serviceName = params.serviceName end
result.grpc_mode = params.mode result.grpc_mode = params.mode
end end
if params.type == 'splithttp' then
result.splithttp_host = params.host
result.splithttp_path = params.path
end
result.encryption = params.encryption or "none" result.encryption = params.encryption or "none"
@ -795,6 +872,7 @@ local function processData(szType, content, add_mode, add_from)
if params.security == "tls" or params.security == "reality" then if params.security == "tls" or params.security == "reality" then
result.tls = "1" result.tls = "1"
result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host 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" result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome"
if params.security == "reality" then if params.security == "reality" then
result.reality = "1" result.reality = "1"