update 2024-08-25 20:31:42
This commit is contained in:
parent
e330bc8cb9
commit
512bf97ac2
|
@ -515,6 +515,7 @@ local function processData(szType, content, add_mode, add_from)
|
|||
--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
|
||||
--ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTp4eHh4eHhAeHh4eC54eHh4eC5jb206NTYwMDE#Hong%20Kong-01
|
||||
|
||||
local idx_sp = 0
|
||||
local alias = ""
|
||||
|
@ -549,7 +550,7 @@ local function processData(szType, content, add_mode, add_from)
|
|||
info = info:sub(1, find_index - 1)
|
||||
end
|
||||
|
||||
local hostInfo = split(UrlDecode(info), "@")
|
||||
local hostInfo = split(base64Decode(info), "@")
|
||||
if hostInfo and #hostInfo > 0 then
|
||||
local host_port = hostInfo[#hostInfo]
|
||||
-- [2001:4860:4860::8888]:443
|
||||
|
|
|
@ -244,6 +244,16 @@ node_socks_bind_local:depends({ node = "nil", ["!reverse"] = true })
|
|||
|
||||
s:tab("DNS", translate("DNS"))
|
||||
|
||||
o = s:taboption("DNS", ListValue, "direct_dns_query_strategy", translate("Direct Query Strategy"))
|
||||
o.default = "UseIP"
|
||||
o:value("UseIP")
|
||||
o:value("UseIPv4")
|
||||
o:value("UseIPv6")
|
||||
|
||||
o = s:taboption("DNS", Flag, "write_ipset_direct", translate("Direct DNS result write to IPSet"), translate("Perform the matching direct domain name rules into IP to IPSet/NFTSet, and then connect directly (not entering the core). Maybe conflict with some special circumstances."))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("DNS", ListValue, "remote_dns_protocol", translate("Remote DNS Protocol"))
|
||||
o:value("tcp", "TCP")
|
||||
o:value("doh", "DoH")
|
||||
|
@ -315,10 +325,6 @@ o.remove = function(self, section)
|
|||
end
|
||||
end
|
||||
|
||||
o = s:taboption("DNS", Flag, "write_ipset_direct", translate("Direct DNS result write to IPSet"), translate("Perform the matching direct domain name rules into IP to IPSet/NFTSet, and then connect directly (not entering the core). Maybe conflict with some special circumstances."))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("DNS", Button, "clear_ipset", translate("Clear IPSet"), translate("Try this feature if the rule modification does not take effect."))
|
||||
o.inputstyle = "remove"
|
||||
function o.write(e, e)
|
||||
|
@ -331,6 +337,8 @@ 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
|
||||
|
||||
|
|
|
@ -334,7 +334,15 @@ if singbox_tags:find("with_quic") then
|
|||
o.default = "3"
|
||||
o:depends({ [option_name("protocol")] = "tuic" })
|
||||
|
||||
o = s:option(Value, option_name("tuic_alpn"), translate("QUIC TLS ALPN"))
|
||||
o = s:option(ListValue, option_name("tuic_alpn"), translate("QUIC TLS ALPN"))
|
||||
o.default = "default"
|
||||
o:value("default", translate("Default"))
|
||||
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("protocol")] = "tuic" })
|
||||
end
|
||||
|
||||
|
|
|
@ -413,6 +413,27 @@ local api = require "luci.passwall2.api"
|
|||
if (v_password) {
|
||||
url = encodeURIComponent(v_password.value) + "@" + url
|
||||
}
|
||||
} else if (v_type === "sing-box" && opt.get(dom_prefix + "protocol").value === "tuic") {
|
||||
protocol = "tuic";
|
||||
var v_username = opt.get(dom_prefix + "uuid");
|
||||
var v_password = opt.get(dom_prefix + "password");
|
||||
var v_port = opt.get(dom_prefix + "port");
|
||||
url = encodeURIComponent(v_username.value) +
|
||||
":" + encodeURIComponent(v_password.value) +
|
||||
"@" + _address +
|
||||
":" + v_port.value + "?";
|
||||
|
||||
var params = "";
|
||||
params += opt.query("sni", dom_prefix + "tls_serverName");
|
||||
params += opt.query("alpn", dom_prefix + "tuic_alpn");
|
||||
params += opt.query("congestion_control", dom_prefix + "tuic_congestion_control");
|
||||
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
|
||||
|
||||
params += "#" + encodeURI(v_alias.value);
|
||||
if (params[0] == "&") {
|
||||
params = params.substring(1);
|
||||
}
|
||||
url += params;
|
||||
}
|
||||
if (url) {
|
||||
url = protocol.toLowerCase() + "://" + url;
|
||||
|
@ -980,6 +1001,45 @@ local api = require "luci.passwall2.api"
|
|||
opt.set('remarks', decodeURI(m.hash.substr(1)));
|
||||
}
|
||||
}
|
||||
if (ssu[0] === "tuic") {
|
||||
if (has_singbox) {
|
||||
dom_prefix = "singbox_"
|
||||
opt.set('type', "sing-box");
|
||||
}
|
||||
opt.set(dom_prefix + 'protocol', "tuic");
|
||||
var _parsedUrl = new URL("http://" + ssu[1]);
|
||||
var username = _parsedUrl.username;
|
||||
var password = _parsedUrl.password;
|
||||
var hostname = _parsedUrl.hostname;
|
||||
var port = _parsedUrl.port;
|
||||
var search = _parsedUrl.search;
|
||||
var hash = _parsedUrl.hash;
|
||||
opt.set(dom_prefix + 'uuid', decodeURIComponent(username));
|
||||
opt.set(dom_prefix + 'password', decodeURIComponent(password));
|
||||
opt.set(dom_prefix + 'address', hostname);
|
||||
opt.set(dom_prefix + 'port', port || "443");
|
||||
var queryParam = {};
|
||||
if (search.length > 1) {
|
||||
var query = search.split('?')
|
||||
var queryParams = query[1];
|
||||
var queryArray = queryParams.split('&');
|
||||
var params;
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
opt.set(dom_prefix + 'tuic_congestion_control', queryParam.congestion_control || 'cubic');
|
||||
opt.set(dom_prefix + 'tuic_alpn', queryParam.alpn || 'default');
|
||||
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 (hash) {
|
||||
opt.set('remarks', decodeURIComponent(hash.substr(1)));
|
||||
}
|
||||
}
|
||||
if (dom_prefix && dom_prefix != null) {
|
||||
if (opt.get(dom_prefix + 'port').value) {
|
||||
opt.get(dom_prefix + 'port').focus();
|
||||
|
|
|
@ -286,7 +286,7 @@ lua_api() {
|
|||
|
||||
run_xray() {
|
||||
local flag node redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||
local dns_listen_port remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache write_ipset_direct
|
||||
local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache write_ipset_direct
|
||||
local loglevel log_file config_file
|
||||
local _extra_param=""
|
||||
eval_set_val $@
|
||||
|
@ -394,7 +394,7 @@ run_xray() {
|
|||
|
||||
run_singbox() {
|
||||
local flag node redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||
local dns_listen_port remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache write_ipset_direct
|
||||
local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache write_ipset_direct
|
||||
local loglevel log_file config_file
|
||||
local _extra_param=""
|
||||
eval_set_val $@
|
||||
|
@ -449,7 +449,7 @@ run_singbox() {
|
|||
[ -n "${direct_ipset}" ] && _extra_param="${_extra_param} -direct_ipset ${direct_ipset}"
|
||||
[ -n "${direct_nftset}" ] && _extra_param="${_extra_param} -direct_nftset ${direct_nftset}"
|
||||
}
|
||||
_extra_param="${_extra_param} -direct_dns_udp_port ${DIRECT_DNS_UDP_PORT} -direct_dns_udp_server ${DIRECT_DNS_UDP_SERVER} -direct_dns_query_strategy UseIP"
|
||||
_extra_param="${_extra_param} -direct_dns_udp_port ${DIRECT_DNS_UDP_PORT} -direct_dns_udp_server ${DIRECT_DNS_UDP_SERVER} -direct_dns_query_strategy ${direct_dns_query_strategy}"
|
||||
|
||||
case "$remote_dns_protocol" in
|
||||
udp)
|
||||
|
@ -656,7 +656,7 @@ run_global() {
|
|||
PROXY_IPV6_UDP=1
|
||||
fi
|
||||
V2RAY_ARGS="flag=global node=$NODE redir_port=$REDIR_PORT"
|
||||
V2RAY_ARGS="${V2RAY_ARGS} dns_listen_port=${TUN_DNS_PORT} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY} dns_cache=${DNS_CACHE}"
|
||||
V2RAY_ARGS="${V2RAY_ARGS} dns_listen_port=${TUN_DNS_PORT} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY} dns_cache=${DNS_CACHE}"
|
||||
local msg="${TUN_DNS} (直连DNS:${AUTO_DNS}"
|
||||
|
||||
[ -n "$REMOTE_DNS_PROTOCOL" ] && {
|
||||
|
@ -946,7 +946,7 @@ acl_app() {
|
|||
dnsmasq_port=11400
|
||||
for item in $items; do
|
||||
index=$(expr $index + 1)
|
||||
local enabled sid remarks sources node remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
|
||||
local enabled sid remarks sources node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
|
||||
local _ip _mac _iprange _ipset _ip_or_mac rule_list config_file
|
||||
sid=$(uci -q show "${CONFIG}.${item}" | grep "=acl_rule" | awk -F '=' '{print $1}' | awk -F '.' '{print $2}')
|
||||
eval $(uci -q show "${CONFIG}.${item}" | cut -d'.' -sf 3-)
|
||||
|
@ -975,6 +975,7 @@ acl_app() {
|
|||
tcp_proxy_mode="global"
|
||||
udp_proxy_mode="global"
|
||||
node=${node:-default}
|
||||
direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP}
|
||||
remote_dns_protocol=${remote_dns_protocol:-tcp}
|
||||
remote_dns=${remote_dns:-1.1.1.1}
|
||||
[ "$remote_dns_protocol" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
|
||||
|
@ -1009,7 +1010,7 @@ acl_app() {
|
|||
elif [ "${type}" = "sing-box" ] && [ -n "${SINGBOX_BIN}" ]; then
|
||||
run_func="run_singbox"
|
||||
fi
|
||||
${run_func} flag=acl_$sid node=$node redir_port=$redir_port socks_address=127.0.0.1 socks_port=$acl_socks_port dns_listen_port=${dns_port} direct_dns_query_strategy=UseIP remote_dns_protocol=${remote_dns_protocol} remote_dns_tcp_server=${remote_dns} remote_dns_udp_server=${remote_dns} remote_dns_doh="${remote_dns}" remote_dns_client_ip=${remote_dns_client_ip} remote_dns_detour=${remote_dns_detour} remote_fakedns=${remote_fakedns} remote_dns_query_strategy=${remote_dns_query_strategy} write_ipset_direct=${write_ipset_direct} config_file=${config_file}
|
||||
${run_func} flag=acl_$sid node=$node redir_port=$redir_port socks_address=127.0.0.1 socks_port=$acl_socks_port dns_listen_port=${dns_port} direct_dns_query_strategy=${direct_dns_query_strategy} remote_dns_protocol=${remote_dns_protocol} remote_dns_tcp_server=${remote_dns} remote_dns_udp_server=${remote_dns} remote_dns_doh="${remote_dns}" remote_dns_client_ip=${remote_dns_client_ip} remote_dns_detour=${remote_dns_detour} remote_fakedns=${remote_fakedns} remote_dns_query_strategy=${remote_dns_query_strategy} write_ipset_direct=${write_ipset_direct} config_file=${config_file}
|
||||
fi
|
||||
dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1))
|
||||
redirect_dns_port=$dnsmasq_port
|
||||
|
@ -1040,7 +1041,7 @@ acl_app() {
|
|||
echo "${redir_port}" > $TMP_ACL_PATH/$sid/var_port
|
||||
}
|
||||
[ -n "$redirect_dns_port" ] && echo "${redirect_dns_port}" > $TMP_ACL_PATH/$sid/var_redirect_dns_port
|
||||
unset enabled sid remarks sources node remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
|
||||
unset enabled sid remarks sources node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
|
||||
unset _ip _mac _iprange _ipset _ip_or_mac rule_list config_file
|
||||
unset redirect_dns_port
|
||||
done
|
||||
|
@ -1147,6 +1148,7 @@ TCP_PROXY_MODE="global"
|
|||
UDP_PROXY_MODE="global"
|
||||
LOCALHOST_PROXY=$(config_t_get global localhost_proxy '1')
|
||||
CLIENT_PROXY=$(config_t_get global client_proxy '1')
|
||||
DIRECT_DNS_QUERY_STRATEGY=$(config_t_get global direct_dns_query_strategy UseIP)
|
||||
REMOTE_DNS_PROTOCOL=$(config_t_get global remote_dns_protocol tcp)
|
||||
REMOTE_DNS_DETOUR=$(config_t_get global remote_dns_detour remote)
|
||||
REMOTE_DNS=$(config_t_get global remote_dns 1.1.1.1:53 | sed 's/#/:/g' | sed -E 's/\:([^:]+)$/#\1/g')
|
||||
|
|
|
@ -480,6 +480,10 @@ local function processData(szType, content, add_mode, add_from)
|
|||
if info.net == 'grpc' then
|
||||
result.grpc_serviceName = info.path
|
||||
end
|
||||
if info.net == 'splithttp' then
|
||||
result.splithttp_host = info.host
|
||||
result.splithttp_path = info.path
|
||||
end
|
||||
if not info.security then result.security = "auto" end
|
||||
if info.tls == "tls" or info.tls == "1" then
|
||||
result.tls = "1"
|
||||
|
@ -488,6 +492,11 @@ local function processData(szType, content, add_mode, add_from)
|
|||
else
|
||||
result.tls = "0"
|
||||
end
|
||||
|
||||
if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "splithttp") then
|
||||
log("跳过节点:" .. result.remarks ..",因Sing-Box不支持" .. szType .. "协议的" .. result.transport .. "传输方式,需更换Xray。")
|
||||
return nil
|
||||
end
|
||||
elseif szType == "ss" then
|
||||
result.type = "SS"
|
||||
|
||||
|
@ -737,10 +746,19 @@ local function processData(szType, content, add_mode, add_from)
|
|||
if params.serviceName then result.grpc_serviceName = params.serviceName end
|
||||
result.grpc_mode = params.mode
|
||||
end
|
||||
if params.type == 'splithttp' then
|
||||
result.splithttp_host = params.host
|
||||
result.splithttp_path = params.path
|
||||
end
|
||||
|
||||
result.encryption = params.encryption or "none"
|
||||
|
||||
result.flow = params.flow or nil
|
||||
|
||||
if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "splithttp") then
|
||||
log("跳过节点:" .. result.remarks ..",因Sing-Box不支持" .. szType .. "协议的" .. result.transport .. "传输方式,需更换Xray。")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
elseif szType == "ssd" then
|
||||
result.type = "SS"
|
||||
|
@ -884,6 +902,11 @@ local function processData(szType, content, add_mode, add_from)
|
|||
|
||||
result.port = port
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
|
||||
if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "splithttp") then
|
||||
log("跳过节点:" .. result.remarks ..",因Sing-Box不支持" .. szType .. "协议的" .. result.transport .. "传输方式,需更换Xray。")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
elseif szType == 'hysteria' then
|
||||
local alias = ""
|
||||
|
@ -991,6 +1014,59 @@ local function processData(szType, content, add_mode, add_from)
|
|||
result.hysteria2_obfs_password = params["obfs-password"]
|
||||
end
|
||||
end
|
||||
elseif szType == 'tuic' then
|
||||
local alias = ""
|
||||
if content:find("#") then
|
||||
local idx_sp = content:find("#")
|
||||
alias = content:sub(idx_sp + 1, -1)
|
||||
content = content:sub(0, idx_sp - 1)
|
||||
end
|
||||
result.remarks = UrlDecode(alias)
|
||||
local Info = content
|
||||
if content:find("@") then
|
||||
local contents = split(content, "@")
|
||||
if contents[1]:find(":") then
|
||||
local userinfo = split(contents[1], ":")
|
||||
result.uuid = UrlDecode(userinfo[1])
|
||||
result.password = UrlDecode(userinfo[2])
|
||||
end
|
||||
Info = (contents[2] or ""):gsub("/%?", "?")
|
||||
end
|
||||
local query = split(Info, "?")
|
||||
local host_port = query[1]
|
||||
local params = {}
|
||||
for _, v in pairs(split(query[2], '&')) do
|
||||
local t = split(v, '=')
|
||||
if #t > 1 then
|
||||
params[string.lower(t[1])] = UrlDecode(t[2])
|
||||
end
|
||||
end
|
||||
if host_port:find(":") then
|
||||
local sp = split(host_port, ":")
|
||||
result.port = sp[#sp]
|
||||
if api.is_ipv6addrport(host_port) then
|
||||
result.address = api.get_ipv6_only(host_port)
|
||||
else
|
||||
result.address = sp[1]
|
||||
end
|
||||
else
|
||||
result.address = host_port
|
||||
end
|
||||
result.tls_serverName = params.sni
|
||||
result.tuic_alpn = params.alpn or "default"
|
||||
result.tuic_congestion_control = params.congestion_control or "cubic"
|
||||
if params.allowinsecure then
|
||||
if params.allowinsecure == "1" or params.allowinsecure == "0" then
|
||||
result.tls_allowInsecure = params.allowinsecure
|
||||
else
|
||||
result.tls_allowInsecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
|
||||
end
|
||||
--log(result.remarks .. ' 使用节点AllowInsecure设定: '.. result.tls_allowInsecure)
|
||||
else
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
end
|
||||
result.type = 'sing-box'
|
||||
result.protocol = "tuic"
|
||||
else
|
||||
log('暂时不支持' .. szType .. "类型的节点订阅,跳过此节点。")
|
||||
return nil
|
||||
|
|
Loading…
Reference in New Issue