mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-10-26 22:52:51 +08:00
update 2026-05-21 10:49:42
This commit is contained in:
1 parent
6792f24236
commit
c94416953e
6 files changed
+507
-72
No files matched your search
@@ -222,6 +222,14 @@ if #hysteria2_type > 0 then
|
||||
for key, value in pairs(hysteria2_type) do
|
||||
o:value(value)
|
||||
end
|
||||
|
||||
o = s:option(Value, "hysteria_up_mbps", "Hy/Hy2 " .. translate("Max upload Mbps"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = "100"
|
||||
|
||||
o = s:option(Value, "hysteria_down_mbps", "Hy/Hy2 " .. translate("Max download Mbps"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = "100"
|
||||
end
|
||||
|
||||
o = s:option(Flag, "boot_update", translate("Update Once on Boot"), translate("Updates the subscription the first time PassWall runs automatically after each system boot."))
|
||||
|
||||
@@ -505,6 +505,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
local sub_vmess_type = DEFAULT_VMESS_TYPE
|
||||
local sub_vless_type = DEFAULT_VLESS_TYPE
|
||||
local sub_hysteria2_type = DEFAULT_HYSTERIA2_TYPE
|
||||
local sub_hy_up_mbps, sub_hy_down_mbps = 1000, 1000
|
||||
if sub_cfg then
|
||||
if sub_cfg.allowInsecure and sub_cfg.allowInsecure ~= "1" then
|
||||
sub_allowinsecure = nil
|
||||
@@ -529,6 +530,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
if hysteria2_type ~= "global" and core_has[hysteria2_type] then
|
||||
sub_hysteria2_type = hysteria2_type
|
||||
end
|
||||
sub_hy_up_mbps = sub_cfg.hysteria_up_mbps
|
||||
sub_hy_down_mbps = sub_cfg.hysteria_down_mbps
|
||||
end
|
||||
local result = {
|
||||
timeout = 60,
|
||||
@@ -1351,8 +1354,8 @@ 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.alpn = params.alpn
|
||||
result.hysteria_up_mbps = params.upmbps
|
||||
result.hysteria_down_mbps = params.downmbps
|
||||
result.hysteria_up_mbps = params.upmbps or sub_hy_up_mbps
|
||||
result.hysteria_down_mbps = params.downmbps or sub_hy_down_mbps
|
||||
result.hysteria_hop = params.mport
|
||||
|
||||
elseif szType == 'hysteria2' or szType == 'hy2' then
|
||||
@@ -1396,8 +1399,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.tls_CertByName = params.vcn
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
result.hysteria2_up_mbps = params.upmbps
|
||||
result.hysteria2_down_mbps = params.downmbps
|
||||
result.hysteria2_up_mbps = params.upmbps or sub_hy_up_mbps
|
||||
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"
|
||||
|
||||
@@ -7,68 +7,39 @@ require "nixio.fs"
|
||||
local m, s, o
|
||||
local sid = arg[1]
|
||||
|
||||
-- 加密方式(SS/SSR用)
|
||||
local encrypt_methods = {
|
||||
"rc4-md5",
|
||||
"rc4-md5-6",
|
||||
"rc4",
|
||||
"table",
|
||||
"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",
|
||||
"cast5-cfb",
|
||||
"des-cfb",
|
||||
"idea-cfb",
|
||||
"rc2-cfb",
|
||||
"seed-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf"
|
||||
"rc4-md5", "rc4-md5-6", "rc4", "table",
|
||||
"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",
|
||||
"cast5-cfb", "des-cfb", "idea-cfb", "rc2-cfb", "seed-cfb",
|
||||
"salsa20", "chacha20", "chacha20-ietf"
|
||||
}
|
||||
|
||||
local encrypt_methods_ss = {
|
||||
-- aead
|
||||
"aes-128-gcm",
|
||||
"aes-192-gcm",
|
||||
"aes-256-gcm",
|
||||
"chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305",
|
||||
-- aead 2022
|
||||
"2022-blake3-aes-128-gcm",
|
||||
"2022-blake3-aes-256-gcm",
|
||||
"2022-blake3-chacha20-poly1305"
|
||||
--[[ stream
|
||||
"table",
|
||||
"rc4",
|
||||
"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" ]]
|
||||
"aes-128-gcm", "aes-192-gcm", "aes-256-gcm",
|
||||
"chacha20-ietf-poly1305", "xchacha20-ietf-poly1305",
|
||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||
}
|
||||
|
||||
-- Shadowsocks 加密方法(Xray 版)
|
||||
local v_ss_encrypt_method_list = {
|
||||
"aes-128-cfb", "aes-256-cfb", "aes-128-gcm", "aes-256-gcm",
|
||||
"chacha20", "chacha20-ietf", "chacha20-poly1305", "chacha20-ietf-poly1305"
|
||||
}
|
||||
|
||||
-- 伪装类型(用于 mKCP/QUIC)
|
||||
local header_type_list = {
|
||||
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard"
|
||||
}
|
||||
|
||||
local protocol = {"origin"}
|
||||
|
||||
obfs = {"plain", "http_simple", "http_post"}
|
||||
|
||||
m = Map("shadowsocksr", translate("Edit ShadowSocksR Server"))
|
||||
|
||||
m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/server")
|
||||
|
||||
if m.uci:get("shadowsocksr", sid) ~= "server_config" then
|
||||
luci.http.redirect(m.redirect)
|
||||
return
|
||||
@@ -79,6 +50,7 @@ s = m:section(NamedSection, sid, "server_config")
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
-- ========== 基本设置 ==========
|
||||
o = s:option(Flag, "enable", translate("Enable"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
@@ -91,6 +63,13 @@ end
|
||||
if nixio.fs.access("/usr/bin/ssr-server") then
|
||||
o:value("ssr", translate("ShadowsocksR"))
|
||||
end
|
||||
-- Xray 协议支持
|
||||
if nixio.fs.access("/usr/bin/xray") or nixio.fs.access("/usr/libexec/xray") then
|
||||
o:value("vmess", "VMess (Xray)")
|
||||
o:value("vless", "VLESS (Xray)")
|
||||
o:value("trojan", "Trojan (Xray)")
|
||||
o:value("shadowsocks", "Shadowsocks (Xray)")
|
||||
end
|
||||
o.default = "socks5"
|
||||
|
||||
o = s:option(Value, "server_port", translate("Server Port"))
|
||||
@@ -114,32 +93,30 @@ o:depends("type", "socks5")
|
||||
o = s:option(Value, "password", translate("Password"))
|
||||
o.password = true
|
||||
o.rmempty = false
|
||||
o:depends("type", "socks5")
|
||||
o:depends("type", "ss")
|
||||
o:depends("type", "ssr")
|
||||
o:depends("type", "trojan")
|
||||
o:depends("type", "shadowsocks")
|
||||
|
||||
-- ========== SS/SSR 协议特有 ==========
|
||||
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
|
||||
for _, v in ipairs(encrypt_methods) do
|
||||
o:value(v)
|
||||
end
|
||||
for _, v in ipairs(encrypt_methods) do o:value(v) end
|
||||
o.rmempty = false
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
|
||||
for _, v in ipairs(encrypt_methods_ss) do
|
||||
o:value(v)
|
||||
end
|
||||
for _, v in ipairs(encrypt_methods_ss) do o:value(v) end
|
||||
o.rmempty = false
|
||||
o:depends("type", "ss")
|
||||
|
||||
o = s:option(ListValue, "protocol", translate("Protocol"))
|
||||
for _, v in ipairs(protocol) do
|
||||
o:value(v)
|
||||
end
|
||||
for _, v in ipairs(protocol) do o:value(v) end
|
||||
o.rmempty = false
|
||||
o:depends("type", "ssr")
|
||||
|
||||
o = s:option(ListValue, "obfs", translate("Obfs"))
|
||||
for _, v in ipairs(obfs) do
|
||||
o:value(v)
|
||||
end
|
||||
for _, v in ipairs(obfs) do o:value(v) end
|
||||
o.rmempty = false
|
||||
o:depends("type", "ssr")
|
||||
|
||||
@@ -151,4 +128,269 @@ o.rmempty = false
|
||||
o:depends("type", "ss")
|
||||
o:depends("type", "ssr")
|
||||
|
||||
return m
|
||||
-- ========== Xray 协议通用字段 ==========
|
||||
-- 用户备注
|
||||
o = s:option(Value, "remarks", translate("Remarks"))
|
||||
o.default = translate("Remarks")
|
||||
o.rmempty = true
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
o:depends("type", "trojan")
|
||||
o:depends("type", "shadowsocks")
|
||||
|
||||
-- 用户等级
|
||||
o = s:option(Value, "level", translate("User Level"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 1
|
||||
o.rmempty = true
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
o:depends("type", "shadowsocks")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
-- ========== Xray 协议认证字段 ==========
|
||||
-- UUID (用于 vmess/vless)
|
||||
o = s:option(Value, "uuid", translate("UUID"))
|
||||
o.description = translate("Required for VMess/VLESS. Generate with: uuidgen")
|
||||
o.rmempty = true
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
|
||||
-- Trojan 密码
|
||||
o = s:option(Value, "trojan_password", translate("Trojan Password"))
|
||||
o.password = true
|
||||
o.rmempty = true
|
||||
o:depends("type", "trojan")
|
||||
|
||||
-- Shadowsocks 密码和加密(Xray 内置)
|
||||
o = s:option(Value, "ss_password", translate("Shadowsocks Password"))
|
||||
o.password = true
|
||||
o.rmempty = true
|
||||
o:depends("type", "shadowsocks")
|
||||
|
||||
o = s:option(ListValue, "ss_method", translate("Encrypt Method"))
|
||||
for _, v in ipairs(v_ss_encrypt_method_list) do o:value(v) end
|
||||
o.default = "chacha20-ietf-poly1305"
|
||||
o.rmempty = true
|
||||
o:depends("type", "shadowsocks")
|
||||
|
||||
o = s:option(ListValue, "ss_network", translate("Transport"))
|
||||
o:value("tcp", "TCP")
|
||||
o:value("udp", "UDP")
|
||||
o:value("tcp,udp", "TCP,UDP")
|
||||
o.default = "tcp,udp"
|
||||
o.rmempty = true
|
||||
o:depends("type", "shadowsocks")
|
||||
|
||||
-- VMess alterId
|
||||
o = s:option(Value, "alter_id", translate("Alter ID"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 0
|
||||
o.rmempty = true
|
||||
o:depends("type", "vmess")
|
||||
|
||||
-- VLESS decryption
|
||||
o = s:option(Value, "decryption", translate("Decryption"))
|
||||
o.default = "none"
|
||||
o.rmempty = true
|
||||
o:depends("type", "vless")
|
||||
|
||||
-- ========== TLS / XTLS 设置 ==========
|
||||
o = s:option(Flag, "tls", translate("TLS"))
|
||||
o.default = 0
|
||||
o.rmempty = true
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
o:depends("type", "trojan")
|
||||
o:depends("type", "shadowsocks")
|
||||
|
||||
o = s:option(Flag, "xtls", translate("XTLS"))
|
||||
o.default = 0
|
||||
o.rmempty = true
|
||||
o:depends({ type = "vless", tls = "1" })
|
||||
|
||||
o = s:option(ListValue, "flow", translate("Flow"))
|
||||
o:value("xtls-rprx-origin", "xtls-rprx-origin")
|
||||
o:value("xtls-rprx-origin-udp443", "xtls-rprx-origin-udp443")
|
||||
o:value("xtls-rprx-direct", "xtls-rprx-direct")
|
||||
o:value("xtls-rprx-direct-udp443", "xtls-rprx-direct-udp443")
|
||||
o:value("xtls-rprx-splice", "xtls-rprx-splice")
|
||||
o:value("xtls-rprx-splice-udp443", "xtls-rprx-splice-udp443")
|
||||
o.default = "xtls-rprx-direct"
|
||||
o.rmempty = true
|
||||
o:depends("xtls", "1")
|
||||
|
||||
o = s:option(Value, "tls_serverName", translate("Server Name (SNI)"))
|
||||
o.rmempty = true
|
||||
o:depends("tls", "1")
|
||||
|
||||
o = s:option(Value, "tls_certificateFile", translate("Certificate File Path"))
|
||||
o.description = translate("e.g.: /etc/ssl/fullchain.pem")
|
||||
o.rmempty = true
|
||||
o:depends("tls", "1")
|
||||
|
||||
o = s:option(Value, "tls_keyFile", translate("Private Key File Path"))
|
||||
o.description = translate("e.g.: /etc/ssl/private.key")
|
||||
o.rmempty = true
|
||||
o:depends("tls", "1")
|
||||
|
||||
-- ========== 传输层设置 (Transport) ==========
|
||||
o = s:option(ListValue, "transport", translate("Transport Protocol"))
|
||||
o:value("tcp", "TCP")
|
||||
o:value("mkcp", "mKCP")
|
||||
o:value("ws", "WebSocket")
|
||||
o:value("h2", "HTTP/2")
|
||||
o:value("ds", "DomainSocket")
|
||||
o:value("quic", "QUIC")
|
||||
o.default = "tcp"
|
||||
o.rmempty = true
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
-- ----- WebSocket 设置 -----
|
||||
o = s:option(Value, "ws_host", translate("WebSocket Host"))
|
||||
o.rmempty = true
|
||||
o:depends("transport", "ws")
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
o = s:option(Value, "ws_path", translate("WebSocket Path"))
|
||||
o.default = "/"
|
||||
o.rmempty = true
|
||||
o:depends("transport", "ws")
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
o:depends("type", "trojan")
|
||||
|
||||
-- ----- HTTP/2 设置 -----
|
||||
o = s:option(Value, "h2_host", translate("HTTP/2 Host"))
|
||||
o.rmempty = true
|
||||
o:depends("transport", "h2")
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
|
||||
o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
|
||||
o.default = "/"
|
||||
o.rmempty = true
|
||||
o:depends("transport", "h2")
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
|
||||
-- ----- TCP 伪装设置 -----
|
||||
o = s:option(ListValue, "tcp_guise", translate("TCP Camouflage Type"))
|
||||
o:value("none", "none")
|
||||
o:value("http", "http")
|
||||
o.default = "none"
|
||||
o.rmempty = true
|
||||
o:depends("transport", "tcp")
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
|
||||
o = s:option(DynamicList, "tcp_guise_http_host", translate("HTTP Host"))
|
||||
o.rmempty = true
|
||||
o:depends("tcp_guise", "http")
|
||||
|
||||
o = s:option(DynamicList, "tcp_guise_http_path", translate("HTTP Path"))
|
||||
o.rmempty = true
|
||||
o:depends("tcp_guise", "http")
|
||||
|
||||
-- ----- mKCP 设置 -----
|
||||
o = s:option(ListValue, "mkcp_guise", translate("mKCP Camouflage Type"))
|
||||
for _, v in ipairs(header_type_list) do o:value(v) end
|
||||
o.default = "none"
|
||||
o.rmempty = true
|
||||
o:depends("transport", "mkcp")
|
||||
|
||||
o = s:option(Value, "mkcp_mtu", translate("KCP MTU"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 1350
|
||||
o.rmempty = true
|
||||
o:depends("transport", "mkcp")
|
||||
|
||||
o = s:option(Value, "mkcp_tti", translate("KCP TTI"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 20
|
||||
o.rmempty = true
|
||||
o:depends("transport", "mkcp")
|
||||
|
||||
o = s:option(Value, "mkcp_uplinkCapacity", translate("KCP Uplink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 5
|
||||
o.rmempty = true
|
||||
o:depends("transport", "mkcp")
|
||||
|
||||
o = s:option(Value, "mkcp_downlinkCapacity", translate("KCP Downlink Capacity"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 20
|
||||
o.rmempty = true
|
||||
o:depends("transport", "mkcp")
|
||||
|
||||
o = s:option(Flag, "mkcp_congestion", translate("KCP Congestion Control"))
|
||||
o.default = 0
|
||||
o.rmempty = true
|
||||
o:depends("transport", "mkcp")
|
||||
|
||||
o = s:option(Value, "mkcp_readBufferSize", translate("KCP Read Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 1
|
||||
o.rmempty = true
|
||||
o:depends("transport", "mkcp")
|
||||
|
||||
o = s:option(Value, "mkcp_writeBufferSize", translate("KCP Write Buffer Size"))
|
||||
o.datatype = "uinteger"
|
||||
o.default = 1
|
||||
o.rmempty = true
|
||||
o:depends("transport", "mkcp")
|
||||
|
||||
o = s:option(Value, "mkcp_seed", translate("KCP Seed"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = true
|
||||
o:depends("transport", "mkcp")
|
||||
|
||||
-- ----- DomainSocket 设置 -----
|
||||
o = s:option(Value, "ds_path", translate("DomainSocket Path"))
|
||||
o.description = translate("A legal file path. This file must not exist before running.")
|
||||
o.rmempty = true
|
||||
o:depends("transport", "ds")
|
||||
|
||||
-- ----- QUIC 设置 -----
|
||||
o = s:option(ListValue, "quic_security", translate("QUIC Security"))
|
||||
o:value("none", "none")
|
||||
o:value("aes-128-gcm", "aes-128-gcm")
|
||||
o:value("chacha20-poly1305", "chacha20-poly1305")
|
||||
o.default = "none"
|
||||
o.rmempty = true
|
||||
o:depends("transport", "quic")
|
||||
|
||||
o = s:option(Value, "quic_key", translate("QUIC Key"))
|
||||
o.rmempty = true
|
||||
o:depends("transport", "quic")
|
||||
|
||||
o = s:option(ListValue, "quic_guise", translate("QUIC Camouflage Type"))
|
||||
for _, v in ipairs(header_type_list) do o:value(v) end
|
||||
o.default = "none"
|
||||
o.rmempty = true
|
||||
o:depends("transport", "quic")
|
||||
|
||||
-- ========== 访问控制 ==========
|
||||
o = s:option(Flag, "bind_local", translate("Bind Local Only"))
|
||||
o.description = translate("When selected, it can only be accessed locally. Recommended when using reverse proxies.")
|
||||
o.default = 0
|
||||
o.rmempty = true
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
o:depends("type", "trojan")
|
||||
o:depends("type", "shadowsocks")
|
||||
|
||||
o = s:option(Flag, "accept_lan", translate("Accept LAN Access"))
|
||||
o.description = translate("When selected, it can be accessed from LAN. This may not be safe!")
|
||||
o.default = 0
|
||||
o.rmempty = true
|
||||
o:depends("type", "vmess")
|
||||
o:depends("type", "vless")
|
||||
o:depends("type", "trojan")
|
||||
o:depends("type", "shadowsocks")
|
||||
|
||||
return m
|
||||
@@ -105,8 +105,13 @@ end
|
||||
o.rmempty = false
|
||||
|
||||
o = sec:option(DummyValue, "type", translate("Server Type"))
|
||||
function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "ss"
|
||||
function o.cfgvalue(self, section)
|
||||
local val = Value.cfgvalue(self, section) or "ss"
|
||||
if val == "vmess" then return "VMess (Xray)"
|
||||
elseif val == "vless" then return "VLESS (Xray)"
|
||||
elseif val == "trojan" then return "Trojan (Xray)"
|
||||
elseif val == "shadowsocks" then return "Shadowsocks (Xray)"
|
||||
else return val end
|
||||
end
|
||||
|
||||
o = sec:option(DummyValue, "server_port", translate("Server Port"))
|
||||
@@ -135,4 +140,4 @@ function o.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or "-"
|
||||
end
|
||||
|
||||
return m
|
||||
return m
|
||||
@@ -985,6 +985,130 @@ start_dns() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 生成 Xray 服务端配置
|
||||
# 生成 Xray 服务端配置
|
||||
generate_xray_config() {
|
||||
local type="$1"
|
||||
local port="$2"
|
||||
local password="$3"
|
||||
local security="$4"
|
||||
local method="$5"
|
||||
local network="$6"
|
||||
local ws_path="$7"
|
||||
local ws_host="$8"
|
||||
local grpc_service="$9"
|
||||
local alter_id="${10}"
|
||||
local tcp_guise="${11}"
|
||||
local tcp_guise_http_host="${12}"
|
||||
local tcp_guise_http_path="${13}"
|
||||
local config_file="${14}"
|
||||
|
||||
local inbound_json=""
|
||||
|
||||
case "$type" in
|
||||
vmess)
|
||||
inbound_json="{
|
||||
\"protocol\": \"vmess\",
|
||||
\"port\": $port,
|
||||
\"settings\": {
|
||||
\"clients\": [{\"id\": \"$password\", \"alterId\": $alter_id}]
|
||||
},
|
||||
\"streamSettings\": {
|
||||
\"network\": \"$network\"
|
||||
}
|
||||
}"
|
||||
;;
|
||||
vless)
|
||||
inbound_json="{
|
||||
\"protocol\": \"vless\",
|
||||
\"port\": $port,
|
||||
\"settings\": {
|
||||
\"clients\": [{\"id\": \"$password\"}],
|
||||
\"decryption\": \"none\"
|
||||
},
|
||||
\"streamSettings\": {
|
||||
\"network\": \"$network\"
|
||||
}
|
||||
}"
|
||||
;;
|
||||
trojan)
|
||||
inbound_json="{
|
||||
\"protocol\": \"trojan\",
|
||||
\"port\": $port,
|
||||
\"settings\": {
|
||||
\"clients\": [{\"password\": \"$password\"}]
|
||||
},
|
||||
\"streamSettings\": {
|
||||
\"network\": \"$network\"
|
||||
}
|
||||
}"
|
||||
;;
|
||||
shadowsocks)
|
||||
inbound_json="{
|
||||
\"protocol\": \"shadowsocks\",
|
||||
\"port\": $port,
|
||||
\"settings\": {
|
||||
\"method\": \"$method\",
|
||||
\"password\": \"$password\"
|
||||
}
|
||||
}"
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# 添加传输层细节
|
||||
case "$network" in
|
||||
ws)
|
||||
local ws_json="{\"path\": \"$ws_path\"}"
|
||||
[ -n "$ws_host" ] && ws_json="{\"path\": \"$ws_path\", \"headers\": {\"Host\": \"$ws_host\"}}"
|
||||
inbound_json=$(echo "$inbound_json" | sed "s/\"streamSettings\": {/\"streamSettings\": {\"wsSettings\": $ws_json, /")
|
||||
;;
|
||||
grpc)
|
||||
[ -n "$grpc_service" ] && inbound_json=$(echo "$inbound_json" | sed "s/\"streamSettings\": {/\"streamSettings\": {\"grpcSettings\": {\"serviceName\": \"$grpc_service\"}, /")
|
||||
;;
|
||||
tcp)
|
||||
# TCP HTTP 伪装
|
||||
if [ "$tcp_guise" = "http" ]; then
|
||||
local tcp_json="{\"header\": {\"type\": \"http\""
|
||||
|
||||
# 添加 HTTP Host
|
||||
if [ -n "$tcp_guise_http_host" ]; then
|
||||
# 将空格分隔的多个 host 转换为 JSON 数组格式
|
||||
local host_list=$(echo "$tcp_guise_http_host" | sed 's/ /","/g')
|
||||
tcp_json="$tcp_json, \"request\": {\"headers\": {\"Host\": [\"$host_list\"]}}"
|
||||
fi
|
||||
|
||||
# 添加 HTTP Path
|
||||
if [ -n "$tcp_guise_http_path" ]; then
|
||||
local path_list=$(echo "$tcp_guise_http_path" | sed 's/ /","/g')
|
||||
tcp_json="$tcp_json, \"response\": {\"headers\": {\"Location\": [\"$path_list\"]}}"
|
||||
fi
|
||||
|
||||
tcp_json="$tcp_json}}"
|
||||
inbound_json=$(echo "$inbound_json" | sed "s/\"streamSettings\": {/\"streamSettings\": {\"tcpSettings\": $tcp_json, /")
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
cat > "$config_file" << EOF
|
||||
{
|
||||
"log": {
|
||||
"loglevel": "warning"
|
||||
},
|
||||
"inbounds": [$inbound_json],
|
||||
"outbounds": [
|
||||
{
|
||||
"protocol": "freedom",
|
||||
"settings": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
return 0
|
||||
}
|
||||
|
||||
gen_service_file() { #1-server.type 2-cfgname 3-file_path
|
||||
local fastopen
|
||||
if [ $(uci_get_by_name $2 fast_open) == "1" ]; then
|
||||
@@ -1875,6 +1999,59 @@ start_server() {
|
||||
ln_start_bin $(first_type microsocks) microsocks $listenip -p $(uci_get_by_name $1 server_port) -1 $auth_opts ssr-server$server_count
|
||||
echolog "Server:Socks5 Server$server_count Started!"
|
||||
;;
|
||||
vmess|vless|trojan|shadowsocks)
|
||||
# Xray 服务端支持
|
||||
local port=$(uci_get_by_name "$1" server_port)
|
||||
local uuid=$(uci_get_by_name "$1" uuid)
|
||||
local trojan_pass=$(uci_get_by_name "$1" trojan_password)
|
||||
local ss_pass=$(uci_get_by_name "$1" ss_password)
|
||||
local security=$(uci_get_by_name "$1" security "auto")
|
||||
local network=$(uci_get_by_name "$1" network "tcp")
|
||||
local ws_path=$(uci_get_by_name "$1" ws_path "/")
|
||||
local ws_host=$(uci_get_by_name "$1" ws_host "")
|
||||
local grpc_service=$(uci_get_by_name "$1" grpc_service "")
|
||||
local alter_id=$(uci_get_by_name "$1" alter_id "0")
|
||||
local tcp_guise=$(uci_get_by_name "$1" tcp_guise "none")
|
||||
local tcp_guise_http_host=$(uci_get_by_name "$1" tcp_guise_http_host "")
|
||||
local tcp_guise_http_path=$(uci_get_by_name "$1" tcp_guise_http_path "")
|
||||
|
||||
# 确定密码/UUID
|
||||
local password=""
|
||||
local method=""
|
||||
if [ "$type" = "vmess" ] || [ "$type" = "vless" ]; then
|
||||
password="$uuid"
|
||||
elif [ "$type" = "trojan" ]; then
|
||||
password="$trojan_pass"
|
||||
elif [ "$type" = "shadowsocks" ]; then
|
||||
password="$ss_pass"
|
||||
method="$security"
|
||||
[ -z "$method" ] && method="chacha20-ietf-poly1305"
|
||||
fi
|
||||
|
||||
[ -z "$password" ] && {
|
||||
echolog "Server: $type 服务端缺少密码/UUID,跳过启动"
|
||||
return 1
|
||||
}
|
||||
|
||||
local config_file="$TMP_PATH/xray-server-$server_count.json"
|
||||
|
||||
# 生成 Xray 配置
|
||||
generate_xray_config "$type" "$port" "$password" "$security" "$method" "$network" "$ws_path" "$ws_host" "$grpc_service" "$alter_id" "$tcp_guise" "$tcp_guise_http_host" "$tcp_guise_http_path" "$config_file"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echolog "Server: Xray $type 配置生成失败"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local xray_bin=$(first_type xray)
|
||||
if [ -z "$xray_bin" ]; then
|
||||
echolog "Server: xray-core 未安装,无法启动 $type 服务端"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ln_start_bin "$xray_bin" xray-server-$server_count run -c "$config_file"
|
||||
echolog "Server: Xray $type 服务端 Server$server_count 已启动 (端口: $port)"
|
||||
;;
|
||||
esac
|
||||
server_port=$(uci_get_by_name $1 server_port)
|
||||
if [ "$USE_TABLES" = "nftables" ]; then
|
||||
|
||||
@@ -114,7 +114,7 @@ while [ "1" == "1" ]; do #死循环
|
||||
fi
|
||||
#server
|
||||
if [ "$server_process_count" -gt 0 ]; then
|
||||
icount=$(match_proc_count 'ssr-server|ss-server-')
|
||||
icount=$(match_proc_count 'ssr-server|ss-server-|xray-server-')
|
||||
if [ "$icount" -lt "$server_process_count" ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "ssrplus server error.restart!"
|
||||
echolog "ssrplus server error.restart!"
|
||||
|
||||
Reference in new issue
Block a user