🌈 Sync 2026-05-19 02:35:14

This commit is contained in:
github-actions[bot] committed 2026-05-19 02:35:14 +08:00
1 parent 595807ea37
commit ca5e918f4b
81 files changed
+12003 -3193

No files matched your search

+1 -14
View File
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.5.11
PKG_RELEASE:=126
PKG_RELEASE:=127
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \
@@ -18,8 +18,6 @@ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \
@@ -43,9 +41,6 @@ LUCI_DEPENDS:=+coreutils +coreutils-base64 +coreutils-nohup +curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy:haproxy \
+PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria:hysteria \
+PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client:shadowsocks-libev-ss-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client:shadowsocks-libev-ss-redir \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Server:shadowsocks-libev-ss-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client:shadowsocks-rust-sslocal \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server:shadowsocks-rust-ssserver \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-local \
@@ -106,14 +101,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy
select PACKAGE_naiveproxy
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client
bool "Include Shadowsocks Libev Client"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Server
bool "Include Shadowsocks Libev Server"
default y if aarch64||arm||i386||x86_64
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client
bool "Include Shadowsocks Rust Client"
depends on !i386
@@ -1,7 +1,6 @@
local api = require "luci.passwall.api"
local uci = api.uci
local appname = "passwall"
local has_ss = api.is_finded("ss-redir")
local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray")
@@ -12,10 +11,6 @@ local vmess_type = {}
local vless_type = {}
local hysteria2_type = {}
local xray_version = api.get_app_version("xray")
if has_ss then
local s = "shadowsocks-libev"
table.insert(ss_type, s)
end
if has_ss_rust then
local s = "shadowsocks-rust"
table.insert(ss_type, s)
@@ -16,7 +16,6 @@ end
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
local has_ss = api.is_finded("ss-redir")
local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray")
@@ -27,10 +26,6 @@ local vmess_type = {}
local vless_type = {}
local hysteria2_type = {}
local xray_version = api.get_app_version("xray")
if has_ss then
local s = "shadowsocks-libev"
table.insert(ss_type, s)
end
if has_ss_rust then
local s = "shadowsocks-rust"
table.insert(ss_type, s)
@@ -262,6 +262,13 @@ if load_balancing_options then -- [[ Load balancing Start ]]
o.default = "2"
o.placeholder = "2"
o.description = translate("The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them.")
o = s:option(Value, _n("tolerance"), translate("Failure Tolerance (%)"))
o:depends({ [_n("balancingStrategy")] = "leastLoad" })
o.datatype = "uinteger"
o.default = "10"
o.placeholder = "10"
o.description = translate("The maximum acceptable speed test failure rate. For example, 1 means allowing a 1% failure rate.")
end -- [[ 负载均衡 End ]]
if load_iface_options then -- [[ 自定义接口 Start ]]
@@ -43,6 +43,8 @@ local security_list = { "none", "auto", "aes-128-gcm", "chacha20-poly1305", "zer
local singbox_tags = luci.sys.exec(singbox_bin .. " version | grep 'Tags:' | awk '{print $2}'")
local singbox_version = api.get_app_version("sing-box"):match("[^v]+")
o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("socks", "Socks")
o:value("http", "HTTP")
@@ -351,13 +353,28 @@ end
if singbox_tags:find("with_quic") then
o = s:option(Value, _n("hysteria2_hop"), translate("Port hopping range"))
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
o:depends({ [_n("protocol")] = "hysteria2" })
o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false })
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
o.datatype = "or(uinteger,portrange)"
o.placeholder = "30"
o.default = "30"
o:depends({ [_n("protocol")] = "hysteria2" })
o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false })
o = s:option(Flag, _n("hysteria2_realms"), translate("Realms"))
o.default = "0"
if api.compare_versions(singbox_version, ">=", "1.14.0") then
o:depends({ [_n("protocol")] = "hysteria2"})
else
o:depends({ [_n("protocol")] = "__hide"})
end
o = s:option(Value, _n("hysteria2_realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name")
o:depends({ [_n("hysteria2_realms")] = "1" })
o = s:option(DynamicList, _n("hysteria2_realm_stun"), translate("Realm STUN"))
o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" }
o:depends({ [_n("hysteria2_realms")] = "1" })
o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
o.password = true
@@ -479,7 +496,7 @@ o.default = "0"
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [_n("protocol")] = "hysteria2" })
o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false })
o:depends({ [_n("protocol")] = "naive" })
o = s:option(TextValue, _n("ech_config"), translate("ECH Config"))
@@ -787,10 +804,14 @@ local protocols = s.fields[_n("protocol")].keylist
if #protocols > 0 then
for i, v in ipairs(protocols) do
if not v:find("^_") then
s.fields[_n("address")]:depends({ [_n("protocol")] = v })
s.fields[_n("port")]:depends({ [_n("protocol")] = v })
s.fields[_n("domain_resolver")]:depends({ [_n("protocol")] = v })
s.fields[_n("domain_strategy")]:depends({ [_n("protocol")] = v })
local depends_condition = { [_n("protocol")] = v }
if v == "hysteria2" then
depends_condition[_n("hysteria2_realms")] = false
end
s.fields[_n("address")]:depends(depends_condition)
s.fields[_n("port")]:depends(depends_condition)
s.fields[_n("domain_resolver")]:depends(depends_condition)
s.fields[_n("domain_strategy")]:depends(depends_condition)
end
end
end
@@ -805,6 +826,7 @@ if not load_shunt_options then
o:value("1", translate("Preproxy Node"))
end
o:value("2", translate("Landing Node"))
o:depends({ [_n("hysteria2_realms")] = false })
o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
o1:depends({ [_n("chain_proxy")] = "1" })
@@ -1,66 +0,0 @@
local m, s = ...
if not api.is_finded("ss-local") and not api.is_finded("ss-redir") then
return
end
type_name = "SS"
-- [[ Shadowsocks Libev ]]
s.fields["type"]:value(type_name, "Shadowsocks Libev")
if s.val["type"] ~= type_name then
return
end
local option_prefix = "ss_"
local function _n(name)
return option_prefix .. name
end
local ss_encrypt_method_list = {
"rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr",
"aes-192-ctr", "aes-256-ctr", "bf-cfb", "salsa20", "chacha20", "chacha20-ietf",
"aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305"
}
o = s:option(ListValue, _n("del_protocol")) --始终隐藏,用于删除 protocol
o:depends({ [_n("__hide")] = "1" })
o.rewrite_option = "protocol"
o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port"
o = s:option(Value, _n("password"), translate("Password"))
o.password = true
o = s:option(Value, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end
o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger"
o.default = 300
o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required"))
o.default = 0
o = s:option(Flag, _n("plugin_enabled"), translate("plugin"))
o.default = 0
o = s:option(ListValue, _n("plugin"), "SIP003 " .. translate("plugin"))
o.default = "none"
o:value("none", translate("none"))
if api.is_finded("xray-plugin") then o:value("xray-plugin") end
if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end
if api.is_finded("obfs-local") then o:value("obfs-local") end
o:depends({ [_n("plugin_enabled")] = true })
o = s:option(Value, _n("plugin_opts"), translate("opts"))
o:depends({ [_n("plugin_enabled")] = true })
api.luci_types(arg[1], m, s, type_name, option_prefix)
@@ -24,6 +24,7 @@ o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o.rmempty = false
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("realms"), translate("Realms"))
@@ -55,6 +55,7 @@ o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o.rmempty = false
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("auth"), translate("Auth"))
@@ -154,6 +155,17 @@ if singbox_tags:find("with_quic") then
end
if singbox_tags:find("with_quic") then
o = s:option(Flag, _n("hysteria2_realms"), translate("Realms"))
o.default = "0"
o:depends({ [_n("protocol")] = "hysteria2"})
o = s:option(Value, _n("hysteria2_realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name")
o:depends({ [_n("hysteria2_realms")] = "1" })
o = s:option(DynamicList, _n("hysteria2_realm_stun"), translate("Realm STUN"))
o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" }
o:depends({ [_n("hysteria2_realms")] = "1" })
o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
o.password = true
o:depends({ [_n("protocol")] = "hysteria2"})
@@ -321,7 +333,7 @@ o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o:depends({ [_n("protocol")] = "naive" })
o:depends({ [_n("protocol")] = "hysteria" })
o:depends({ [_n("protocol")] = "tuic" })
o:depends({ [_n("protocol")] = "hysteria2" })
o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false })
o = s:option(TextValue, _n("ech_key"), translate("ECH Key"))
o.default = ""
@@ -1,78 +0,0 @@
local m, s = ...
local api = require "luci.passwall.api"
if not api.is_finded("ss-server") then
return
end
local type_name = "SS"
local option_prefix = "ss_"
local function _n(name)
return option_prefix .. name
end
local ss_encrypt_method_list = {
"rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr",
"aes-192-ctr", "aes-256-ctr", "bf-cfb", "camellia-128-cfb",
"camellia-192-cfb", "camellia-256-cfb", "salsa20", "chacha20",
"chacha20-ietf", -- aead
"aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305"
}
-- [[ Shadowsocks ]]
s.fields["type"]:value(type_name, translate("Shadowsocks"))
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("password"), translate("Password"))
o.password = true
o:depends({ [_n("custom")] = false })
o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger"
o.default = 300
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0"
o:depends({ [_n("custom")] = false })
o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
o.rows = 10
o.wrap = "off"
o:depends({ [_n("custom")] = true })
o.validate = function(self, value, t)
if value and api.jsonc.parse(value) then
return value
else
return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!")
end
end
o.custom_cfgvalue = function(self, section, value)
local config_str = m:get(section, "config_str")
if config_str then
return api.base64Decode(config_str)
end
end
o.custom_write = function(self, section, value)
m:set(section, "config_str", api.base64Encode(value) or "")
end
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"
o.rmempty = false
api.luci_types(arg[1], m, s, type_name, option_prefix)
+34 -3
View File
@@ -472,9 +472,10 @@ function get_valid_nodes()
end
end
local port = e.port or e.hysteria_hop or e.hysteria2_hop
if (port and e.address) or e.hysteria2_realms then
local is_realm = (e.type == "Hysteria2" or e.protocol == 'hysteria2') and e.hysteria2_realms or nil
if (port and e.address) or is_realm then
local address = e.address
if is_ip(address) or datatypes.hostname(address) or e.hysteria2_realms then
if is_ip(address) or datatypes.hostname(address) or is_realm then
if (e.type == "sing-box" or e.type == "Xray") and e.protocol then
local protocol = e.protocol
if protocol == "vmess" then
@@ -501,10 +502,11 @@ function get_valid_nodes()
type_name = type_name .. " " .. protocol
end
if is_ipv6(address) then address = get_ipv6_full(address) end
type_name = is_realm and type_name .. " Realm" or type_name
e["remark"] = trim("%s:[%s]" % {type_name, e.remarks})
if show_node_info == "1" then
port = (port or ""):gsub(":", "-")
if not e.hysteria2_realms then
if not is_realm then
e["remark"] = trim("%s:[%s] %s:%s" % {type_name, e.remarks, address, port})
end
end
@@ -596,6 +598,9 @@ function get_node_remarks(n)
end
type_name = type_name .. " " .. protocol
end
if (n.type == "Hysteria2" or n.protocol == 'hysteria2') and n.hysteria2_realms then
type_name = type_name .. " Realm"
end
remarks = trim("%s:[%s]" % {type_name, n.remarks})
end
end
@@ -1595,3 +1600,29 @@ function vps_domain_exclude(domain)
if map[domain] then return true end
return false
end
function parse_realm_uri(uri)
if type(uri) ~= "string" then return nil end
-- realm://token@server/realm_id?query
local token, server_url, realm_id, query = trim(uri):match("^realm://([^@]+)@([^/]+)/([^?]*)%??(.*)$")
if not token or not server_url or not realm_id then return nil end
realm_id = realm_id:gsub("/+$", "")
local realm = {
token = token,
server_url = server_url,
realm_id = realm_id
}
-- 解析 query 中的 stun=
if query and query ~= "" then
local stun_servers = {}
for key, value in query:gmatch("([^&=?]+)=([^&]+)") do
if key == "stun" and value ~= "" then
stun_servers[#stun_servers + 1] = value
end
end
if #stun_servers > 0 then
realm.stun_servers = stun_servers
end
end
return realm
end
@@ -132,7 +132,7 @@ local function start()
end
end
bin = ln_run("/usr/bin/microsocks", "microsocks_" .. id, string.format("-i :: -p %s %s", port, auth), log_path)
elseif type == "SS" or type == "SSR" then
elseif type == "SSR" then
if user.custom == "1" and user.config_str then
config = jsonc.parse(api.base64Decode(user.config_str))
else
@@ -67,11 +67,7 @@ function gen_config(var)
server_host = api.get_ipv6_full(server_host)
end
local server = server_host .. (server_port and ":" .. server_port or "")
if node.hysteria2_hop then
server = server .. (server_port and "," or ":") .. string.gsub(node.hysteria2_hop, ":", "-")
end
local server = server_host .. ":" .. ((server_port or "") .. "," .. (node.hysteria2_hop or "")):gsub("^[%s,]+", ""):gsub("[%s,]+$", ""):gsub(":", "-")
local config = {
server = (function()
@@ -80,11 +80,7 @@ function gen_config(var)
tcp_tproxy = var["tcp_tproxy"] and true or nil
}
if node.type == "SS" then
config.plugin = plugin_file or nil
config.plugin_opts = (plugin_file) and node.plugin_opts or nil
config.mode = mode
elseif node.type == "SSR" then
if node.type == "SSR" then
config.protocol = node.protocol
config.protocol_param = node.protocol_param
config.obfs = node.obfs
@@ -103,8 +103,8 @@ function gen_outbound(flag, node, tag, proxy_table)
local run_socks_instance = true
if proxy_table ~= nil and type(proxy_table) == "table" then
proxy_tag = proxy_table.tag or nil
fragment = (proxy_table.fragment and node.protocol ~= "naive") and true or nil
record_fragment = (proxy_table.record_fragment and node.protocol ~= "naive") and true or nil
fragment = (proxy_table.fragment and node.protocol ~= "naive" and not node.hysteria2_realms) and true or nil
record_fragment = (proxy_table.record_fragment and node.protocol ~= "naive" and not node.hysteria2_realms) and true or nil
run_socks_instance = proxy_table.run_socks_instance
end
@@ -472,6 +472,7 @@ function gen_outbound(flag, node, tag, proxy_table)
table.insert(server_ports, range)
end
end
result.server_port = nil
end
protocol_table = {
server_ports = next(server_ports) and server_ports or nil,
@@ -528,6 +529,10 @@ function gen_outbound(flag, node, tag, proxy_table)
table.insert(server_ports, range)
end
end
result.server_port = nil
end
if node.hysteria2_realms then
server_ports = {}
end
local interval, interval_max
if next(server_ports) then
@@ -571,7 +576,18 @@ function gen_outbound(flag, node, tag, proxy_table)
return (t and t >= 2 and t <= 60) and t or nil
end)(node.hysteria2_keep_alive_period),
disable_path_mtu_discovery = version_ge_1_14_0 and (tonumber(node.hysteria2_disable_mtu_discovery) == 1) or nil,
tls = tls
tls = tls,
realm = node.hysteria2_realms and (function()
result.server = nil
result.server_port = nil
local realm = api.parse_realm_uri(node.hysteria2_realm_url)
if realm then
realm.server_url = realm.server_url and "https://" .. realm.server_url or nil
realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun
return realm
end
return nil
end)() or nil
}
end
@@ -908,7 +924,17 @@ function gen_config_server(node)
}
},
ignore_client_bandwidth = (node.hysteria2_ignore_client_bandwidth == "1") and true or false,
tls = tls
tls = tls,
realm = node.hysteria2_realms and (function()
local realm = api.parse_realm_uri(node.hysteria2_realm_url)
if realm then
realm.server_url = realm.server_url and "https://" .. realm.server_url or nil
realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun
realm.stun_domain_resolver = "direct"
return realm
end
return nil
end)() or nil
}
end
@@ -2088,7 +2114,7 @@ function gen_config(var)
if not value.detour and value.server then
value.detour = "direct"
end
if value.server and not api.datatypes.hostname(value.server) then
if (value.server and not api.datatypes.hostname(value.server)) and not value.realm then
value.domain_resolver = nil
end
for k, v in pairs(config.outbounds[index]) do
@@ -1072,7 +1072,13 @@ function gen_config(var)
type = _node.balancingStrategy,
settings = {
expected = _node.expected and tonumber(_node.expected) and tonumber(_node.expected) or 2,
maxRTT = "1s"
maxRTT = "1s",
tolerance = (function(t)
t = tonumber(t) or 0
if t < 1 then return nil end
if t > 100 then t = 100 end
return t / 100
end)(_node.tolerance)
}
}
else
@@ -4,13 +4,12 @@ local api = require "luci.passwall.api"
local appname = api.appname
local map = self.map
local has_ss = api.is_finded("ss-redir")
local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria")
local ss_type = api.get_core("ss_type", {{has_ss,"shadowsocks-libev"},{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}})
local ss_type = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}})
local trojan_type = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}})
local vmess_type = api.get_core("vmess_type", {{has_xray,"xray"},{has_singbox,"sing-box"}})
local vless_type = api.get_core("vless_type", {{has_xray,"xray"},{has_singbox,"sing-box"}})
@@ -165,10 +164,7 @@ local current_node = map:get(section)
var dom_prefix = null
var protocol = ""
if (v_type === "SS") {
dom_prefix = "ss_"
protocol = "ss"
} else if (v_type === "SS-Rust") {
if (v_type === "SS-Rust") {
dom_prefix = "ssrust_"
protocol = "ss"
} else if (v_type === "SSR") {
@@ -196,7 +192,7 @@ local current_node = map:get(section)
}
}
var url = null;
if (v_type === "SS" || v_type === "SS-Rust" || ((v_type === "sing-box" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "shadowsocks")) {
if (v_type === "SS-Rust" || ((v_type === "sing-box" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "shadowsocks")) {
protocol = "ss"
var v_port = opt.get(dom_prefix + "port");
var v_method = opt.get(dom_prefix + "method") || opt.get(dom_prefix + "ss_method");
@@ -1000,17 +996,9 @@ local current_node = map:get(section)
dom_prefix = "singbox_"
opt.set('type', "sing-box");
opt.set(dom_prefix + 'protocol', "shadowsocks");
} else if (ss_type == "shadowsocks-rust") {
} else {
dom_prefix = "ssrust_"
opt.set('type', "SS-Rust");
} else {
if (["2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"].includes(method)) {
dom_prefix = "ssrust_"
opt.set('type', "SS-Rust");
} else {
dom_prefix = "ss_"
opt.set('type', "SS");
}
}
const _method = (method || "none").toLowerCase();
@@ -910,7 +910,11 @@ table td, .table .td {
} else {
port_s = o["hysteria_hop"] || o["hysteria2_hop"];
}
str += type + ":" + remarks;
if ((o.type === "Hysteria2" || o.protocol === 'hysteria2') && o.hysteria2_realms) {
str += type + " Realm:" + remarks;
} else {
str += type + ":" + remarks;
}
return str;
}
@@ -952,7 +956,7 @@ table td, .table .td {
var newDom = node_template.cloneNode(true);
newDom.classList.add("cbi-rowstyle-" + (i % 2 + 1));
var innerHTML = newDom.innerHTML;
if (auto_detection_time != "icmp" && o["address"] && o["port"]) {
if (auto_detection_time != "icmp" && o["address"]) {
innerHTML = innerHTML.split("{{ping}}").join('<span class="ping"><a href="javascript:void(0)" onclick="javascript:ping_node(\'{{id}}\', this, \'icmp\')"><%:Test%></a></span>');
} else {
innerHTML = innerHTML.split("{{ping}}").join('<span class="ping_value" cbiid="{{id}}"><a href="javascript:void(0)" style="color:inherit">---</a></span>');
@@ -962,7 +966,8 @@ table td, .table .td {
} else {
innerHTML = innerHTML.split("{{tcping}}").join('<span class="tcping_value" cbiid="{{id}}"><a href="javascript:void(0)" style="color:inherit">---</a></span>');
}
if (o["protocol"] && o["protocol"] === '_shunt') {
let is_realm = (o.type === "Hysteria2" || o.protocol === 'hysteria2') && o.hysteria2_realms || false;
if (o["protocol"] === '_shunt' || is_realm) {
innerHTML = innerHTML.split("{{url_test}}").join('<span class="ping" cbiid="{{id}}">---</span>');
} else {
innerHTML = innerHTML.split("{{url_test}}").join('<span class="ping"><a href="javascript:void(0)" onclick="javascript:urltest_node(\'{{id}}\', this)" title="<%:TLS handshake test, latency for reference only%>"><%:Test%></a></span>');
@@ -971,11 +976,13 @@ table td, .table .td {
innerHTML = innerHTML.split("{{group}}").join(o["group"] || "");
let node_remarks = get_remarks_name(o);
if (show_node_info == "1") {
if (o["address"] && o["port"]) {
let _port = o["port"] || o["hysteria_hop"] || o["hysteria2_hop"];
if (_port) _port = _port.replace(/:/g, '-');
if (o["address"] && _port) {
let _address = o["address"]
if (o["full_address"])
_address = o["full_address"]
node_remarks += "<br>" + _address + ":" + o["port"]
node_remarks += "<br>" + _address + ":" + _port
}
}
innerHTML = innerHTML.split("{{remarks}}").join(node_remarks);
+6
View File
@@ -577,6 +577,12 @@ msgstr "优选节点数量"
msgid "The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them."
msgstr "负载均衡器选出最优节点的个数,流量将在这几个节点中随机分配。"
msgid "Failure Tolerance (%)"
msgstr "测速失败率容忍度(%)"
msgid "The maximum acceptable speed test failure rate. For example, 1 means allowing a 1% failure rate."
msgstr "最多可接受的测速失败率,例如 1 表示允许 1% 的测速失败率。"
msgid "Shunt"
msgstr "分流"
@@ -374,7 +374,7 @@ run_socks() {
fi
fi
if [ -n "${error_msg}" ] && [ "$(config_n_get $node hysteria2_realms)" = "1" ]; then
if [ -n "${error_msg}" ] && ([ -n "$(config_n_get $node hysteria_hop)" ] || [ -n "$(config_n_get $node hysteria2_hop)" ] || [ "$(config_n_get $node hysteria2_realms)" = "1" ]); then
unset error_msg
fi
@@ -463,17 +463,6 @@ run_socks() {
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u
;;
ss)
[ -n "$no_run" ] || {
local plugin_sh="${config_file%.json}_plugin.sh"
json_add_string "plugin_sh" "$plugin_sh"
}
json_add_string "local_addr" "$bind"
json_add_string "local_port" "$socks_port"
json_add_string "mode" "tcp_and_udp"
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v
;;
ss-rust)
[ "$http_port" != "0" ] && {
http_flag=1
@@ -632,15 +621,6 @@ run_redir() {
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v -U
;;
ss)
local plugin_sh="${config_file%.json}_plugin.sh"
json_add_string "plugin_sh" "$plugin_sh"
json_add_string "local_addr" "0.0.0.0"
json_add_string "local_port" "$local_port"
json_add_string "mode" "udp_only"
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ss-redir)" "ss-redir" $log_file -c "$config_file" -v
;;
ss-rust)
local plugin_sh="${config_file%.json}_plugin.sh"
json_add_string "plugin_sh" "$plugin_sh"
@@ -889,23 +869,6 @@ run_redir() {
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v ${_extra_param}
;;
ss)
[ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true"
if [ "$TCP_UDP" = "1" ]; then
config_file="${config_file//TCP/TCP_UDP}"
UDP_REDIR_PORT=$TCP_REDIR_PORT
unset UDP_NODE
json_add_string "mode" "tcp_and_udp"
else
json_add_string "mode" "tcp_only"
fi
local plugin_sh="${config_file%.json}_plugin.sh"
json_add_string "plugin_sh" "$plugin_sh"
json_add_string "local_addr" "0.0.0.0"
json_add_string "local_port" "$local_port"
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ss-redir)" "ss-redir" $log_file -c "$config_file" -v
;;
ss-rust)
json_add_string "local_tcp_redir_port" "$local_port"
[ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true"
@@ -2049,8 +2012,8 @@ get_config() {
FILTER_PROXY_IPV6=$(config_t_get global filter_proxy_ipv6 0)
DNS_REDIRECT=$(config_t_get global dns_redirect 1)
REDIRECT_LIST="socks ss ss-rust ssr sing-box xray naiveproxy hysteria2"
TPROXY_LIST="socks ss ss-rust ssr sing-box xray hysteria2"
REDIRECT_LIST="socks ss-rust ssr sing-box xray naiveproxy hysteria2"
TPROXY_LIST="socks ss-rust ssr sing-box xray hysteria2"
NEXT_DNS_LISTEN_PORT=15353
TUN_DNS="127.0.0.1#${NEXT_DNS_LISTEN_PORT}"
@@ -24,7 +24,6 @@ local UrlDecode = api.UrlDecode
local uci = api.uci
local fs = api.fs
local has_ss = api.is_finded("ss-redir")
local has_ss_rust = api.is_finded("sslocal")
local has_ssr = api.is_finded("ssr-local") and api.is_finded("ssr-redir")
local has_singbox = api.finded_com("sing-box")
@@ -35,7 +34,7 @@ local DEFAULT_FILTER_KEYWORD_MODE = uci:get(appname, "@global_subscribe[0]", "fi
local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}
local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(appname, "@global_subscribe[0]", "filter_keep_list") or {}
-- 取节点使用core类型(节点订阅页面未设置时,自动取默认)
local DEFAULT_SS_TYPE = api.get_core("ss_type", {{has_ss,"shadowsocks-libev"},{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}})
local DEFAULT_SS_TYPE = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}})
local DEFAULT_TROJAN_TYPE = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}})
local DEFAULT_VMESS_TYPE = api.get_core("vmess_type", {{has_xray,"xray"},{has_singbox,"sing-box"}})
local DEFAULT_VLESS_TYPE = api.get_core("vless_type", {{has_xray,"xray"},{has_singbox,"sing-box"}})
@@ -43,7 +42,6 @@ local DEFAULT_HYSTERIA2_TYPE = api.get_core("hysteria2_type", {{has_hysteria2,"h
local core_has = {
["xray"] = has_xray,
["sing-box"] = has_singbox,
["shadowsocks-libev"] = has_ss,
["shadowsocks-rust"] = has_ss_rust,
["hysteria2"] = has_hysteria2
}
@@ -482,9 +480,7 @@ end
-- 设置 ss 协议实现类型
local function set_ss_implementation(ss_type, result)
if ss_type == "shadowsocks-libev" and has_ss then
result.type = "SS"
elseif ss_type == "shadowsocks-rust" and has_ss_rust then
if ss_type == "shadowsocks-rust" and has_ss_rust then
result.type = 'SS-Rust'
elseif ss_type == "xray" and has_xray then
result.type = 'Xray'
@@ -835,20 +831,6 @@ local function processData(szType, content, add_mode, group, sub_cfg)
end
end
if result.type == "SS" then
local aead2022_methods = { "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" }
local aead2022 = false
for k, v in ipairs(aead2022_methods) do
if method:lower() == v:lower() then
aead2022 = true
end
end
if aead2022 then
-- shadowsocks-libev 不支持2022加密
result.error_msg = "shadowsocks-libev 不支持2022加密。"
end
end
if params.type then
params.type = string.lower(params.type)
if result.type == "sing-box" and params.type == "raw" then
@@ -862,7 +844,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
else
result.transport = params.type
end
if result.type ~= "SS-Rust" and result.type ~= "SS" then
if result.type ~= "SS-Rust" then
if params.type == 'ws' then
result.ws_host = params.host
result.ws_path = params.path