mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-02 20:33:56 +08:00
update 2026-06-04 00:28:20
This commit is contained in:
1 parent
a3dfac28a4
commit
623cdab94c
36 files changed
+468
-228
No files matched your search
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall2
|
||||
PKG_VERSION:=26.5.19
|
||||
PKG_VERSION:=26.6.3
|
||||
PKG_RELEASE:=1
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ function index()
|
||||
local appname = api.appname -- global definitions not available
|
||||
local uci = api.uci -- in function index()
|
||||
entry({"admin", "services", appname}).dependent = true
|
||||
entry({"admin", "services", appname, "reset_config"}, call("reset_config")).leaf = true
|
||||
entry({"admin", "services", appname, "show"}, call("show_menu")).leaf = true
|
||||
entry({"admin", "services", appname, "hide"}, call("hide_menu")).leaf = true
|
||||
local e
|
||||
@@ -109,6 +108,7 @@ function index()
|
||||
--[[Backup]]
|
||||
entry({"admin", "services", appname, "create_backup"}, call("create_backup")).leaf = true
|
||||
entry({"admin", "services", appname, "restore_backup"}, call("restore_backup")).leaf = true
|
||||
entry({"admin", "services", appname, "reset_config"}, call("reset_config")).leaf = true
|
||||
|
||||
--[[geoview]]
|
||||
entry({"admin", "services", appname, "geo_view"}, call("geo_view")).leaf = true
|
||||
@@ -130,6 +130,8 @@ local function http_write_json_error(data)
|
||||
end
|
||||
|
||||
function reset_config()
|
||||
uci:revert(appname)
|
||||
luci.sys.call("echo '' > /tmp/log/passwall2.log")
|
||||
luci.sys.call('/etc/init.d/passwall2 stop')
|
||||
luci.sys.call('[ -f "/usr/share/passwall2/0_default_config" ] && cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2')
|
||||
http.redirect(api.url())
|
||||
@@ -745,6 +747,7 @@ function restore_backup()
|
||||
fp:write(decoded)
|
||||
fp:close()
|
||||
if chunk_index + 1 == total_chunks then
|
||||
uci:revert(appname)
|
||||
api.sys.call("echo '' > /tmp/log/passwall2.log")
|
||||
api.log(0, string.format(" * PassWall2 %s", i18n.translate("Configuration file uploaded successfully…")))
|
||||
local temp_dir = '/tmp/passwall2_bak'
|
||||
|
||||
@@ -72,7 +72,7 @@ end
|
||||
|
||||
m:append(Template(appname .. "/global/status"))
|
||||
|
||||
global_cfgid = m:get("@global[0]")[".name"]
|
||||
global_cfgid = (m:get("@global[0]") or {})[".name"] or ""
|
||||
|
||||
s = m:section(TypedSection, "global")
|
||||
s.anonymous = true
|
||||
|
||||
@@ -59,11 +59,13 @@ o.rewrite_option = o.option
|
||||
o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value("salamander")
|
||||
o:value("gecko")
|
||||
o.rewrite_option = o.option
|
||||
|
||||
o = s:option(Value, _n("obfs_password"), translate("Obfs Password"))
|
||||
o.rewrite_option = o.option
|
||||
o:depends({ [_n("obfs_type")] = "salamander" })
|
||||
o:depends({ [_n("obfs_type")] = "gecko" })
|
||||
|
||||
o = s:option(Flag, _n("fast_open"), translate("Fast Open"))
|
||||
o.default = "0"
|
||||
|
||||
@@ -339,13 +339,28 @@ o:depends({ [_n("protocol")] = "vless" })
|
||||
---- [[hysteria2]]
|
||||
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(xray_version, ">", "26.5.9") 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
|
||||
@@ -354,10 +369,12 @@ o:depends({ [_n("protocol")] = "hysteria2"})
|
||||
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value("salamander")
|
||||
o:value("gecko")
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
|
||||
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
|
||||
o:depends({ [_n("hysteria2_obfs_type")] = "gecko" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
@@ -431,11 +448,26 @@ if api.compare_versions(xray_version, ">=", "26.1.31") then
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
end
|
||||
|
||||
o = s:option(Flag, _n("ech"), translate("ECH"))
|
||||
o = s:option(Flag, _n("tls_certificate"), translate("TLS Certificate (PEM)"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(TextValue, _n("tls_certificate_pem"), " ", translate("Full certificate (chain), PEM format."))
|
||||
o.default = ""
|
||||
o.rows = 5
|
||||
o.wrap = "off"
|
||||
o:depends({ [_n("tls_certificate")] = true })
|
||||
o.validate = function(self, value)
|
||||
value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
|
||||
return value
|
||||
end
|
||||
|
||||
o = s:option(Flag, _n("ech"), translate("ECH"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
|
||||
o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false })
|
||||
|
||||
o = s:option(TextValue, _n("ech_config"), translate("ECH Config"))
|
||||
o.default = ""
|
||||
o.rows = 5
|
||||
@@ -706,7 +738,7 @@ o:depends({ [_n("protocol")] = "vless" })
|
||||
o:depends({ [_n("protocol")] = "trojan" })
|
||||
o:depends({ [_n("protocol")] = "shadowsocks" })
|
||||
o:depends({ [_n("protocol")] = "wireguard" })
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false })
|
||||
|
||||
o = s:option(TextValue, _n("finalmask"), " ")
|
||||
o:depends({ [_n("use_finalmask")] = true })
|
||||
@@ -775,10 +807,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)
|
||||
|
||||
if v ~= "hysteria2" then
|
||||
s.fields[_n("tcp_fast_open")]:depends({ [_n("protocol")] = v })
|
||||
@@ -801,7 +837,7 @@ if not load_shunt_options then
|
||||
o:value("2", translate("Landing Node"))
|
||||
|
||||
o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
|
||||
o1:depends({ [_n("chain_proxy")] = "1" })
|
||||
o1:depends({ [_n("chain_proxy")] = "1", [_n("hysteria2_realms")] = false })
|
||||
o1.template = appname .. "/cbi/nodes_listvalue"
|
||||
o1.group = {}
|
||||
|
||||
@@ -813,7 +849,7 @@ if not load_shunt_options then
|
||||
end
|
||||
|
||||
o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
|
||||
o2:depends({ [_n("chain_proxy")] = "2" })
|
||||
o2:depends({ [_n("chain_proxy")] = "2", [_n("hysteria2_realms")] = false })
|
||||
o2.template = appname .. "/cbi/nodes_listvalue"
|
||||
o2.group = {}
|
||||
|
||||
|
||||
@@ -423,10 +423,12 @@ if singbox_tags:find("with_quic") then
|
||||
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value("salamander")
|
||||
o:value("gecko")
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
|
||||
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
|
||||
o:depends({ [_n("hysteria2_obfs_type")] = "gecko" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
@@ -531,6 +533,24 @@ o:depends({ [_n("protocol")] = "hysteria"})
|
||||
o:depends({ [_n("protocol")] = "tuic" })
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Flag, _n("tls_certificate"), translate("TLS Certificate (PEM)"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
|
||||
o:depends({ [_n("protocol")] = "hysteria"})
|
||||
o:depends({ [_n("protocol")] = "tuic" })
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
o:depends({ [_n("protocol")] = "naive" })
|
||||
|
||||
o = s:option(TextValue, _n("tls_certificate_pem"), " ", translate("Full certificate (chain), PEM format."))
|
||||
o.default = ""
|
||||
o.rows = 5
|
||||
o.wrap = "off"
|
||||
o:depends({ [_n("tls_certificate")] = true })
|
||||
o.validate = function(self, value)
|
||||
value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
|
||||
return value
|
||||
end
|
||||
|
||||
o = s:option(Flag, _n("ech"), translate("ECH"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
|
||||
|
||||
@@ -48,12 +48,14 @@ o:depends({ [_n("custom")] = false })
|
||||
o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value("salamander")
|
||||
o:value("gecko")
|
||||
o.rewrite_option = o.option
|
||||
o:depends({ [_n("custom")] = false })
|
||||
|
||||
o = s:option(Value, _n("obfs_password"), translate("Obfs Password"))
|
||||
o.rewrite_option = o.option
|
||||
o:depends({ [_n("obfs_type")] = "salamander" })
|
||||
o:depends({ [_n("obfs_type")] = "gecko" })
|
||||
|
||||
o = s:option(Flag, _n("udp"), translate("UDP"))
|
||||
o.default = "1"
|
||||
|
||||
@@ -127,6 +127,17 @@ o:value("xtls-rprx-vision")
|
||||
o:depends({ [_n("protocol")] = "vless" })
|
||||
|
||||
---- [[ hysteria2 ]]
|
||||
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"})
|
||||
@@ -134,10 +145,12 @@ o:depends({ [_n("protocol")] = "hysteria2"})
|
||||
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value("salamander")
|
||||
o:value("gecko")
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
|
||||
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
|
||||
o:depends({ [_n("hysteria2_obfs_type")] = "gecko" })
|
||||
|
||||
o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control"))
|
||||
o.default = 0
|
||||
@@ -210,7 +223,8 @@ function o.write(self, section, value)
|
||||
end
|
||||
|
||||
o = s:option(ListValue, _n("alpn"), translate("alpn"))
|
||||
o.default = "h2,http/1.1"
|
||||
o.default = "default"
|
||||
o:value("default", translate("Default"))
|
||||
o:value("h3")
|
||||
o:value("h2")
|
||||
o:value("h3,h2")
|
||||
@@ -378,7 +392,7 @@ o:depends({ [_n("custom")] = false, [_n("protocol")] = "vless" })
|
||||
o:depends({ [_n("custom")] = false, [_n("protocol")] = "trojan" })
|
||||
o:depends({ [_n("custom")] = false, [_n("protocol")] = "shadowsocks" })
|
||||
o:depends({ [_n("custom")] = false, [_n("protocol")] = "wireguard" })
|
||||
o:depends({ [_n("custom")] = false, [_n("protocol")] = "hysteria2" })
|
||||
o:depends({ [_n("custom")] = false, [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false })
|
||||
|
||||
o = s:option(TextValue, _n("finalmask"), "FinalMask JSON")
|
||||
o:depends({ [_n("use_finalmask")] = true })
|
||||
|
||||
@@ -175,10 +175,12 @@ if singbox_tags:find("with_quic") then
|
||||
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value("salamander")
|
||||
o:value("gecko")
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
|
||||
o:depends({ [_n("hysteria2_obfs_type")] = "salamander" })
|
||||
o:depends({ [_n("hysteria2_obfs_type")] = "gecko" })
|
||||
|
||||
o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control"), translate("Commands the client to use the BBR flow control algorithm"))
|
||||
o.default = 0
|
||||
|
||||
@@ -154,12 +154,14 @@ function base64Encode(text)
|
||||
end
|
||||
|
||||
function UrlEncode(szText)
|
||||
if type(szText) ~= "string" then return "" end
|
||||
return szText:gsub("([^%w%-_%.%~])", function(c)
|
||||
return string.format("%%%02X", string.byte(c))
|
||||
end)
|
||||
end
|
||||
|
||||
function UrlDecode(szText)
|
||||
if type(szText) ~= "string" then return "" end
|
||||
return szText and szText:gsub("%+", " "):gsub("%%(%x%x)", function(h)
|
||||
return string.char(tonumber(h, 16))
|
||||
end) or nil
|
||||
|
||||
@@ -20,8 +20,8 @@ function gen_config_server(node)
|
||||
key = node.tls_keyFile,
|
||||
},
|
||||
obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and {
|
||||
type = "salamander",
|
||||
salamander = {
|
||||
type = node.hysteria2_obfs_type,
|
||||
[node.hysteria2_obfs_type] = {
|
||||
password = node.hysteria2_obfs_password
|
||||
}
|
||||
} or nil,
|
||||
@@ -101,8 +101,8 @@ function gen_config(var)
|
||||
end)() or nil
|
||||
},
|
||||
obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and {
|
||||
type = "salamander",
|
||||
salamander = {
|
||||
type = node.hysteria2_obfs_type,
|
||||
[node.hysteria2_obfs_type] = {
|
||||
password = node.hysteria2_obfs_password
|
||||
}
|
||||
} or nil,
|
||||
|
||||
@@ -255,6 +255,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
--max_version = "1.3",
|
||||
fragment = fragment,
|
||||
record_fragment = record_fragment,
|
||||
certificate = (node.tls_certificate == "1" and node.tls_certificate_pem ~= "") and split(node.tls_certificate_pem, "\n") or nil,
|
||||
ech = (node.ech == "1") and (function()
|
||||
local function get_ech_domain(s) --兼容xray "域名+DNS" 格式ech
|
||||
local domain, dns = s:match("^([^+]+)%+(.+)$")
|
||||
|
||||
@@ -73,8 +73,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 or nil
|
||||
noise = proxy_table.noise or nil
|
||||
fragment = (proxy_table.fragment and not node.hysteria2_realms) and true or nil
|
||||
noise = (proxy_table.noise and not node.hysteria2_realms) and true or nil
|
||||
run_socks_instance = proxy_table.run_socks_instance
|
||||
end
|
||||
|
||||
@@ -189,7 +189,11 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
if not node.tls_CertByName then return "" end
|
||||
return node.tls_CertByName
|
||||
end)(),
|
||||
echConfigList = (node.ech == "1") and node.ech_config or nil
|
||||
echConfigList = (node.ech == "1") and node.ech_config or nil,
|
||||
certificates = (node.tls_certificate == "1" and node.tls_certificate_pem ~= "") and {
|
||||
certificate = api.split(node.tls_certificate_pem, "\n"),
|
||||
usage = "verify"
|
||||
} or nil
|
||||
} or nil,
|
||||
realitySettings = (node.stream_security == "reality") and {
|
||||
serverName = node.tls_serverName,
|
||||
@@ -298,14 +302,36 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
udp[#udp+1] = c
|
||||
finalmask.udp = udp
|
||||
elseif TP == "hysteria" then
|
||||
local udp = {}
|
||||
if node.hysteria2_obfs_type and node.hysteria2_obfs_type ~= "" then
|
||||
finalmask.udp = {{
|
||||
type = node.hysteria2_obfs_type,
|
||||
local o = {
|
||||
type = "salamander",
|
||||
settings = node.hysteria2_obfs_password and {
|
||||
password = node.hysteria2_obfs_password
|
||||
password = node.hysteria2_obfs_password,
|
||||
packetSize = node.hysteria2_obfs_type == "gecko" and "512-1200" or nil
|
||||
} or nil
|
||||
}}
|
||||
}
|
||||
udp[#udp+1] = o
|
||||
end
|
||||
if node.hysteria2_realms then
|
||||
local realm = api.parse_realm_uri(node.hysteria2_realm_url)
|
||||
local url, stun
|
||||
if realm then
|
||||
if realm.token and realm.server_url and realm.realm_id then
|
||||
url = "realm://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id
|
||||
end
|
||||
stun = realm.stun_servers or node.hysteria2_realm_stun
|
||||
end
|
||||
local r = {
|
||||
type = "realm",
|
||||
settings = {
|
||||
url = url,
|
||||
stunServers = stun
|
||||
}
|
||||
}
|
||||
udp[#udp+1] = r
|
||||
end
|
||||
finalmask.udp = udp
|
||||
local up = tonumber(node.hysteria2_up_mbps) or 0
|
||||
local down = tonumber(node.hysteria2_down_mbps) or 0
|
||||
finalmask.quicParams = {
|
||||
@@ -415,6 +441,13 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
|
||||
if node.protocol == "wireguard" then
|
||||
result.settings.kernelMode = false
|
||||
if node.finalmask and node.finalmask ~= "" then
|
||||
local ok, fm = pcall(jsonc.parse, api.base64Decode(node.finalmask))
|
||||
if ok and type(fm) == "table" then
|
||||
result.streamSettings = result.streamSettings or {}
|
||||
result.streamSettings.finalmask = fm
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local alpn = {}
|
||||
@@ -487,9 +520,9 @@ function gen_config_server(node)
|
||||
|
||||
if node.protocol == "vmess" or node.protocol == "vless" then
|
||||
if node.uuid then
|
||||
local clients = {}
|
||||
local users = {}
|
||||
for i = 1, #node.uuid do
|
||||
clients[i] = {
|
||||
users[i] = {
|
||||
id = node.uuid[i],
|
||||
flow = (node.protocol == "vless"
|
||||
and (node.tls == "1" or (node.decryption and node.decryption ~= "" and node.decryption ~= "none"))
|
||||
@@ -497,7 +530,7 @@ function gen_config_server(node)
|
||||
}
|
||||
end
|
||||
settings = {
|
||||
clients = clients,
|
||||
users = users,
|
||||
decryption = (node.protocol == "vless") and ((node.decryption and node.decryption ~= "") and node.decryption or "none") or nil
|
||||
}
|
||||
end
|
||||
@@ -505,7 +538,7 @@ function gen_config_server(node)
|
||||
settings = {
|
||||
udp = ("1" == node.udp_forward) and true or false,
|
||||
auth = ("1" == node.auth) and "password" or "noauth",
|
||||
accounts = ("1" == node.auth) and {
|
||||
users = ("1" == node.auth) and {
|
||||
{
|
||||
user = node.username,
|
||||
pass = node.password
|
||||
@@ -515,7 +548,7 @@ function gen_config_server(node)
|
||||
elseif node.protocol == "http" then
|
||||
settings = {
|
||||
allowTransparent = false,
|
||||
accounts = ("1" == node.auth) and {
|
||||
users = ("1" == node.auth) and {
|
||||
{
|
||||
user = node.username,
|
||||
pass = node.password
|
||||
@@ -533,20 +566,20 @@ function gen_config_server(node)
|
||||
}
|
||||
elseif node.protocol == "trojan" then
|
||||
if node.uuid then
|
||||
local clients = {}
|
||||
local users = {}
|
||||
for i = 1, #node.uuid do
|
||||
clients[i] = {
|
||||
password = node.uuid[i]
|
||||
users[i] = {
|
||||
password = node.uuid[i],
|
||||
}
|
||||
end
|
||||
settings = {
|
||||
clients = clients
|
||||
users = users
|
||||
}
|
||||
end
|
||||
elseif node.protocol == "hysteria2" then
|
||||
settings = {
|
||||
version = 2,
|
||||
clients = node.hysteria2_auth_password and {
|
||||
users = node.hysteria2_auth_password and {
|
||||
{ auth = node.hysteria2_auth_password }
|
||||
}
|
||||
}
|
||||
@@ -724,14 +757,36 @@ function gen_config_server(node)
|
||||
udp[#udp+1] = c
|
||||
finalmask.udp = udp
|
||||
elseif node.transport == "hysteria" then
|
||||
local udp = {}
|
||||
if node.hysteria2_obfs_type and node.hysteria2_obfs_type ~= "" then
|
||||
finalmask.udp = {{
|
||||
type = node.hysteria2_obfs_type,
|
||||
local o = {
|
||||
type = "salamander",
|
||||
settings = node.hysteria2_obfs_password and {
|
||||
password = node.hysteria2_obfs_password
|
||||
password = node.hysteria2_obfs_password,
|
||||
packetSize = node.hysteria2_obfs_type == "gecko" and "512-1200" or nil
|
||||
} or nil
|
||||
}}
|
||||
}
|
||||
udp[#udp+1] = o
|
||||
end
|
||||
if node.hysteria2_realms then
|
||||
local realm = api.parse_realm_uri(node.hysteria2_realm_url)
|
||||
local url, stun
|
||||
if realm then
|
||||
if realm.token and realm.server_url and realm.realm_id then
|
||||
url = "realm://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id
|
||||
end
|
||||
stun = realm.stun_servers or node.hysteria2_realm_stun
|
||||
end
|
||||
local r = {
|
||||
type = "realm",
|
||||
settings = {
|
||||
url = url,
|
||||
stunServers = stun
|
||||
}
|
||||
}
|
||||
udp[#udp+1] = r
|
||||
end
|
||||
finalmask.udp = udp
|
||||
local ignore = tonumber(node.hysteria2_ignore_client_bandwidth) == 1
|
||||
local up = (not ignore) and tonumber(node.hysteria2_up_mbps) or 0
|
||||
local down = (not ignore) and tonumber(node.hysteria2_down_mbps) or 0
|
||||
@@ -761,7 +816,7 @@ function gen_config_server(node)
|
||||
}
|
||||
|
||||
local alpn = {}
|
||||
if node.alpn then
|
||||
if node.alpn and node.alpn ~= "default" then
|
||||
string.gsub(node.alpn, '[^' .. "," .. ']+', function(w)
|
||||
table.insert(alpn, w)
|
||||
end)
|
||||
@@ -907,7 +962,7 @@ function gen_config(var)
|
||||
end
|
||||
if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then
|
||||
inbound.settings.auth = "password"
|
||||
inbound.settings.accounts = {
|
||||
inbound.settings.users = {
|
||||
{
|
||||
user = local_socks_username,
|
||||
pass = local_socks_password
|
||||
@@ -925,7 +980,7 @@ function gen_config(var)
|
||||
settings = {allowTransparent = false}
|
||||
}
|
||||
if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then
|
||||
inbound.settings.accounts = {
|
||||
inbound.settings.users = {
|
||||
{
|
||||
user = local_http_username,
|
||||
pass = local_http_password
|
||||
@@ -2047,7 +2102,7 @@ function gen_proto_config(var)
|
||||
}
|
||||
if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then
|
||||
inbound.settings.auth = "password"
|
||||
inbound.settings.accounts = {
|
||||
inbound.settings.users = {
|
||||
{
|
||||
user = local_socks_username,
|
||||
pass = local_socks_password
|
||||
@@ -2067,7 +2122,7 @@ function gen_proto_config(var)
|
||||
}
|
||||
}
|
||||
if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then
|
||||
inbound.settings.accounts = {
|
||||
inbound.settings.users = {
|
||||
{
|
||||
user = local_http_username,
|
||||
pass = local_http_password
|
||||
|
||||
@@ -150,12 +150,9 @@ local api = require "luci.passwall2.api"
|
||||
if (confirm("<%: Do you want to restore the client to default settings?%>")) {
|
||||
setTimeout(function () {
|
||||
if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) {
|
||||
var xhr1 = new XMLHttpRequest();
|
||||
xhr1.open("GET",'<%= api.url("clear_log") %>', false);
|
||||
xhr1.send();
|
||||
var xhr2 = new XMLHttpRequest();
|
||||
xhr2.open("GET",'<%= api.url("reset_config") %>', false);
|
||||
xhr2.send();
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("GET",'<%= api.url("reset_config") %>', false);
|
||||
xhr.send();
|
||||
window.location.href = '<%= api.url("log") %>'
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
@@ -600,7 +600,7 @@ local current_node = map:get(section)
|
||||
v_password = opt.get("hysteria2_auth_password");
|
||||
var dom_obfs = opt.get("hysteria2_obfs_password");
|
||||
if (dom_obfs && dom_obfs.value != "") {
|
||||
params += "&obfs=" + "salamander";
|
||||
params += opt.query("obfs", "hysteria2_obfs_type");
|
||||
params += opt.query("obfs-password", "hysteria2_obfs_password");
|
||||
}
|
||||
params += opt.query("mport", "hysteria2_hop");
|
||||
@@ -1598,7 +1598,7 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'protocol', "hysteria2");
|
||||
opt.set(dom_prefix + 'hysteria2_auth_password', decodeURIComponent(password));
|
||||
if (queryParam["obfs-password"] || queryParam["obfs_password"]) {
|
||||
opt.set(dom_prefix + 'hysteria2_obfs_type', "salamander");
|
||||
opt.set(dom_prefix + 'hysteria2_obfs_type', queryParam.obfs || "salamander");
|
||||
opt.set(dom_prefix + 'hysteria2_obfs_password', queryParam["obfs-password"] || queryParam["obfs_password"]);
|
||||
}
|
||||
opt.set(dom_prefix + 'hysteria2_hop', queryParam.mport || "");
|
||||
@@ -1609,7 +1609,7 @@ local current_node = map:get(section)
|
||||
dom_prefix = "hysteria2_"
|
||||
opt.set(dom_prefix + 'auth_password', decodeURIComponent(password));
|
||||
if (queryParam["obfs-password"] || queryParam["obfs_password"]) {
|
||||
opt.set(dom_prefix + 'obfs_type', "salamander");
|
||||
opt.set(dom_prefix + 'obfs_type', queryParam.obfs || "salamander");
|
||||
opt.set(dom_prefix + 'obfs_password', queryParam["obfs-password"] || queryParam["obfs_password"]);
|
||||
}
|
||||
opt.set(dom_prefix + 'hop', queryParam.mport || "");
|
||||
|
||||
@@ -1656,6 +1656,12 @@ msgstr "نام گواهی TLS (CertName)"
|
||||
msgid "TLS is used to verify the leaf certificate name."
|
||||
msgstr "TLS برای تأیید نام گواهی برگ (Leaf Certificate) استفاده میشود."
|
||||
|
||||
msgid "TLS Certificate (PEM)"
|
||||
msgstr "گواهی TLS (PEM)"
|
||||
|
||||
msgid "Full certificate (chain), PEM format."
|
||||
msgstr "گواهی کامل (زنجیرهای)، فرمت PEM."
|
||||
|
||||
msgid "ECH Config"
|
||||
msgstr "پیکربندی ECH"
|
||||
|
||||
@@ -2281,8 +2287,8 @@ msgstr "نادیده گرفتن گره %s به دلیل ناسازگاری با
|
||||
msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead."
|
||||
msgstr "صرفنظر از گره: %s. زیرا Sing-Box از روش انتقال %s پروتکل %s پشتیبانی نمیکند، باید به جای آن از Xray استفاده شود."
|
||||
|
||||
msgid "Xray unsupport %s plugin."
|
||||
msgstr "Xray از افزونه %s پشتیبانی نمیکند."
|
||||
msgid "%s unsupport SS %s plugin."
|
||||
msgstr "%s از افزونه %s پشتیبانی نمیکند."
|
||||
|
||||
msgid "Plugin options Incomplete."
|
||||
msgstr "گزینههای افزونه ناقص است."
|
||||
|
||||
@@ -1657,6 +1657,12 @@ msgstr "Имя TLS-сертификата (CertName)"
|
||||
msgid "TLS is used to verify the leaf certificate name."
|
||||
msgstr "Используется TLS для проверки имени конечного сертификата."
|
||||
|
||||
msgid "TLS Certificate (PEM)"
|
||||
msgstr "Сертификат TLS (PEM)"
|
||||
|
||||
msgid "Full certificate (chain), PEM format."
|
||||
msgstr "Полный сертификат (цепочка), формат PEM."
|
||||
|
||||
msgid "ECH Config"
|
||||
msgstr "Конфигурация ECH"
|
||||
|
||||
@@ -2279,8 +2285,8 @@ msgstr "Пропуск сервера %s: несовместимость с яд
|
||||
msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead."
|
||||
msgstr "Пропуск сервера: %s. Sing-Box не поддерживает метод передачи %s протокола %s, необходимо использовать Xray."
|
||||
|
||||
msgid "Xray unsupport %s plugin."
|
||||
msgstr "Xray не поддерживает плагин %s."
|
||||
msgid "%s unsupport SS %s plugin."
|
||||
msgstr "%s не поддерживает плагин %s."
|
||||
|
||||
msgid "Plugin options Incomplete."
|
||||
msgstr "Опции плагина указаны не полностью."
|
||||
|
||||
@@ -1648,6 +1648,12 @@ msgstr "TLS 证书名称(CertName)"
|
||||
msgid "TLS is used to verify the leaf certificate name."
|
||||
msgstr "TLS 用于验证 leaf 证书的 name。"
|
||||
|
||||
msgid "TLS Certificate (PEM)"
|
||||
msgstr "TLS 证书(PEM)"
|
||||
|
||||
msgid "Full certificate (chain), PEM format."
|
||||
msgstr "完整证书(链),PEM 格式。"
|
||||
|
||||
msgid "ECH Config"
|
||||
msgstr "ECH 配置"
|
||||
|
||||
@@ -2267,8 +2273,8 @@ msgstr "跳过 %s 节点,因未适配到 %s 核心程序,或未正确设置
|
||||
msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead."
|
||||
msgstr "跳过节点:%s,因 Sing-Box 不支持 %s 协议的 %s 传输方式,需更换 Xray。"
|
||||
|
||||
msgid "Xray unsupport %s plugin."
|
||||
msgstr "Xray 不支持 %s 插件。"
|
||||
msgid "%s unsupport SS %s plugin."
|
||||
msgstr "%s 不支持 %s 插件。"
|
||||
|
||||
msgid "Plugin options Incomplete."
|
||||
msgstr "插件选项不完整。"
|
||||
|
||||
@@ -1648,6 +1648,12 @@ msgstr "TLS 憑證名稱(CertName)"
|
||||
msgid "TLS is used to verify the leaf certificate name."
|
||||
msgstr "TLS 用於驗證 leaf 憑證的 name。"
|
||||
|
||||
msgid "TLS Certificate (PEM)"
|
||||
msgstr "TLS 憑證(PEM)"
|
||||
|
||||
msgid "Full certificate (chain), PEM format."
|
||||
msgstr "完整憑證(鏈),PEM 格式。"
|
||||
|
||||
msgid "ECH Config"
|
||||
msgstr "ECH 配置"
|
||||
|
||||
@@ -2273,8 +2279,8 @@ msgstr "跳過 %s 節點,因未適配到 %s 核心程序,或未正確設置
|
||||
msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead."
|
||||
msgstr "跳過節點:%s,因 Sing-Box 不支持 %s 協議的 %s 傳輸方式,需更換 Xray。"
|
||||
|
||||
msgid "Xray unsupport %s plugin."
|
||||
msgstr "Xray 不支持 %s 插件。"
|
||||
msgid "%s unsupport SS %s plugin."
|
||||
msgstr "%s 不支持 %s 插件。"
|
||||
|
||||
msgid "Plugin options Incomplete."
|
||||
msgstr "插件選項不完整。"
|
||||
|
||||
@@ -1012,9 +1012,10 @@ acl_app() {
|
||||
[ -n "$items" ] && {
|
||||
local index=0
|
||||
local item
|
||||
local redir_port dns_port dnsmasq_port
|
||||
local redir_port dns_port dnsmasq_port socks_port
|
||||
local ipt_tmp msg msg2
|
||||
redir_port=11200
|
||||
socks_port=11600
|
||||
dns_port=11300
|
||||
dnsmasq_port=${GLOBAL_DNSMASQ_PORT:-11400}
|
||||
for item in $items; do
|
||||
@@ -1098,12 +1099,13 @@ acl_app() {
|
||||
set_cache_var "ACL_${sid}_default" "1"
|
||||
else
|
||||
redir_port=$(get_new_port $(expr $redir_port + 1))
|
||||
socks_port=$(get_new_port $(expr $socks_port + 1))
|
||||
|
||||
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
if [ -n "${type}" ]; then
|
||||
config_file=$TMP_ACL_PATH/${node}_TCP_UDP_DNS_${redir_port}.json
|
||||
dns_port=$(get_new_port $(expr $dns_port + 1))
|
||||
local acl_socks_port=$(get_new_port $(expr $redir_port + $index))
|
||||
local acl_socks_port=$socks_port
|
||||
local run_func
|
||||
[ -n "${XRAY_BIN}" ] && run_func="run_xray"
|
||||
[ -n "${SINGBOX_BIN}" ] && run_func="run_singbox"
|
||||
|
||||
@@ -528,36 +528,50 @@ local function parseClashNode(node, add_mode, group, sub_cfg)
|
||||
elseif node.plugin == "v2ray-plugin" then
|
||||
result.plugin = "v2ray-plugin"
|
||||
end
|
||||
if node["plugin-opts"] then
|
||||
if node.plugin == "obfs" then
|
||||
local plugin_opts = ""
|
||||
local opts_mode = node["plugin-opts"].mode
|
||||
if opts_mode then
|
||||
plugin_opts = plugin_opts .. "obfs=" .. opts_mode .. ";"
|
||||
if result.plugin then
|
||||
result.plugin_enabled = "1"
|
||||
if result.type == 'Xray' then
|
||||
if result.plugin ~= "obfs-local" then
|
||||
result.plugin_enabled = nil
|
||||
result.error_msg = i18n.translatef("%s unsupport SS %s plugin.", "Xray", result.plugin)
|
||||
end
|
||||
local opts_host = node["plugin-opts"].host
|
||||
if opts_host then
|
||||
plugin_opts = plugin_opts .. "obfs-host=" .. opts_host
|
||||
elseif result.type == 'sing-box' then
|
||||
if result.plugin ~= "obfs-local" and result.plugin ~= "v2ray-plugin" then
|
||||
result.plugin_enabled = nil
|
||||
result.error_msg = i18n.translatef("%s unsupport SS %s plugin.", "Sing-Box", result.plugin)
|
||||
end
|
||||
result.plugin_opts = plugin_opts
|
||||
elseif node.plugin == "v2ray-plugin" then
|
||||
local plugin_opts = ""
|
||||
local opts_mode = node["plugin-opts"].mode
|
||||
local opts_tls = node["plugin-opts"].tls
|
||||
if opts_tls then
|
||||
plugin_opts = plugin_opts .. "tls;"
|
||||
end
|
||||
if node["plugin-opts"] and result.plugin_enabled == "1" then
|
||||
if node.plugin == "obfs" then
|
||||
local plugin_opts = ""
|
||||
local opts_mode = node["plugin-opts"].mode
|
||||
if opts_mode then
|
||||
plugin_opts = plugin_opts .. "obfs=" .. opts_mode .. ";"
|
||||
end
|
||||
local opts_host = node["plugin-opts"].host
|
||||
if opts_host then
|
||||
plugin_opts = plugin_opts .. "obfs-host=" .. opts_host
|
||||
end
|
||||
result.plugin_opts = plugin_opts
|
||||
elseif node.plugin == "v2ray-plugin" then
|
||||
local plugin_opts = ""
|
||||
local opts_mode = node["plugin-opts"].mode
|
||||
local opts_tls = node["plugin-opts"].tls
|
||||
if opts_tls then
|
||||
plugin_opts = plugin_opts .. "tls;"
|
||||
end
|
||||
local opts_skip_cert_verify = node["plugin-opts"]["skip-cert-verify"]
|
||||
local opts_host = node["plugin-opts"].host
|
||||
if opts_host then
|
||||
plugin_opts = plugin_opts .. "host=" .. opts_host .. ";"
|
||||
end
|
||||
local opts_path = node["plugin-opts"].path
|
||||
local opts_mux = node["plugin-opts"].mux
|
||||
if node["plugin-opts"].headers then
|
||||
--todo
|
||||
end
|
||||
result.plugin_opts = plugin_opts
|
||||
end
|
||||
local opts_skip_cert_verify = node["plugin-opts"]["skip-cert-verify"]
|
||||
local opts_host = node["plugin-opts"].host
|
||||
if opts_host then
|
||||
plugin_opts = plugin_opts .. "host=" .. opts_host .. ";"
|
||||
end
|
||||
local opts_path = node["plugin-opts"].path
|
||||
local opts_mux = node["plugin-opts"].mux
|
||||
if node["plugin-opts"].headers then
|
||||
--todo
|
||||
end
|
||||
result.plugin_opts = plugin_opts
|
||||
end
|
||||
end
|
||||
elseif node.type == 'ssr' then
|
||||
@@ -961,6 +975,11 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.tls = "0"
|
||||
end
|
||||
|
||||
if info.ech and info.ech ~= "" then
|
||||
result.ech = "1"
|
||||
result.ech_config = info.ech
|
||||
end
|
||||
|
||||
result.tcp_fast_open = info.tfo
|
||||
|
||||
info.fm = (info.fm and info.fm ~= "") and UrlDecode(info.fm) or nil
|
||||
@@ -1090,7 +1109,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
if result.type == 'Xray' then
|
||||
-- The obfs-local plugin converts data to a format supported by xray.
|
||||
if result.plugin ~= "obfs-local" then
|
||||
result.error_msg = i18n.translatef("Xray unsupport %s plugin.", result.plugin)
|
||||
result.error_msg = i18n.translatef("%s unsupport SS %s plugin.", "Xray", result.plugin)
|
||||
else
|
||||
local obfs = result.plugin_opts:match("obfs=([^;]+)") or ""
|
||||
local obfs_host = result.plugin_opts:match("obfs%-host=([^;]+)") or ""
|
||||
@@ -1110,6 +1129,12 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.plugin = nil
|
||||
result.plugin_opts = nil
|
||||
end
|
||||
elseif result.type == 'sing-box' then
|
||||
if result.plugin ~= "obfs-local" and result.plugin ~= "v2ray-plugin" then
|
||||
result.error_msg = i18n.translatef("%s unsupport SS %s plugin.", "Sing-Box", result.plugin)
|
||||
else
|
||||
result.plugin_enabled = "1"
|
||||
end
|
||||
else
|
||||
result.plugin_enabled = "1"
|
||||
end
|
||||
@@ -1223,7 +1248,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
local insecure = params.allowinsecure or params.allowInsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
result.uot = params.udp
|
||||
elseif (params.type ~= "tcp" and params.type ~= "raw") and (params.headerType and params.headerType ~= "none") then
|
||||
else
|
||||
result.error_msg = i18n.translatef("Please replace Xray or Sing-Box to support more transmission methods in Shadowsocks.")
|
||||
end
|
||||
end
|
||||
@@ -1684,7 +1709,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.hysteria2_down_mbps = params.downmbps or sub_hy_down_mbps
|
||||
result.hysteria2_hop = params.mport
|
||||
if params["obfs-password"] or params["obfs_password"] then
|
||||
result.hysteria2_obfs_type = "salamander"
|
||||
result.hysteria2_obfs_type = params.obfs or "salamander"
|
||||
result.hysteria2_obfs_password = params["obfs-password"] or params["obfs_password"]
|
||||
end
|
||||
|
||||
@@ -1818,6 +1843,10 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.reality_publicKey = params.pbk or nil
|
||||
result.reality_shortId = params.sid or nil
|
||||
end
|
||||
if params.ech and params.ech ~= "" then
|
||||
result.ech = "1"
|
||||
result.ech_config = params.ech
|
||||
end
|
||||
end
|
||||
result.port = port
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
|
||||
Reference in new issue
Block a user