luci: update subscribe script support ipv6 node

This commit is contained in:
xiaorouji 2023-03-29 13:51:28 +08:00 committed by sbwml
parent ac259f2d11
commit 3a4fa1fcf5

View File

@ -352,15 +352,17 @@ local function processData(szType, content, add_mode, add_from)
add_mode = add_mode, --0为手动配置,1为导入,2为订阅 add_mode = add_mode, --0为手动配置,1为导入,2为订阅
add_from = add_from add_from = add_from
} }
--ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0)
if szType == 'ssr' then if szType == 'ssr' then
result.type = "SSR"
local dat = split(content, "/%?") local dat = split(content, "/%?")
local hostInfo = split(dat[1], ':') local hostInfo = split(dat[1], ':')
result.type = "SSR" if dat[1]:match('%[(.*)%]') then
result.address = "" result.address = dat[1]:match('%[(.*)%]')
for i=1,#hostInfo-5,1 do else
result.address = result.address .. hostInfo[i] .. ":" result.address = hostInfo[#hostInfo-5]
end end
result.address = string.sub(result.address, 0, #result.address-1)
result.port = hostInfo[#hostInfo-4] result.port = hostInfo[#hostInfo-4]
result.protocol = hostInfo[#hostInfo-3] result.protocol = hostInfo[#hostInfo-3]
result.method = hostInfo[#hostInfo-2] result.method = hostInfo[#hostInfo-2]
@ -436,6 +438,15 @@ local function processData(szType, content, add_mode, add_from)
result.tls = "0" result.tls = "0"
end end
elseif szType == "ss" then elseif szType == "ss" then
result.type = "SS"
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
--userinfo = websafe-base64-encode-utf8(method ":" password)
--ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1
--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
local idx_sp = 0 local idx_sp = 0
local alias = "" local alias = ""
if content:find("#") then if content:find("#") then
@ -444,28 +455,9 @@ local function processData(szType, content, add_mode, add_from)
end end
result.remarks = UrlDecode(alias) result.remarks = UrlDecode(alias)
local info = content:sub(1, idx_sp - 1) local info = content:sub(1, idx_sp - 1)
local hostInfo = split(base64Decode(info), "@") if info:find("/%?") then
local hostInfoLen = #hostInfo local find_index = info:find("/%?")
local host = nil local query = split(info, "/%?")
local userinfo = nil
if hostInfoLen > 2 then
host = split(hostInfo[hostInfoLen], ":")
userinfo = {}
for i = 1, hostInfoLen - 1 do
tinsert(userinfo, hostInfo[i])
end
userinfo = table.concat(userinfo, '@')
else
host = split(hostInfo[2], ":")
userinfo = base64Decode(hostInfo[1])
end
local method = userinfo:sub(1, userinfo:find(":") - 1)
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
result.type = "SS"
result.address = host[1]
if host[2] and host[2]:find("/%?") then
local query = split(host[2], "/%?")
result.port = query[1]
local params = {} local params = {}
for _, v in pairs(split(query[2], '&')) do for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
@ -485,55 +477,86 @@ local function processData(szType, content, add_mode, add_from)
if result.plugin and result.plugin == "simple-obfs" then if result.plugin and result.plugin == "simple-obfs" then
result.plugin = "obfs-local" result.plugin = "obfs-local"
end end
else info = info:sub(1, find_index - 1)
result.port = host[2]
end end
result.method = method
result.password = password
local aead = false local hostInfo = split(base64Decode(info), "@")
for k, v in ipairs({"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305"}) do if hostInfo and #hostInfo > 0 then
if method:lower() == v:lower() then local host_port = hostInfo[#hostInfo]
aead = true -- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
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 end
end
if aead then local userinfo = nil
if ss_aead_type_default == "shadowsocks-libev" and has_ss then if #hostInfo > 2 then
result.type = "SS" userinfo = {}
elseif ss_aead_type_default == "shadowsocks-rust" and has_ss_rust then for i = 1, #hostInfo - 1 do
result.type = 'SS-Rust' tinsert(userinfo, hostInfo[i])
if method:lower() == "chacha20-poly1305" then
result.method = "chacha20-ietf-poly1305"
end end
elseif ss_aead_type_default == "v2ray" and has_v2ray and not result.plugin then userinfo = table.concat(userinfo, '@')
result.type = 'V2ray' else
result.protocol = 'shadowsocks' userinfo = base64Decode(hostInfo[1])
result.transport = 'tcp' end
if method:lower() == "chacha20-ietf-poly1305" then
result.method = "chacha20-poly1305" local method = userinfo:sub(1, userinfo:find(":") - 1)
end local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
elseif ss_aead_type_default == "xray" and has_xray and not result.plugin then result.method = method
result.type = 'Xray' result.password = password
result.protocol = 'shadowsocks'
result.transport = 'tcp' local aead = false
if method:lower() == "chacha20-ietf-poly1305" then for k, v in ipairs({"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305"}) do
result.method = "chacha20-poly1305" if method:lower() == v:lower() then
aead = true
end end
end end
end if aead then
local aead2022 = false if ss_aead_type_default == "shadowsocks-libev" and has_ss then
for k, v in ipairs({"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"}) do result.type = "SS"
if method:lower() == v:lower() then elseif ss_aead_type_default == "shadowsocks-rust" and has_ss_rust then
aead2022 = true result.type = 'SS-Rust'
if method:lower() == "chacha20-poly1305" then
result.method = "chacha20-ietf-poly1305"
end
elseif ss_aead_type_default == "v2ray" and has_v2ray and not result.plugin then
result.type = 'V2ray'
result.protocol = 'shadowsocks'
result.transport = 'tcp'
if method:lower() == "chacha20-ietf-poly1305" then
result.method = "chacha20-poly1305"
end
elseif ss_aead_type_default == "xray" and has_xray and not result.plugin then
result.type = 'Xray'
result.protocol = 'shadowsocks'
result.transport = 'tcp'
if method:lower() == "chacha20-ietf-poly1305" then
result.method = "chacha20-poly1305"
end
end
end end
end local aead2022 = false
if aead2022 then for k, v in ipairs({"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"}) do
if ss_aead_type_default == "xray" and has_xray and not result.plugin then if method:lower() == v:lower() then
result.type = 'Xray' aead2022 = true
result.protocol = 'shadowsocks' end
result.transport = 'tcp' end
elseif has_ss_rust then if aead2022 then
result.type = 'SS-Rust' if ss_aead_type_default == "xray" and has_xray and not result.plugin then
result.type = 'Xray'
result.protocol = 'shadowsocks'
result.transport = 'tcp'
elseif has_ss_rust then
result.type = 'SS-Rust'
end
end end
end end
elseif szType == "trojan" then elseif szType == "trojan" then
@ -550,29 +573,28 @@ local function processData(szType, content, add_mode, add_from)
result.password = UrlDecode(Info[1]) result.password = UrlDecode(Info[1])
local port = "443" local port = "443"
Info[2] = (Info[2] or ""):gsub("/%?", "?") Info[2] = (Info[2] or ""):gsub("/%?", "?")
local hostInfo = nil
if Info[2]:find(":") then
hostInfo = split(Info[2], ":")
result.address = hostInfo[1]
local idx_port = 2
if hostInfo[2]:find("?") then
hostInfo = split(hostInfo[2], "?")
idx_port = 1
end
if hostInfo[idx_port] ~= "" then port = hostInfo[idx_port] end
else
if Info[2]:find("?") then
hostInfo = split(Info[2], "?")
end
result.address = hostInfo and hostInfo[1] or Info[2]
end
local peer, sni = nil, ""
local query = split(Info[2], "?") local query = split(Info[2], "?")
local host_port = query[1]
local params = {} local params = {}
for _, v in pairs(split(query[2], '&')) do for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
params[string.lower(t[1])] = UrlDecode(t[2]) params[string.lower(t[1])] = UrlDecode(t[2])
end end
-- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
if host_port:find(":") then
local sp = split(host_port, ":")
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
local peer, sni = nil, ""
if params.peer then peer = params.peer end if params.peer then peer = params.peer end
sni = params.sni and params.sni or "" sni = params.sni and params.sni or ""
if params.ws and params.ws == "1" then if params.ws and params.ws == "1" then
@ -632,29 +654,27 @@ local function processData(szType, content, add_mode, add_from)
result.password = UrlDecode(Info[1]) result.password = UrlDecode(Info[1])
local port = "443" local port = "443"
Info[2] = (Info[2] or ""):gsub("/%?", "?") Info[2] = (Info[2] or ""):gsub("/%?", "?")
local hostInfo = nil
if Info[2]:find(":") then
hostInfo = split(Info[2], ":")
result.address = hostInfo[1]
local idx_port = 2
if hostInfo[2]:find("?") then
hostInfo = split(hostInfo[2], "?")
idx_port = 1
end
if hostInfo[idx_port] ~= "" then port = hostInfo[idx_port] end
else
if Info[2]:find("?") then
hostInfo = split(Info[2], "?")
end
result.address = hostInfo and hostInfo[1] or Info[2]
end
local peer, sni = nil, ""
local query = split(Info[2], "?") local query = split(Info[2], "?")
local host_port = query[1]
local params = {} local params = {}
for _, v in pairs(split(query[2], '&')) do for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
params[string.lower(t[1])] = UrlDecode(t[2]) params[string.lower(t[1])] = UrlDecode(t[2])
end end
-- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
if host_port:find(":") then
local sp = split(host_port, ":")
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
local peer, sni = nil, ""
if params.peer then peer = params.peer end if params.peer then peer = params.peer end
sni = params.sni and params.sni or "" sni = params.sni and params.sni or ""
if params.type and params.type == "ws" then if params.type and params.type == "ws" then
@ -704,29 +724,26 @@ local function processData(szType, content, add_mode, add_from)
result.uuid = UrlDecode(Info[1]) result.uuid = UrlDecode(Info[1])
local port = "443" local port = "443"
Info[2] = (Info[2] or ""):gsub("/%?", "?") Info[2] = (Info[2] or ""):gsub("/%?", "?")
local hostInfo = nil
if Info[2]:find(":") then
hostInfo = split(Info[2], ":")
result.address = hostInfo[1]
local idx_port = 2
if hostInfo[2]:find("?") then
hostInfo = split(hostInfo[2], "?")
idx_port = 1
end
if hostInfo[idx_port] ~= "" then port = hostInfo[idx_port] end
else
if Info[2]:find("?") then
hostInfo = split(Info[2], "?")
end
result.address = hostInfo and hostInfo[1] or Info[2]
end
local query = split(Info[2], "?") local query = split(Info[2], "?")
local host_port = query[1]
local params = {} local params = {}
for _, v in pairs(split(query[2], '&')) do for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
params[t[1]] = UrlDecode(t[2]) params[t[1]] = UrlDecode(t[2])
end end
-- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
if host_port:find(":") then
local sp = split(host_port, ":")
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
params.type = string.lower(params.type) params.type = string.lower(params.type)
if params.type == 'ws' then if params.type == 'ws' then
@ -796,9 +813,7 @@ local function processData(szType, content, add_mode, add_from)
result.type = "Hysteria" result.type = "Hysteria"
local dat = split(content, '%?') local dat = split(content, '%?')
local hostInfo = split(dat[1], ':') local host_port = dat[1]
result.address = hostInfo[1]
result.port = hostInfo[2]
local params = {} local params = {}
for _, v in pairs(split(dat[2], '&')) do for _, v in pairs(split(dat[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
@ -806,6 +821,19 @@ local function processData(szType, content, add_mode, add_from)
params[t[1]] = t[2] params[t[1]] = t[2]
end end
end end
-- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
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.protocol = params.protocol result.protocol = params.protocol
result.hysteria_obfs = params.obfsParam result.hysteria_obfs = params.obfsParam
result.hysteria_auth_type = "string" result.hysteria_auth_type = "string"
@ -1125,8 +1153,8 @@ local function parse_link(raw, add_mode, add_from)
if result then if result then
if not result.type then if not result.type then
log('丢弃节点:' .. result.remarks .. ",找不到可使用二进制.") log('丢弃节点:' .. result.remarks .. ",找不到可使用二进制.")
elseif (add_mode == "2" and is_filter_keyword(result.remarks)) or not result.address or result.remarks == "NULL" or result.address=="127.0.0.1" or elseif (add_mode == "2" and is_filter_keyword(result.remarks)) or not result.address or result.remarks == "NULL" or result.address == "127.0.0.1" or
(not datatypes.hostname(result.address) and not (datatypes.ipmask4(result.address) or datatypes.ipmask6(result.address))) then (not datatypes.hostname(result.address) and not (api.is_ip(result.address))) then
log('丢弃过滤节点: ' .. result.type .. ' 节点, ' .. result.remarks) log('丢弃过滤节点: ' .. result.type .. ' 节点, ' .. result.remarks)
else else
tinsert(node_list, result) tinsert(node_list, result)