update 2026-09-19 23:12:35

This commit is contained in:
action committed 2026-09-19 23:12:35 +08:00
1 parent 61c1fb2c04
commit 4e782452f1
8 files changed
+144 -38

No files matched your search

@@ -564,9 +564,12 @@ o.default = ""
o.rows = 5
o.wrap = "off"
o:depends({ tls_certificate = true })
o.cfgvalue = function(self, section)
return (m:get(section, "tls_certificate_pem") or ""):gsub("\\n", "\n")
end
o.validate = function(self, value)
value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value
value = api.trim(value):gsub("\r\n", "\n"):gsub("\r", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value:gsub("\n", "\\n")
end
o = s:option(Value, "cipherSuites", translate("Cipher Suites"), '<a href="https://go.dev/src/crypto/tls/cipher_suites.go#L44" target="_blank">***</a>' .. " " .. translate("Configures the list of supported cipher suites, separated by :"))
@@ -585,9 +588,12 @@ o.default = ""
o.rows = 5
o.wrap = "off"
o:depends({ ech = true })
o.cfgvalue = function(self, section)
return (m:get(section, "ech_config") or ""):gsub("\\n", "\n")
end
o.validate = function(self, value)
value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value
value = api.trim(value):gsub("\r\n", "\n"):gsub("\r", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value:gsub("\n", "\\n")
end
o = s:option(Value, "ech_query_server_name", translate("ECH Query Domain"), translate("Overrides the domain name used for ECH HTTPS record queries."))
@@ -453,9 +453,12 @@ o.default = ""
o.rows = 5
o.wrap = "off"
o:depends({ tls_certificate = true })
o.cfgvalue = function(self, section)
return (m:get(section, "tls_certificate_pem") or ""):gsub("\\n", "\n")
end
o.validate = function(self, value)
value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value
value = api.trim(value):gsub("\r\n", "\n"):gsub("\r", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value:gsub("\n", "\\n")
end
o = s:option(Flag, "ech", translate("ECH"))
@@ -253,12 +253,19 @@ o.default = 0
o.validate = function(self, value, t)
if value then
local reality = s.fields["reality"] and s.fields["reality"]:formvalue(t) or nil
local use_pem = s.fields["tls_use_pem"] and s.fields["tls_use_pem"]:formvalue(t) or nil
if reality and reality == "1" then return value end
if value == "1" then
if value == "1" and use_pem ~= "1" then
local ca = s.fields["tls_certificateFile"] and s.fields["tls_certificateFile"]:formvalue(t) or ""
local key = s.fields["tls_keyFile"] and s.fields["tls_keyFile"]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Certificate or Private key path can not be empty!")
return nil, translate("Certificate and Private key path can not be empty!")
end
elseif value == "1" and use_pem == "1" then
local ca = s.fields["tls_certificate"] and s.fields["tls_certificate"]:formvalue(t) or ""
local key = s.fields["tls_key"] and s.fields["tls_key"]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Certificate and Private key PEM can not be empty!")
end
end
return value
@@ -311,14 +318,21 @@ o:depends({ protocol = "hysteria" })
-- [[ TLS部分 ]] --
o = s:option(FileUpload, "tls_certificateFile", translate("Path to the certificate file"), translate("as:") .. "/etc/ssl/fullchain.crt")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".crt"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o = s:option(Flag, "tls_use_pem", translate("Use PEM"), translate("Use certificate and private key PEM content."))
o:depends({ tls = true, reality = false })
o:depends({ protocol = "naive" })
o:depends({ protocol = "hysteria" })
o:depends({ protocol = "tuic" })
o:depends({ protocol = "hysteria2" })
o = s:option(FileUpload, "tls_certificateFile", translate("Path to the certificate file"), translate("as:") .. "/etc/ssl/fullchain.crt")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".crt"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o:depends({ tls = true, reality = false, tls_use_pem = false })
o:depends({ protocol = "naive", tls_use_pem = false })
o:depends({ protocol = "hysteria", tls_use_pem = false })
o:depends({ protocol = "tuic", tls_use_pem = false })
o:depends({ protocol = "hysteria2", tls_use_pem = false })
o.validate = function(self, value, t)
if value and value ~= "" then
if not api.fs.access(value) then
@@ -333,11 +347,11 @@ end
o = s:option(FileUpload, "tls_keyFile", translate("Path to the private key file"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o:depends({ tls = true, reality = false })
o:depends({ protocol = "naive" })
o:depends({ protocol = "hysteria" })
o:depends({ protocol = "tuic" })
o:depends({ protocol = "hysteria2" })
o:depends({ tls = true, reality = false, tls_use_pem = false })
o:depends({ protocol = "naive", tls_use_pem = false })
o:depends({ protocol = "hysteria", tls_use_pem = false })
o:depends({ protocol = "tuic", tls_use_pem = false })
o:depends({ protocol = "hysteria2", tls_use_pem = false })
o.validate = function(self, value, t)
if value and value ~= "" then
if not api.fs.access(value) then
@@ -349,6 +363,32 @@ o.validate = function(self, value, t)
return nil
end
o = s:option(TextValue, "tls_certificate", "TLS Certificate (PEM)", translate("Full certificate (chain), PEM format."))
o.default = ""
o.rows = 5
o.wrap = "off"
o:depends({ tls_use_pem = true })
o.cfgvalue = function(self, section)
return (m:get(section, "tls_certificate") or ""):gsub("\\n", "\n")
end
o.validate = function(self, value)
value = api.trim(value):gsub("\r\n", "\n"):gsub("\r", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value:gsub("\n", "\\n")
end
o = s:option(TextValue, "tls_key", "TLS Private Key (PEM)", translate("Private key in PEM format."))
o.default = ""
o.rows = 5
o.wrap = "off"
o:depends({ tls_use_pem = true })
o.cfgvalue = function(self, section)
return (m:get(section, "tls_key") or ""):gsub("\\n", "\n")
end
o.validate = function(self, value)
value = api.trim(value):gsub("\r\n", "\n"):gsub("\r", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value:gsub("\n", "\\n")
end
o = s:option(Flag, "ech", translate("ECH"))
o.default = "0"
o:depends({ tls = true, flow = "", reality = false })
@@ -362,13 +402,12 @@ o.default = ""
o.rows = 5
o.wrap = "off"
o:depends({ ech = true })
o.cfgvalue = function(self, section)
return (m:get(section, "ech_key") or ""):gsub("\\n", "\n")
end
o.validate = function(self, value)
value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n")
value = value:gsub("^%s*\n", "")
if value:sub(-1) == "\n" then
value = value:sub(1, -2)
end
return value
value = api.trim(value):gsub("\r\n", "\n"):gsub("\r", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value:gsub("\n", "\\n")
end
o = s:option(ListValue, "transport", translate("Transport"))
@@ -193,12 +193,19 @@ o.default = 0
o.validate = function(self, value, t)
if value then
local reality = s.fields["reality"] and s.fields["reality"]:formvalue(t) or nil
local use_pem = s.fields["tls_use_pem"] and s.fields["tls_use_pem"]:formvalue(t) or nil
if reality and reality == "1" then return value end
if value == "1" then
if value == "1" and use_pem ~= "1" then
local ca = s.fields["tls_certificateFile"] and s.fields["tls_certificateFile"]:formvalue(t) or ""
local key = s.fields["tls_keyFile"] and s.fields["tls_keyFile"]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Certificate or Private key path can not be empty!")
return nil, translate("Certificate and Private key path can not be empty!")
end
elseif value == "1" and use_pem == "1" then
local ca = s.fields["tls_certificate"] and s.fields["tls_certificate"]:formvalue(t) or ""
local key = s.fields["tls_key"] and s.fields["tls_key"]:formvalue(t) or ""
if ca == "" or key == "" then
return nil, translate("Certificate and Private key PEM can not be empty!")
end
end
return value
@@ -263,11 +270,15 @@ end
-- [[ TLS部分 ]] --
o = s:option(Flag, "tls_use_pem", translate("Use PEM"), translate("Use certificate and private key PEM content."))
o:depends({ tls = true, reality = false })
o:depends({ protocol = "hysteria2" })
o = s:option(FileUpload, "tls_certificateFile", translate("Path to the certificate file"), translate("as:") .. "/etc/ssl/fullchain.crt")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. s.section .. ".crt"
if o and o:formvalue(s.section) then o.default = o:formvalue(s.section) end
o:depends({ tls = true, reality = false })
o:depends({ protocol = "hysteria2"})
o:depends({ tls = true, reality = false, tls_use_pem = false })
o:depends({ protocol = "hysteria2", tls_use_pem = false })
o.validate = function(self, value, t)
if value and value ~= "" then
if not api.fs.access(value) then
@@ -282,8 +293,8 @@ end
o = s:option(FileUpload, "tls_keyFile", translate("Path to the private key file"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. s.section .. ".key"
if o and o:formvalue(s.section) then o.default = o:formvalue(s.section) end
o:depends({ tls = true, reality = false })
o:depends({ protocol = "hysteria2"})
o:depends({ tls = true, reality = false, tls_use_pem = false })
o:depends({ protocol = "hysteria2", tls_use_pem = false })
o.validate = function(self, value, t)
if value and value ~= "" then
if not api.fs.access(value) then
@@ -295,6 +306,32 @@ o.validate = function(self, value, t)
return nil
end
o = s:option(TextValue, "tls_certificate", "TLS Certificate (PEM)", translate("Full certificate (chain), PEM format."))
o.default = ""
o.rows = 5
o.wrap = "off"
o:depends({ tls_use_pem = true })
o.cfgvalue = function(self, section)
return (m:get(section, "tls_certificate") or ""):gsub("\\n", "\n")
end
o.validate = function(self, value)
value = api.trim(value):gsub("\r\n", "\n"):gsub("\r", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value:gsub("\n", "\\n")
end
o = s:option(TextValue, "tls_key", "TLS Private Key (PEM)", translate("Private key in PEM format."))
o.default = ""
o.rows = 5
o.wrap = "off"
o:depends({ tls_use_pem = true })
o.cfgvalue = function(self, section)
return (m:get(section, "tls_key") or ""):gsub("\\n", "\n")
end
o.validate = function(self, value)
value = api.trim(value):gsub("\r\n", "\n"):gsub("\r", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n")
return value:gsub("\n", "\\n")
end
o = s:option(Flag, "ech", translate("ECH"))
o.default = "0"
o:depends({ tls = true, reality = false })
@@ -248,7 +248,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 api.split(node.tls_certificate_pem, "\n") or nil,
certificate = (node.tls_certificate == "1" and node.tls_certificate_pem ~= "") and api.split(node.tls_certificate_pem:gsub("\\n", "\n"), "\n") or nil,
cipher_suites = (node.cipherSuites and node.cipherSuites ~= "") and api.split(node.cipherSuites, ":") or nil,
ech = (node.ech == "1") and (function()
local function get_ech_domain(s) --兼容xray "域名+DNS" 格式ech
@@ -273,7 +273,7 @@ function gen_outbound(flag, node, tag, proxy_table)
ech.query_server_name = qname
ech_domain[qname] = true
elseif config then
ech.config = { config }
ech.config = api.split(config:gsub("\\n", "\n"), "\n")
elseif node.tls_serverName and node.tls_serverName ~= "" then
ech_domain[node.tls_serverName] = true
end
@@ -709,8 +709,10 @@ function gen_config_server(node)
local tls = {
enabled = true,
certificate_path = node.tls_certificateFile,
key_path = node.tls_keyFile,
certificate_path = (node.tls_use_pem ~= "1") and node.tls_certificateFile or nil,
key_path = (node.tls_use_pem ~= "1") and node.tls_keyFile or nil,
certificate = (node.tls_use_pem == "1" and node.tls_certificate) and api.split(node.tls_certificate:gsub("\\n", "\n"), "\n") or nil,
key = (node.tls_use_pem == "1" and node.tls_key) and api.split(node.tls_key:gsub("\\n", "\n"), "\n") or nil,
alpn = (node.alpn and node.alpn ~= "default") and (function()
local alpn = {}
string.gsub(node.alpn, '[^,]+', function(w)
@@ -724,6 +726,8 @@ function gen_config_server(node)
if node.tls == "1" and node.reality == "1" then
tls.certificate_path = nil
tls.key_path = nil
tls.certificate = nil
tls.key = nil
tls.server_name = node.reality_handshake_server
tls.reality = {
enabled = true,
@@ -181,7 +181,7 @@ function gen_outbound(flag, node, tag, proxy_table)
verifyPeerCertByName = node.tls_CertByName or "",
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"),
certificate = api.split(node.tls_certificate_pem:gsub("\\n", "\n"), "\n"),
usage = "verify"
} or nil,
cipherSuites = node.cipherSuites or nil
@@ -697,8 +697,10 @@ function gen_config_server(node)
disableSystemRoot = false,
certificates = {
{
certificateFile = node.tls_certificateFile,
keyFile = node.tls_keyFile
certificateFile = (node.tls_use_pem ~= "1") and node.tls_certificateFile or nil,
keyFile = (node.tls_use_pem ~= "1") and node.tls_keyFile or nil,
certificate = (node.tls_use_pem == "1" and node.tls_certificate) and api.split(node.tls_certificate:gsub("\\n", "\n"), "\n") or nil,
key = (node.tls_use_pem == "1" and node.tls_key) and api.split(node.tls_key:gsub("\\n", "\n"), "\n") or nil
}
},
echServerKeys = (node.ech == "1") and node.ech_key or nil
+17 -2
View File
@@ -1613,8 +1613,17 @@ msgstr "ECH 密钥路径"
msgid "Can't find this file!"
msgstr "找不到这个文件!"
msgid "Certificate or Private key path can not be empty!"
msgstr "证书或私钥文件路径不能为空!"
msgid "Certificate and Private key path can not be empty!"
msgstr "证书和私钥文件路径不能为空!"
msgid "Certificate and Private key PEM can not be empty!"
msgstr "证书和私钥 PEM 不能为空!"
msgid "Use PEM"
msgstr "使用 PEM"
msgid "Use certificate and private key PEM content."
msgstr "使用证书和私钥的 PEM 内容。"
msgid "Server-Side"
msgstr "服务器端"
@@ -1808,6 +1817,12 @@ msgstr "TLS 证书(PEM)"
msgid "Full certificate (chain), PEM format."
msgstr "完整证书(链),PEM 格式。"
msgid "TLS Private Key (PEM)"
msgstr "TLS 私钥(PEM)"
msgid "Private key in PEM format."
msgstr "PEM 格式的私钥。"
msgid "ECH Config"
msgstr "ECH 配置"
+1 -1
View File
@@ -23,7 +23,7 @@ msgid "Set the router's wireless name and password. For more advanced settings,
msgstr "设置路由器的无线名字和密码,更多高级设置请进入 网络-无线 页面。"
msgid "Leave empty to use ISP DNS"
msgstr "留空则使用阿里DNS"
msgstr "留空则使用运营商DNS"
msgid "Enter the main router IP"
msgstr "请输入主路由IP"