update 2025-02-16 20:43:00

This commit is contained in:
actions-user 2025-02-16 20:43:00 +08:00
parent d8232e36df
commit 811b401d54
15 changed files with 111467 additions and 56282 deletions

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-bypass
PKG_VERSION:=1.8.1
PKG_VERSION:=1.8.2
PKG_RELEASE:=23
PKG_CONFIG_DEPENDS:= \

View File

@ -4,16 +4,6 @@ local uci=luci.model.uci.cursor()
local server_count=0
local SYS=require"luci.sys"
function url(...)
local url = string.format("admin/services/%s", bypass)
local args = { ... }
for i, v in pairs(args) do
if v ~= "" then
url = url .. "/" .. v
end
end
return require "luci.dispatcher".build_url(url)
end
local server_table={}
luci.model.uci.cursor():foreach("bypass","servers",function(s)
if (s.type=="ss" and not nixio.fs.access("/usr/bin/ss-local")) or (s.type=="ssr" and not nixio.fs.access("/usr/bin/ssr-local")) or s.type=="socks5" or s.type=="tun" then
@ -82,7 +72,7 @@ o = s:option(Value, "ad_url", translate("anti-AD Update URL"))
o:value("https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt", translate("privacy-protection-tools/anti-ad-github"))
o:value("https://anti-ad.net/domains.txt", translate("privacy-protection-tools/anti-AD"))
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/ad_list.txt", translate("sirpdboy/ad_list"))
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/ad_list.txt"
o.default = "https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt"
---- gfwlist URL
o = s:option(Value, "gfwlist_url", translate("GFW domains Update URL"))
@ -91,8 +81,7 @@ o:value("https://fastly.jsdelivr.net/gh/Loukky/gfwlist-by-loukky/gfwlist.txt", t
o:value("https://fastly.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt", translate("gfwlist/gfwlist"))
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/gfwlist.txt", translate("sirpdboy/gfwlist"))
o:value("https://openwrt.ai/bypass/gfwlist.txt", translate("supes/gfwlist"))
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/gfwlist.txt"
o.default = "https://fastly.jsdelivr.net/gh/YW5vbnltb3Vz/domain-list-community@release/gfwlist.txt"
----chnroute URL
o = s:option(Value, "chnroute_url", translate("China IPv4 Update URL"))
@ -104,26 +93,26 @@ o:value("https://fastly.jsdelivr.net/gh/soffchen/GeoIP2-CN@release/CN-ip-cidr.tx
o:value("https://fastly.jsdelivr.net/gh/Hackl0us/GeoIP2-CN@release/CN-ip-cidr.txt", translate("Hackl0us/GeoIP2-CN"))
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/all_cn.txt", translate("sirpdboy/all_cn"))
o:value("https://openwrt.ai/bypass/all_cn.txt", translate("supes/all_cn"))
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/all_cn.txt"
o.default = "https://ispip.clang.cn/all_cn.txt"
----chnroute6 URL
o = s:option(Value, "chnroute6_url", translate("China IPv6 Update URL"))
o:value("https://ispip.clang.cn/all_cn_ipv6.txt", translate("Clang.CN.IPv6"))
o:value("https://fastly.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china6.txt", translate("gaoyifan/china-ipv6"))
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/all_cn_ipv6.txt", translate("sirpdboy/all_cn_ipv6"))
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/all_cn_ipv6.txt"
o.default = "https://ispip.clang.cn/all_cn_ipv6.txt"
----domains URL
o = s:option(Value, "domains_url", translate("China Domains Update URL"))
o:value("https://fastly.jsdelivr.net/gh/yubanmeiqin9048/domain@release/accelerated-domains.china.txt", translate("yubanmeiqin9048/domains.china"))
o:value("https://github.com/sirpdboy/iplist/releases/latest/download/domains_cn.txt", translate("sirpdboy/domains_cn"))
o.default = "https://github.com/sirpdboy/iplist/releases/latest/download/domains_cn.txt"
o.default = "https://fastly.jsdelivr.net/gh/yubanmeiqin9048/domain@release/accelerated-domains.china.txt"
o = s:option(Button, "UpdateRule", translate("Update All Rule List"))
o.inputstyle = "apply"
function o.write(t, n)
luci.sys.call("/usr/share/bypass/update")
luci.http.redirect(url("log"))
o.write = function()
luci.sys.call("bash /usr/share/bypass/update")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "bypass", "log"))
end
s=m:section(TypedSection,"socks5_proxy",translate("Global SOCKS5 Server"))

View File

@ -154,8 +154,8 @@ end
if is_finded("sslocal") or is_finded("ssmanager") then
o:value("ss", translate("Shadowsocks-rust Version"))
end
if is_finded("trojan-plus") or is_finded("trojan") then
o:value("trojan", translate("Trojan-plus"))
if is_finded("trojan") then
o:value("trojan", translate("Trojan"))
end
if is_finded("naive") then
o:value("naiveproxy", translate("NaiveProxy"))
@ -509,6 +509,7 @@ o.rmempty = true
-- Tuic settings for the local inbound socks5 server
o = s:option(Flag, "tuic_dual_stack", translate("Dual-stack Listening Socket"))
o.description = translate("If this option is not set, the socket behavior is platform dependent.")
o:depends("type", "tuic")
o.default = "0"
o.rmempty = true
@ -564,6 +565,7 @@ o:value("kcp", "mKCP")
o:value("ws", "WebSocket")
o:value("httpupgrade", "HTTPUpgrade")
o:value("splithttp", "SplitHTTP")
o:value("xhttp", "XHTTP")
o:value("h2", "HTTP/2")
o:value("quic", "QUIC")
o:value("grpc", "gRPC")
@ -641,6 +643,71 @@ o.rmempty = true
o = s:option(Value, "splithttp_path", translate("Splithttp Path"))
o:depends("transport", "splithttp")
o.rmempty = true
-- [[ XHTTP部分 ]]--
o = s:option(ListValue, "xhttp_alpn", translate("XHTTP Alpn"))
o.default = ""
o:value("", translate("Default"))
o:value("h3")
o:value("h2")
o:value("h3,h2")
o:value("http/1.1")
o:value("h2,http/1.1")
o:value("h3,h2,http/1.1")
o:depends("transport", "xhttp")
o = s:option(ListValue, "xhttp_mode", translate("XHTTP Mode"))
o:depends("transport", "xhttp")
o.default = "auto"
o:value("auto")
o:value("packet-up")
o:value("stream-up")
o:value("stream-one")
o = s:option(Value, "xhttp_host", translate("XHTTP Host"))
o:depends({transport = "xhttp", tls = false})
o.rmempty = true
o = s:option(Value, "xhttp_path", translate("XHTTP Path"))
o.placeholder = "/"
o:depends("transport", "xhttp")
o.rmempty = true
o = s:option(Flag, "enable_xhttp_extra", translate("XHTTP Extra"))
o.description = translate("Enable this option to configure XHTTP Extra (JSON format).")
o.rmempty = true
o.default = "0"
o:depends("transport", "xhttp")
o = s:option(TextValue, "xhttp_extra", " ")
o.description = translate(
"<font><b>" .. translate("Configure XHTTP Extra Settings (JSON format), see:") .. "</b></font>" ..
" <a href='https://xtls.github.io/config/transports/splithttp.html#extra' target='_blank'>" ..
"<font style='color:green'><b>" .. translate("Click to the page") .. "</b></font></a>")
o:depends("enable_xhttp_extra", true)
o.rmempty = true
o.rows = 10
o.wrap = "off"
o.custom_write = function(self, section, value)
m:set(section, "xhttp_extra", value)
local success, data = pcall(luci.jsonc.parse, value)
if success and data then
local address = (data.extra and data.extra.downloadSettings and data.extra.downloadSettings.address)
or (data.downloadSettings and data.downloadSettings.address)
if address and address ~= "" then
m:set(section, "download_address", address)
else
m:del(section, "download_address")
end
else
m:del(section, "download_address")
end
end
o.validate = function(self, value)
value = value:gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n")
if value:sub(-1) == "\n" then
value = value:sub(1, -2)
end
local success, data = pcall(luci.jsonc.parse, value)
if not success or not data then
return nil, translate("Invalid JSON format")
end
return value
end
-- [[ H2部分 ]]--
@ -871,6 +938,18 @@ if is_finded("xray") then
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw", tls = true})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw", reality = true})
o = s:option(ListValue, "xhttp_tls_flow", translate("Flow"))
for _, v in ipairs(tls_flows) do
if v == "none" then
o.default = "none"
o:value("none", translate("none"))
else
o:value("xtls-rprx-vision", translate("xtls-rprx-vision"))
end
end
o.rmempty = true
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp", tls = true})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp", reality = true})
-- [[ uTLS ]]--
o = s:option(ListValue, "fingerprint", translate("Finger Print"))
o.default = ""
@ -919,43 +998,77 @@ o:depends({type = "hysteria", insecure = true })
o:depends({type = "hysteria2", insecure = true })
o.rmempty = true
-- [[ Mux ]]--
o = s:option(Flag, "mux", translate("Mux"))
-- [[ Mux.Cool ]] --
o = s:option(Flag, "mux", translate("Mux"), translate("Enable Mux.Cool"))
o.rmempty = false
o.default = false
o:depends({type = "v2ray", v2ray_protocol = "vless"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "ws"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "kcp"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "httpupgrade"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "splithttp"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "h2"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "quic"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "grpc"})
o:depends({type = "v2ray", v2ray_protocol = "vmess"})
o:depends({type = "v2ray", v2ray_protocol = "trojan"})
o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
o:depends({type = "v2ray", v2ray_protocol = "socks"})
o:depends({type = "v2ray", v2ray_protocol = "http"})
-- [[ XUDP Mux ]] --
o = s:option(Flag, "xmux", translate("Xudp Mux"), translate("Enable Xudp Mux"))
o.rmempty = false
o.default = false
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"})
-- [[ TCP 最大并发连接数 ]]--
o = s:option(ListValue, "concurrency", translate("concurrency"))
o = s:option(Value, "concurrency", translate("concurrency"))
o.description = translate(
"<ul>"
.. "<li>" .. translate("Default: disable. When entering a negative number, such as -1, The Mux module will not be used to carry TCP traffic.") .. "</li>"
.. "<li>" .. translate("Min value is 1, Max value is 128. When omitted or set to 0, it equals 8.") .. "</li>"
.. "</ul>")
o.rmempty = true
o.default = "-1"
o:value("-1", translate("disable"))
o:value("8", translate("8"))
o:depends("mux", true)
-- [[ UDP 最大并发连接数 ]]--
o = s:option(ListValue, "xudpConcurrency", translate("xudpConcurrency"))
o = s:option(Value, "xudpConcurrency", translate("xudpConcurrency"))
o.description = translate(
"<ul>"
.. "<li>" .. translate("Default:16. When entering a negative number, such as -1, The Mux module will not be used to carry UDP traffic, Use original UDP transmission method of proxy protocol.") .. "</li>"
.. "<li>" .. translate("Min value is 1, Max value is 1024. When omitted or set to 0, Will same path as TCP traffic.") .. "</li>"
.. "</ul>")
o.rmempty = true
o.default = "16"
o:value("-1", translate("disable"))
o:value("16", translate("16"))
o:depends("mux", true)
o:depends("xmux", true)
-- [[ 对被代理的 UDP/443 流量处理方式 ]]--
o = s:option(ListValue, "xudpProxyUDP443", translate("xudpProxyUDP443"))
o.description = translate(
"<ul>"
.. "<li>" .. translate("Default reject rejects traffic.") .. "</li>"
.. "<li>" .. translate("allow: Allows use Mux connection.") .. "</li>"
.. "<li>" .. translate("skip: Not use Mux module to carry UDP 443 traffic, Use original UDP transmission method of proxy protocol.") .. "</li>"
.. "</ul>")
o.rmempty = true
o.default = "reject"
o:value("reject", translate("reject"))
o:value("allow", translate("allow"))
o:value("skip", translate("skip"))
o:depends("mux", true)
-- [[ XHTTP TCP Fast Open ]]--
o = s:option(Flag, "tcpfastopen", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support."))
o.rmempty = true
o.default = "0"
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"})
-- [[ MPTCP ]]--
o = s:option(Flag, "mptcp", translate("MPTCP"))
o.rmempty = false
o.default = false
o = s:option(Flag, "mptcp", translate("MPTCP"), translate("Enable Multipath TCP, need to be enabled in both server and client configuration."))
o.rmempty = true
o.default = "0"
o:depends({type = "v2ray", v2ray_protocol = "vless"})
o:depends({type = "v2ray", v2ray_protocol = "vmess"})
o:depends({type = "v2ray", v2ray_protocol = "trojan"})
@ -1029,7 +1142,7 @@ o:value("/etc/ssl/private/ca.pem")
o.description = translate("Please confirm the current certificate path")
o.default = "/etc/ssl/private/ca.pem"
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
o = s:option(Flag, "fast_open", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support."))
o.rmempty = true
o.default = "0"
o:depends("type", "ssr")

View File

@ -9,17 +9,26 @@ local dsp=require "luci.dispatcher"
//<![CDATA[
window.addEventListener('load',function(){
const doms=document.getElementsByClassName('pingtime');
const ports=document.getElementsByClassName("socket-connected")
const ports = document.getElementsByClassName("socket-connected");
const transports = document.getElementsByClassName("transport");
const wsPaths = document.getElementsByClassName("wsPath");
const tlss = document.getElementsByClassName("tls");
const xhr=(index) =>{
return new Promise((res) =>{
const dom=doms[index];
const port=ports[index];
const transport = transports[index];
const wsPath = wsPaths[index];
const tls = tlss[index];
if (!dom) res()
port.innerHTML='<font style=\"color:#0072c3\"><%:connecting%></font>';
XHR.get('<%=dsp.build_url("admin/services/bypass/ping")%>',{
index,
domain: dom.getAttribute("hint"),
port: port.getAttribute("hint")
port: port.getAttribute("hint"),
transport: transport.getAttribute("hint"),
wsPath: wsPath.getAttribute("hint"),
tls: tls.getAttribute("hint")
},
(x,result) =>{
let col='#ff0000';
@ -27,27 +36,29 @@ local dsp=require "luci.dispatcher"
if (result.ping < 300) col='#ff3300';
if (result.ping < 200) col='#ff7700';
if (result.ping < 100) col='#249400';
}
dom.innerHTML = `<font style=\"color:${col}\">${(result.ping ? result.ping : "--") + " ms"}</font>`;
if (result.socket) {
port.innerHTML='<font style=\"color:#249400\"><%:ok%></font>'
}else{
port.innerHTML='<font style=\"color:#ff0000\"><%:fail%></font>'
}
dom.innerHTML =`<font style=\"${col}\">${(result.ping?result.ping:"--")+" ms"}</font>`
res();
});
})
}
});
};
let task=-1;
const thread=() =>{
task=task + 1
task = task + 1;
if (doms[task]){
xhr(task).then(thread);
}
}
};
for (let i=0; i < 20; i++){
thread()
thread();
}
})
});
function cbi_row_drop(fromId,toId,store,isToBottom){
var fromNode=document.getElementById(fromId);

View File

@ -1,3 +1,6 @@
<%+cbi/valueheader%>
<span class="socket-connected" hint="<%=self:cfgvalue(section)%>"><%:None%></span>
<span class="socket-connected" hint="<%=self:cfgvalue(section)%>">wait</span>
<span class="transport" hint="<%=self.transport%>"></span>
<span class="wsPath" hint="<%=self.ws_path%>"></span>
<span class="tls" hint="<%=self.tls%>"></span>
<%+cbi/valuefooter%>

View File

@ -20,7 +20,23 @@ function b64DecodeUnicode(str) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
// Check if the elements exist before trying to modify them
function setElementValue(name, value) {
const element = document.getElementsByName(name)[0];
if (element) {
if (element.type === "checkbox" || element.type === "radio") {
element.checked = value === true;
} else {
element.value = value;
}
}
}
function dispatchEventIfExists(name, event) {
const element = document.getElementsByName(name)[0];
if (element) {
element.dispatchEvent(event);
}
}
function b64decutf8safe(str) {
var l;
str = str.replace(/-/g, "+").replace(/_/g, "/");
@ -518,8 +534,9 @@ function import_ssr_url(btn, urlname, sid) {
case "trojan":
try {
var url = new URL("http://" + ssu[1]);
var params = url.searchParams;
} catch(e) {
alert(e)
alert(e);
return false;
}
@ -533,7 +550,77 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.bypass.' + sid + '.password')[0].value = decodeURIComponent(url.username);
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].checked = true;
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].dispatchEvent(event);
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = url.searchParams.get("sni");
document.getElementsByName('cbid.bypass.' + sid + '.fingerprint')[0].value = params.get("fp") || "";
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = params.get("sni");
if (params.get("allowInsecure") === "1") {
document.getElementsByName('cbid.bypass.' + sid + '.insecure')[0].checked = true; // ÉèÖà insecure Ϊ true
document.getElementsByName('cbid.bypass.' + sid + '.insecure')[0].dispatchEvent(event); // ´¥·¢Ê¼þ
}
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].value =
params.get("type") == "http" ? "h2" :
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
(params.get("type") || "raw"));
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].dispatchEvent(event);
switch (params.get("type")) {
case "ws":
if (params.get("security") !== "tls") {
setElementValue('cbid.bypass.' + sid + '.ws_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
}
setElementValue('cbid.bypass.' + sid + '.ws_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
break;
case "httpupgrade":
if (params.get("security") !== "tls") {
document.getElementsByName('cbid.bypass.' + sid + '.httpupgrade_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
}
document.getElementsByName('cbid.bypass.' + sid + '.httpupgrade_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
break;
case "splithttp":
if (params.get("security") !== "tls") {
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
}
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
break;
case "xhttp":
if (params.get("security") !== "tls") {
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
}
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_mode')[0].value = params.get("mode") || "auto";
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
if (params.get("extra") && params.get("extra").trim() !== "") {
document.getElementsByName('cbid.bypass.' + sid + '.enable_xhttp_extra')[0].checked = true; // ÉèÖà enable_xhttp_extra Ϊ true
document.getElementsByName('cbid.bypass.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // ´¥·¢Ê¼þ
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_extra')[0].value = params.get("extra") || "";
}
break;
case "kcp":
document.getElementsByName('cbid.bypass.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.bypass.' + sid + '.seed')[0].value = params.get("seed") || "";
break;
case "http":
/* this is non-standard, bullshit */
case "h2":
document.getElementsByName('cbid.bypass.' + sid + '.h2_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.bypass.' + sid + '.h2_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
break;
case "quic":
document.getElementsByName('cbid.bypass.' + sid + '.quic_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.bypass.' + sid + '.quic_security')[0].value = params.get("quicSecurity") || "none";
document.getElementsByName('cbid.bypass.' + sid + '.quic_key')[0].value = params.get("key") || "";
break;
case "grpc":
document.getElementsByName('cbid.bypass.' + sid + '.serviceName')[0].value = params.get("serviceName") || "";
document.getElementsByName('cbid.bypass.' + sid + '.grpc_mode')[0].value = params.get("mode") || "gun";
break;
case "raw":
case "tcp":
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].dispatchEvent(event);
if (params.get("headerType") === "http") {
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
}
break;
}
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false;
@ -556,10 +643,11 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.bypass.' + sid + '.alter_id')[0].value = ssm.aid;
document.getElementsByName('cbid.bypass.' + sid + '.vmess_id')[0].value = ssm.id;
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].value = ssm.net;
(ssm.net === "raw" || ssm.net === "tcp") ? "raw" : ssm.net;
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].dispatchEvent(event);
if (ssm.net == "tcp") {
if (ssm.net === "raw" || ssm.net === "tcp") {
if (ssm.type && ssm.type != "http") {
ssm.type = "none"
ssm.type = "none";
} else {
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = ssm.host;
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = ssm.path;
@ -579,6 +667,16 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_host')[0].value = ssm.host;
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_path')[0].value = ssm.path;
}
if (ssm.net == "xhttp") {
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_mode')[0].value = ssm.mode;
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_host')[0].value = ssm.host;
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_path')[0].value = ssm.path;
if (params.get("extra") && params.get("extra").trim() !== "") {
document.getElementsByName('cbid.bypass.' + sid + '.enable_xhttp_extra')[0].checked = true; // ÉèÖà enable_xhttp_extra Ϊ true
document.getElementsByName('cbid.bypass.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // ´¥·¢Ê¼þ
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_extra')[0].value = ssm.extra;
}
}
if (ssm.net == "h2") {
document.getElementsByName('cbid.bypass.' + sid + '.h2_host')[0].value = ssm.host;
document.getElementsByName('cbid.bypass.' + sid + '.h2_path')[0].value = ssm.path;
@ -593,10 +691,20 @@ function import_ssr_url(btn, urlname, sid) {
if (ssm.tls == "tls") {
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].checked = true;
document.getElementsByName('cbid.bypass.' + sid + '.tls')[0].dispatchEvent(event);
document.getElementsByName('cbid.bypass.' + sid + '.fingerprint')[0].value = ssm.fp;
if (ssm.net == "xhttp") {
document.getElementsByName('cbid.bypass.' + sid + '.xhttp_alpn')[0].value = ssm.alpn;
}
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = ssm.sni || ssm.host;
}
if (ssm.mux !== undefined) {
document.getElementsByName('cbid.bypass.' + sid + '.mux')[0].checked = true;
document.getElementsByName('cbid.bypass.' + sid + '.mux')[0].dispatchEvent(event);
}
if (ssm.xmux !== undefined) {
document.getElementsByName('cbid.bypass.' + sid + '.xmux')[0].checked = true;
document.getElementsByName('cbid.bypass.' + sid + '.xmux')[0].dispatchEvent(event);
}
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false;
@ -605,89 +713,99 @@ function import_ssr_url(btn, urlname, sid) {
var url = new URL("http://" + ssu[1]);
var params = url.searchParams;
} catch(e) {
alert(e)
alert(e);
return false;
}
document.getElementsByName('cbid.bypass.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].value = "v2ray";
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.bypass.' + sid + '.v2ray_protocol')[0].value = "vless";
document.getElementsByName('cbid.bypass.' + sid + '.v2ray_protocol')[0].dispatchEvent(event);
document.getElementsByName('cbid.bypass.' + sid + '.server')[0].value = url.hostname;
document.getElementsByName('cbid.bypass.' + sid + '.server_port')[0].value = url.port || "80";
document.getElementsByName('cbid.bypass.' + sid + '.vmess_id')[0].value = url.username;
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].value =
params.get("type") == "http" ? "h2" :
(params.get("type") == "raw" ? "raw" :
(params.get("type") || "tcp"));
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].dispatchEvent(event);
document.getElementsByName('cbid.bypass.' + sid + '.vless_encryption')[0].value = params.get("encryption") || "none";
setElementValue('cbid.bypass.' + sid + '.alias', url.hash ? decodeURIComponent(url.hash.slice(1)) : "");
setElementValue('cbid.bypass.' + sid + '.type', "v2ray");
dispatchEventIfExists('cbid.bypass.' + sid + '.type', event);
setElementValue('cbid.bypass.' + sid + '.v2ray_protocol', "vless");
dispatchEventIfExists('cbid.bypass.' + sid + '.v2ray_protocol', event);
setElementValue('cbid.bypass.' + sid + '.server', url.hostname);
setElementValue('cbid.bypass.' + sid + '.server_port', url.port || "80");
setElementValue('cbid.bypass.' + sid + '.vmess_id', url.username);
setElementValue('cbid.bypass.' + sid + '.transport',
params.get("type") === "http" ? "h2" :
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
(params.get("type") || "tcp"))
);
dispatchEventIfExists('cbid.bypass.' + sid + '.transport', event);
setElementValue('cbid.bypass.' + sid + '.vless_encryption', params.get("encryption") || "none");
if ([ "tls", "xtls", "reality" ].includes(params.get("security"))) {
document.getElementsByName('cbid.bypass.' + sid + '.' + params.get("security"))[0].checked = true;
document.getElementsByName('cbid.bypass.' + sid + '.' + params.get("security"))[0].dispatchEvent(event);
setElementValue('cbid.bypass.' + sid + '.' + params.get("security"), true);
dispatchEventIfExists('cbid.bypass.' + sid + '.' + params.get("security"), event);
if (params.get("security") === "reality") {
document.getElementsByName('cbid.bypass.' + sid + '.reality_publickey')[0].value = params.get("pbk") ? decodeURIComponent(params.get("pbk")) : "";
document.getElementsByName('cbid.bypass.' + sid + '.reality_shortid')[0].value = params.get("sid") || "";
document.getElementsByName('cbid.bypass.' + sid + '.reality_spiderx')[0].value = params.get("spx") ? decodeURIComponent(params.get("spx")) : "";
setElementValue('cbid.bypass.' + sid + '.reality_publickey', params.get("pbk") ? decodeURIComponent(params.get("pbk")) : "");
setElementValue('cbid.bypass.' + sid + '.reality_shortid', params.get("sid") || "");
setElementValue('cbid.bypass.' + sid + '.reality_spiderx', params.get("spx") ? decodeURIComponent(params.get("spx")) : "");
}
if (params.get("security") === "xtls") {
document.getElementsByName('cbid.bypass.' + sid + '.tls_flow')[0].value = params.get("flow") || "";
document.getElementsByName('cbid.bypass.' + sid + '.tls_flow')[0].dispatchEvent(event);
}
document.getElementsByName('cbid.bypass.' + sid + '.fingerprint')[0].value = params.get("fp") || "";
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = params.get("sni") || "";
setElementValue('cbid.bypass.' + sid + '.tls_flow', params.get("flow") || "none");
dispatchEventIfExists('cbid.bypass.' + sid + '.tls_flow', event);
setElementValue('cbid.bypass.' + sid + '.xhttp_alpn', params.get("alpn") || "");
setElementValue('cbid.bypass.' + sid + '.fingerprint', params.get("fp") || "");
setElementValue('cbid.bypass.' + sid + '.tls_host', params.get("sni") || "");
}
switch (params.get("type")) {
case "ws":
if (params.get("security") !== "tls")
document.getElementsByName('cbid.bypass.' + sid + '.ws_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.bypass.' + sid + '.ws_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
if (params.get("security") !== "tls") {
setElementValue('cbid.bypass.' + sid + '.ws_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
}
setElementValue('cbid.bypass.' + sid + '.ws_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
break;
case "httpupgrade":
if (params.get("security") !== "tls")
document.getElementsByName('cbid.bypass.' + sid + '.httpupgrade_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.bypass.' + sid + '.httpupgrade_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
if (params.get("security") !== "tls") {
setElementValue('cbid.bypass.' + sid + '.httpupgrade_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
}
setElementValue('cbid.bypass.' + sid + '.httpupgrade_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
break;
case "splithttp":
if (params.get("security") !== "tls")
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.bypass.' + sid + '.splithttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
if (params.get("security") !== "tls") {
setElementValue('cbid.bypass.' + sid + '.splithttp_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
}
setElementValue('cbid.bypass.' + sid + '.splithttp_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
break;
case "xhttp":
if (params.get("security") !== "tls") {
setElementValue('cbid.bypass.' + sid + '.xhttp_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
}
setElementValue('cbid.bypass.' + sid + '.xhttp_mode', params.get("mode") || "auto");
setElementValue('cbid.bypass.' + sid + '.xhttp_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
if (params.get("extra") && params.get("extra").trim() !== "") {
setElementValue('cbid.bypass.' + sid + '.enable_xhttp_extra', true); // ÉèÖà enable_xhttp_extra Ϊ true
dispatchEventIfExists('cbid.bypass.' + sid + '.enable_xhttp_extra', event); // ´¥·¢Ê¼þ
setElementValue('cbid.bypass.' + sid + '.xhttp_extra', params.get("extra") || "");
}
break;
case "kcp":
document.getElementsByName('cbid.bypass.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.bypass.' + sid + '.seed')[0].value = params.get("seed") || "";
setElementValue('cbid.bypass.' + sid + '.kcp_guise', params.get("headerType") || "none");
setElementValue('cbid.bypass.' + sid + '.seed', params.get("seed") || "");
break;
case "http":
/* this is non-standard, bullshit */
case "h2":
document.getElementsByName('cbid.bypass.' + sid + '.h2_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.bypass.' + sid + '.h2_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
setElementValue('cbid.bypass.' + sid + '.h2_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
setElementValue('cbid.bypass.' + sid + '.h2_path', params.get("path") ? decodeURIComponent(params.get("path")) : "");
break;
case "quic":
document.getElementsByName('cbid.bypass.' + sid + '.quic_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.bypass.' + sid + '.quic_security')[0].value = params.get("quicSecurity") || "none";
document.getElementsByName('cbid.bypass.' + sid + '.quic_key')[0].value = params.get("key") || "";
setElementValue('cbid.bypass.' + sid + '.quic_guise', params.get("headerType") || "none");
setElementValue('cbid.bypass.' + sid + '.quic_security', params.get("quicSecurity") || "none");
setElementValue('cbid.bypass.' + sid + '.quic_key', params.get("key") || "");
break;
case "grpc":
document.getElementsByName('cbid.bypass.' + sid + '.serviceName')[0].value = params.get("serviceName") || "";
document.getElementsByName('cbid.bypass.' + sid + '.grpc_mode')[0].value = params.get("mode") || "gun";
setElementValue('cbid.bypass.' + sid + '.serviceName', params.get("serviceName") || "");
setElementValue('cbid.bypass.' + sid + '.grpc_mode', params.get("mode") || "gun");
break;
case "tcp":
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].dispatchEvent(event);
if (params.get("headerType") === "http") {
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
}
case "raw":
document.getElementsByName('cbid.bypass.' + sid + '.raw_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.bypass.' + sid + '.raw_guise')[0].dispatchEvent(event);
setElementValue('cbid.bypass.' + sid + '.tcp_guise', params.get("headerType") || "none");
dispatchEventIfExists('cbid.bypass.' + sid + '.tcp_guise', event);
if (params.get("headerType") === "http") {
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
setElementValue('cbid.bypass.' + sid + '.http_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
setElementValue('cbid.bypass.' + sid + '.http_path', params.get("path") ? decodeURIComponent(params.get("path")) : "");
}
break;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -32,11 +32,11 @@ config access_control
config server_global
config global_rules
option ad_url 'https://github.com/sirpdboy/iplist/releases/latest/download/ad_list.txt'
option gfwlist_url 'https://github.com/sirpdboy/iplist/releases/latest/download/gfwlist.txt'
option chnroute_url 'https://github.com/sirpdboy/iplist/releases/latest/download/all_cn.txt'
option chnroute6_url 'https://github.com/sirpdboy/iplist/releases/latest/download/all_cn_ipv6.txt'
option domains_url 'https://github.com/sirpdboy/iplist/releases/latest/download/domains_cn.txt'
option ad_url 'https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt'
option gfwlist_url 'https://fastly.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt'
option chnroute_url 'https://ispip.clang.cn/all_cn.txt'
option chnroute6_url 'https://ispip.clang.cn/all_cn_ipv6.txt'
option domains_url 'https://fastly.jsdelivr.net/gh/yubanmeiqin9048/domain@release/accelerated-domains.china.txt'
config server_subscribe
option proxy '0'

View File

@ -4,7 +4,7 @@ local ucursor = require "luci.model.uci".cursor()
local json = require "luci.jsonc"
local server_section = arg[1]
local proto = arg[2]
local proto = arg[2] or "tcp"
local local_port = arg[3] or "0"
local socks_port = arg[4] or "0"
local chain = arg[5] or "0"
@ -178,12 +178,12 @@ if local_port ~= "0" then
end
-- 开启 socks 代理
-- 检查是否启用 socks 代理
if proto:find("tcp") and socks_port ~= "0" then
if proto and proto:find("tcp") and socks_port ~= "0" then
table.insert(Xray.inbounds, {
-- socks
protocol = "socks",
port = tonumber(socks_port),
settings = {
settings = (socks_server.server ~= "same") and {
auth = socks_server.socks5_auth,
udp = true,
mixed = (socks_server.socks5_mixed == '1') and true or false,
@ -193,7 +193,7 @@ if proto:find("tcp") and socks_port ~= "0" then
pass = socks_server.socks5_pass
}
} or nil
}
} or nil
})
end
-- 传出连接
@ -207,7 +207,7 @@ end
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil,
tlsSettings = (server.tls == '1') and {
-- tls
alpn = server.tls_alpn,
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or server.tls_alpn,
fingerprint = server.fingerprint,
allowInsecure = (server.insecure == "1"),
serverName = server.tls_host,
@ -223,6 +223,7 @@ end
minVersion = "1.3"
} or nil,
realitySettings = (server.reality == '1') and {
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or nil,
publicKey = server.reality_publickey,
shortId = server.reality_shortid,
spiderX = server.reality_spiderx,
@ -269,6 +270,20 @@ end
host = (server.splithttp_host or server.tls_host) or nil,
path = server.splithttp_path or "/"
} or nil,
xhttpSettings = (server.transport == "xhttp") and {
-- xhttp
mode = server.xhttp_mode or "auto",
host = (server.xhttp_host or server.tls_host) or nil,
path = server.xhttp_path or "/",
extra = (server.enable_xhttp_extra == "1" and server.xhttp_extra) and (function()
local success, parsed = pcall(json.parse, server.xhttp_extra)
if success then
return parsed.extra or parsed
else
return nil
end
end)() or nil
} or nil,
httpSettings = (server.transport == "h2") and {
-- h2
path = server.h2_path or "",
@ -293,18 +308,19 @@ end
} or nil,
sockopt = {
mark = 250,
tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and "dialerproxy" or nil
}
} or nil,
mux = (server.v2ray_protocol ~= "wireguard") and {
-- mux
enabled = (server.mux == "1") and true or false, -- Mux
concurrency = tonumber(server.concurrency), -- TCP 最大并发连接数
xudpConcurrency = tonumber(server.xudpConcurrency), -- UDP 最大并发连接数
xudpProxyUDP443 = server.xudpProxyUDP443 -- 对被代理的 UDP/443 流量处理方式
enabled = (server.mux == "1" or server.xmux == "1") and true or false, -- Mux
concurrency = (server.mux == "1" and ((server.concurrency ~= "0") and tonumber(server.concurrency) or 8)) or (server.xmux == "1" and -1) or nil, -- TCP 最大并发连接数
xudpConcurrency = ((server.xudpConcurrency ~= "0") and tonumber(server.xudpConcurrency)) or nil, -- UDP 最大并发连接数
xudpProxyUDP443 = (server.mux == "1") and server.xudpProxyUDP443 or nil -- 对被代理的 UDP/443 流量处理方式
} or nil
}
}
@ -331,8 +347,9 @@ if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.e
streamSettings = {
sockopt = {
mark = 250,
tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法
}
}
@ -584,6 +601,10 @@ function config:handleIndex(index)
hysteria = function()
print(json.stringify(hysteria, 1))
end,
hysteria2 = function()
print(json.stringify(hysteria2, 1))
end,
shadowtls = function()
local chain_switch = {
sslocal = function()

View File

@ -180,12 +180,12 @@ end
-- 开启 socks 代理
-- 检查是否启用 socks 代理
if proto:find("tcp") and socks_port ~= "0" then
if proto and proto:find("tcp") and socks_port ~= "0" then
table.insert(Xray.inbounds, {
-- socks
protocol = "socks",
port = tonumber(socks_port),
settings = {
settings = (socks_server.server ~= "same") and {
auth = socks_server.socks5_auth,
udp = true,
mixed = (socks_server.socks5_mixed == '1') and true or false,
@ -195,7 +195,7 @@ if proto:find("tcp") and socks_port ~= "0" then
pass = socks_server.socks5_pass
}
} or nil
}
} or nil
})
end
@ -210,10 +210,10 @@ end
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil,
tlsSettings = (server.tls == '1') and {
-- tls
alpn = server.tls_alpn,
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or server.tls_alpn,
fingerprint = server.fingerprint,
allowInsecure = (server.insecure == "1"),
serverName = tls_host,
serverName = server.tls_host,
certificates = server.certificate and {
usage = "verify",
certificateFile = server.certpath
@ -226,6 +226,7 @@ end
minVersion = "1.3"
} or nil,
realitySettings = (server.reality == '1') and {
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or nil,
publicKey = server.reality_publickey,
shortId = server.reality_shortid,
spiderX = server.reality_spiderx,
@ -272,6 +273,20 @@ end
host = (server.splithttp_host or server.tls_host) or nil,
path = server.splithttp_path or "/"
} or nil,
xhttpSettings = (server.transport == "xhttp") and {
-- xhttp
mode = server.xhttp_mode or "auto",
host = (server.xhttp_host or server.tls_host) or nil,
path = server.xhttp_path or "/",
extra = (server.enable_xhttp_extra == "1" and server.xhttp_extra) and (function()
local success, parsed = pcall(json.parse, server.xhttp_extra)
if success then
return parsed.extra or parsed
else
return nil
end
end)() or nil
} or nil,
httpSettings = (server.transport == "h2") and {
-- h2
path = server.h2_path or "",
@ -296,18 +311,19 @@ end
} or nil,
sockopt = {
mark = 250,
tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and "dialerproxy" or nil
}
} or nil,
mux = (server.v2ray_protocol ~= "wireguard") and {
-- mux
enabled = (server.mux == "1") and true or false, -- Mux
concurrency = tonumber(server.concurrency), -- TCP 最大并发连接数
xudpConcurrency = tonumber(server.xudpConcurrency), -- UDP 最大并发连接数
xudpProxyUDP443 = server.xudpProxyUDP443 -- 对被代理的 UDP/443 流量处理方式
}
} or nil,
mux = (server.v2ray_protocol ~= "wireguard") and {
-- mux
enabled = (server.mux == "1" or server.xmux == "1") and true or false, -- Mux
concurrency = (server.mux == "1" and ((server.concurrency ~= "0") and tonumber(server.concurrency) or 8)) or (server.xmux == "1" and -1) or nil, -- TCP 最大并发连接数
xudpConcurrency = ((server.xudpConcurrency ~= "0") and tonumber(server.xudpConcurrency)) or nil, -- UDP 最大并发连接数
xudpProxyUDP443 = (server.mux == "1") and server.xudpProxyUDP443 or nil -- 对被代理的 UDP/443 流量处理方式
} or nil
}
}
@ -334,8 +350,9 @@ if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.e
streamSettings = {
sockopt = {
mark = 250,
tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法
}
}

View File

@ -39,7 +39,38 @@ local log = function(...)
io.write(os.date("%Y-%m-%d %H:%M:%S ").."Subscribe : "..table.concat({...}," ").."\n")
io.close(file)
end
local encrypt_methods_ss = {
-- plain
"none",
"plain",
-- 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" ]]
}
-- 分割字符串
local function split(full, sep)
if full then
@ -92,9 +123,10 @@ end
-- base64
local function base64Decode(text)
local raw = text
if not text then return '' end
if not text then
return ''
end
text = text:gsub("%z", "")
text = text:gsub("%c", "")
text = text:gsub("_", "/")
text = text:gsub("-", "+")
local mod4 = #text % 4
@ -119,20 +151,15 @@ end
local function processData(szType, content)
local result = {type = szType, local_port = 1234, kcp_param = '--nocomp'}
if szType == 'ssr' then
result.type = 'ssr'
local dat = split(content, "/%?")
local hostInfo = split(dat[1], ':')
if dat[1]:match('%[(.*)%]') then
result.server = dat[1]:match('%[(.*)%]')
else
result.server = hostInfo[#hostInfo-5]
end
result.server_port = hostInfo[#hostInfo-4]
result.protocol = hostInfo[#hostInfo-3]
result.encrypt_method = hostInfo[#hostInfo-2]
result.obfs = hostInfo[#hostInfo-1]
result.password = base64Decode(hostInfo[#hostInfo])
result.type = 'ssr'
result.server = hostInfo[1]
result.server_port = hostInfo[2]
result.protocol = hostInfo[3]
result.encrypt_method = hostInfo[4]
result.obfs = hostInfo[5]
result.password = base64Decode(hostInfo[6])
local params = {}
for _, v in pairs(split(dat[2], '&')) do
local t = split(v, '=')
@ -148,23 +175,18 @@ local function processData(szType, content)
elseif szType == 'vmess' then
local info = jsonParse(content)
result.type = 'v2ray'
result.alter_id = info.aid
result.v2ray_protocol = 'vmess'
result.server = info.add
result.server_port = info.port
result.v2ray_protocol = 'vmess'
if info.net == "tcp" then
info.net = "raw"
end
result.transport = info.net
result.alter_id = info.aid
result.vmess_id = info.id
result.alias = info.ps
-- result.mux = 1
-- result.concurrency = 8
if not info.net then
info.net = "tcp"
end
info.net = string.lower(info.net)
result.transport = info.net
if info.net == 'ws' then
result.ws_host = info.host
result.ws_path = info.path
@ -177,11 +199,29 @@ local function processData(szType, content)
result.splithttp_host = info.host
result.splithttp_path = info.path
end
if info.net == 'xhttp' then
result.xhttp_mode = info.mode
result.xhttp_host = info.host
result.xhttp_path = info.path
-- 检查 extra 参数是否存在且非空
result.enable_xhttp_extra = (info.extra and info.extra ~= "") and "1" or nil
result.xhttp_extra = (info.extra and info.extra ~= "") and info.extra or nil
-- 尝试解析 JSON 数据
local success, Data = pcall(jsonParse, info.extra)
if success and Data then
local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address)
or (Data.downloadSettings and Data.downloadSettings.address)
result.download_address = address and address ~= "" and address or nil
else
-- 如果解析失败,清空下载地址
result.download_address = nil
end
end
if info.net == 'h2' then
result.h2_host = info.host
result.h2_path = info.path
end
if info.net == 'tcp' then
if info.net == 'raw' or info.net == 'tcp' then
if info.type and info.type ~= "http" then
info.type = "none"
end
@ -189,7 +229,7 @@ local function processData(szType, content)
result.http_host = info.host
result.http_path = info.path
end
if info.net == 'kcp' or info.net == 'mkcp' then
if info.net == 'kcp' then
result.kcp_guise = info.type
result.mtu = 1350
result.tti = 50
@ -213,13 +253,18 @@ local function processData(szType, content)
end
if info.security then
result.security = info.security
else
result.security = "auto"
end
if info.tls == "tls" or info.tls == "1" then
result.tls = "1"
result.tls_host = (info.sni and info.sni ~= "") and info.sni or info.host
result.insecure = insecure and "1" or "0"
if info.alpn and info.alpn ~= "" then
result.xhttp_alpn = info.alpn
end
if info.sni and info.sni ~= "" then
result.tls_host = info.sni
elseif info.host then
result.tls_host = info.host
end
result.insecure = 1
else
result.tls = "0"
end
@ -228,9 +273,6 @@ local function processData(szType, content)
-- result.server = nil
-- end
elseif szType == "ss" then
result.type = v2_ss
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
--userinfo = websafe-base64-encode-utf8(method ":" password)
--ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1
@ -244,11 +286,21 @@ local function processData(szType, content)
idx_sp = content:find("#")
alias = content:sub(idx_sp + 1, -1)
end
result.alias = UrlDecode(alias)
local info = content:sub(1, idx_sp - 1)
if info:find("/%?") then
local find_index = info:find("/%?")
local query = split(info, "/%?")
local hostInfo = split(base64Decode(info), "@")
local host = split(hostInfo[2], ":")
local userinfo = base64Decode(hostInfo[1])
local method = userinfo:sub(1, userinfo:find(":") - 1)
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
result.alias = UrlDecode(alias)
result.type = v2_ss
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
result.encrypt_method_ss = method
result.password = password
result.server = host[1]
if host[2]:find("/%?") then
local query = split(host[2], "/%?")
result.server_port = query[1]
local params = {}
for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=')
@ -263,122 +315,32 @@ local function processData(szType, content)
else
result.plugin = plugin_info
end
end
if result.plugin and result.plugin == "simple-obfs" then
-- 部分机场下发的插件名为 simple-obfs这里应该改为 obfs-local
if result.plugin == "simple-obfs" then
result.plugin = "obfs-local"
end
info = info:sub(1, find_index - 1)
end
else
result.server_port = host[2]:gsub("/","")
end
if not checkTabValue(encrypt_methods_ss)[method] then
-- 1202 年了还不支持 SS AEAD 的屑机场
result.server = nil
end
elseif szType == "sip008" then
result.type = v2_ss
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
result.server = content.server
result.server_port = content.server_port
result.password = content.password
result.encrypt_method_ss = content.method
result.plugin = content.plugin
result.plugin_opts = content.plugin_opts
result.alias = content.remarks
if not checkTabValue(encrypt_methods_ss)[content.method] then
result.server = nil
end
local hostInfo = split(base64Decode(info), "@")
if hostInfo and #hostInfo > 0 then
local host_port = hostInfo[#hostInfo]
-- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
if host_port:find(":") then
local sp = split(host_port, ":")
result.server_port = sp[#sp]
result.server = sp[1]
else
result.server = host_port
end
local userinfo = nil
if #hostInfo > 2 then
userinfo = {}
for i = 1, #hostInfo - 1 do
tinsert(userinfo, hostInfo[i])
end
userinfo = table.concat(userinfo, '@')
else
userinfo = base64Decode(hostInfo[1])
end
local method = userinfo:sub(1, userinfo:find(":") - 1)
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
result.encrypt_method_ss = method
result.password = password
local aead = false
for k, v in ipairs({"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305"}) do
if method:lower() == v:lower() then
aead = true
end
end
if aead then
result.type = v2_ss
result.v2ray_protocol = 'shadowsocks'
result.transport = 'tcp'
if method:lower() == "chacha20-ietf-poly1305" then
result.method = "chacha20-poly1305"
end
end
local aead2022 = false
for k, v in ipairs({"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"}) do
if method:lower() == v:lower() then
aead2022 = true
end
end
if aead2022 then
result.type = v2_ss
result.v2ray_protocol = 'shadowsocks'
result.transport = 'tcp'
end
end
elseif szType == "trojan" then
local alias = ""
if content:find("#") then
local idx_sp = content:find("#")
alias = content:sub(idx_sp + 1, -1)
content = content:sub(0, idx_sp - 1)
end
result.alias = UrlDecode(alias)
result.type = "trojan"
if content:find("@") then
local Info = split(content, "@")
result.password = UrlDecode(Info[1])
local port = "443"
Info[2] = (Info[2] or ""):gsub("/%?", "?")
local query = split(Info[2], "?")
local host_port = query[1]
local params = {}
for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=')
params[string.lower(t[1])] = UrlDecode(t[2])
end
if host_port:find(":") then
local sp = split(host_port, ":")
port = sp[#sp]
result.server = sp[1]
else
result.server = host_port
end
local peer, sni = nil, ""
if params.peer then peer = params.peer end
sni = params.sni and params.sni or ""
result.server_port = port
result.tls = '1'
result.tls_host = peer and peer or sni
if params.allowinsecure then
if params.allowinsecure == "1" or params.allowinsecure == "0" then
result.insecure = params.allowinsecure
else
result.insecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
end
--log(result.alias .. ' 使用节点AllowInsecure设定: '.. result.insecure)
else
-- 按照官方的建议 默认验证ssl证书
result.insecure = insecure and "1" or "0"
end
end
elseif szType == "ssd" then
result.type = v2_ss
@ -386,8 +348,7 @@ local function processData(szType, content)
result.server = content.server
result.server_port = content.port
result.password = content.password
result.encrypt_method_ss = content.encryption
result.plugin = content.plugin
result.encrypt_method_ss = content.method
result.plugin_opts = content.plugin_options
result.alias = "[" .. content.airport .. "] " .. content.remarks
if content.plugin == "simple-obfs" then
@ -395,45 +356,142 @@ local function processData(szType, content)
else
result.plugin = content.plugin
end
elseif szType == "vless" then
result.type = "v2ray"
result.v2ray_protocol = "vless"
if not checkTabValue(encrypt_methods_ss)[content.encryption] then
result.server = nil
end
elseif szType == "trojan" then
local params = {}
local idx_sp = 0
local alias = ""
if content:find("#") then
local idx_sp = content:find("#")
idx_sp = content:find("#")
alias = content:sub(idx_sp + 1, -1)
content = content:sub(0, idx_sp - 1)
end
local info = content:sub(1, idx_sp - 1)
local hostInfo = split(info, "@")
local userinfo = hostInfo[1]
local password = userinfo
-- 分离服务器地址和端口
local host = split(hostInfo[2], ":")
local server = host[1]
local port = host[2]
result.alias = UrlDecode(alias)
if content:find("@") then
local Info = split(content, "@")
result.vmess_id = UrlDecode(Info[1])
local port = "443"
Info[2] = (Info[2] or ""):gsub("/%?", "?")
local query = split(Info[2], "?")
local host_port = query[1]
local params = {}
result.type = v2_tj
result.v2ray_protocol = "trojan"
result.server = server
result.password = password
-- 按照官方的建议 默认验证ssl证书
result.insecure = "0"
result.tls = "1"
if port:find("?") then
local query = split(port, "?")
result.server_port = query[1]
for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=')
params[t[1]] = UrlDecode(t[2])
params[t[1]] = t[2]
end
-- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
if host_port:find(":") then
local sp = split(host_port, ":")
port = sp[#sp]
result.server = sp[1]
else
result.server = host_port
if params.alpn then
-- 处理 alpn 参数
result.xhttp_alpn = params.alpn
end
if params.sni then
-- 未指定peersni默认使用remote addr
result.tls_host = params.sni
end
if params.allowInsecure then
-- 处理 insecure 参数
result.insecure = params.allowInsecure
end
else
result.server_port = port
end
if v2_tj ~= "trojan" then
if params.fp then
-- 处理 fingerprint 参数
result.fingerprint = params.fp
end
-- 处理传输协议
result.transport = params.type or "tcp" -- 默认传输协议为 tcp
if result.transport == "tcp" then
result.transport = "raw"
end
if result.transport == "ws" then
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
result.ws_path = params.path and UrlDecode(params.path) or "/"
elseif result.transport == "httpupgrade" then
result.httpupgrade_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
result.httpupgrade_path = params.path and UrlDecode(params.path) or "/"
elseif result.transport == "splithttp" then
result.splithttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
result.splithttp_path = params.path and UrlDecode(params.path) or "/"
elseif result.transport == "xhttp" then
result.xhttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
result.xhttp_mode = params.mode or "auto"
result.xhttp_path = params.path and UrlDecode(params.path) or "/"
-- 检查 extra 参数是否存在且非空
result.enable_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil
result.xhttp_extra = (params.extra and params.extra ~= "") and params.extra or nil
-- 尝试解析 JSON 数据
local success, Data = pcall(jsonParse, params.extra)
if success and Data then
local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address)
or (Data.downloadSettings and Data.downloadSettings.address)
result.download_address = address and address ~= "" and address or nil
else
-- 如果解析失败,清空下载地址
result.download_address = nil
end
elseif result.transport == "http" or result.transport == "h2" then
result.transport = "h2"
result.h2_host = params.host and UrlDecode(params.host) or nil
result.h2_path = params.path and UrlDecode(params.path) or nil
elseif result.transport == "kcp" then
result.kcp_guise = params.headerType or "none"
result.seed = params.seed
result.mtu = 1350
result.tti = 50
result.uplink_capacity = 5
result.downlink_capacity = 20
result.read_buffer_size = 2
result.write_buffer_size = 2
elseif result.transport == "quic" then
result.quic_guise = params.headerType or "none"
result.quic_security = params.quicSecurity or "none"
result.quic_key = params.key
elseif result.transport == "grpc" then
result.serviceName = params.serviceName
result.grpc_mode = params.mode or "gun"
elseif result.transport == "tcp" or result.transport == "raw" then
result.tcp_guise = params.headerType and params.headerType ~= "" and params.headerType or "none"
if result.tcp_guise == "http" then
result.tcp_host = params.host and UrlDecode(params.host) or nil
result.tcp_path = params.path and UrlDecode(params.path) or nil
end
end
end
if not params.type then
params.type = "tcp"
end
params.type = string.lower(params.type)
result.transport = params.type
if params.type == 'ws' then
elseif szType == "vless" then
local url = URL.parse("http://" .. content)
local params = url.query
result.alias = url.fragment and UrlDecode(url.fragment) or nil
result.type = "v2ray"
result.v2ray_protocol = "vless"
result.server = url.host
result.server_port = url.port
result.vmess_id = url.user
result.vless_encryption = params.encryption or "none"
result.transport = params.type or "tcp"
result.tls = (params.security == "tls" or params.security == "xtls") and "1" or "0"
result.xhttp_alpn = params.alpn or ""
result.tls_host = params.sni
result.tls_flow = (params.security == "tls" or params.security == "reality") and params.flow or nil
result.fingerprint = params.fp
result.reality = (params.security == "reality") and "1" or "0"
result.reality_publickey = params.pbk and UrlDecode(params.pbk) or nil
result.reality_shortid = params.sid
result.reality_spiderx = params.spx and UrlDecode(params.spx) or nil
if result.transport == "ws" then
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
result.ws_path = params.path and UrlDecode(params.path) or "/"
@ -443,60 +501,51 @@ local function processData(szType, content)
elseif result.transport == "splithttp" then
result.splithttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
result.splithttp_path = params.path and UrlDecode(params.path) or "/"
elseif result.transport == "xhttp" then
result.xhttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
result.xhttp_mode = params.mode or "auto"
result.xhttp_path = params.path and UrlDecode(params.path) or "/"
-- 检查 extra 参数是否存在且非空
result.enable_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil
result.xhttp_extra = (params.extra and params.extra ~= "") and params.extra or nil
-- 尝试解析 JSON 数据
local success, Data = pcall(jsonParse, params.extra)
if success and Data then
local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address)
or (Data.downloadSettings and Data.downloadSettings.address)
result.download_address = address and address ~= "" and address or nil
else
-- 如果解析失败,清空下载地址
result.download_address = nil
end
-- make it compatible with bullshit, "h2" transport is non-existent at all
elseif result.transport == "http" or result.transport == "h2" then
result.transport = "h2"
result.h2_host = params.host and UrlDecode(params.host) or nil
result.h2_path = params.path and UrlDecode(params.path) or nil
elseif params.type == 'tcp' then
result.tcp_guise = params.headerType or "none"
if result.tcp_guise == "http" then
elseif result.transport == "kcp" then
result.kcp_guise = params.headerType or "none"
result.seed = params.seed
result.mtu = 1350
result.tti = 50
result.uplink_capacity = 5
result.downlink_capacity = 20
result.read_buffer_size = 2
result.write_buffer_size = 2
elseif result.transport == "quic" then
result.quic_guise = params.headerType or "none"
result.quic_security = params.quicSecurity or "none"
result.quic_key = params.key
elseif result.transport == "grpc" then
result.serviceName = params.serviceName
result.grpc_mode = params.mode or "gun"
elseif result.transport == "tcp" or result.transport == "raw" then
result.tcp_guise = params.headerType or "none"
if result.tcp_guise == "http" then
result.tcp_host = params.host and UrlDecode(params.host) or nil
result.tcp_path = params.path and UrlDecode(params.path) or nil
end
elseif params.type == 'kcp' or params.type == 'mkcp' then
params.type = "kcp"
result.kcp_guise = params.headerType or "none"
result.mtu = 1350
result.tti = 50
result.uplink_capacity = 5
result.downlink_capacity = 20
result.read_buffer_size = 2
result.write_buffer_size = 2
result.seed = params.seed
elseif params.type == 'quic' then
result.quic_guise = params.headerType or "none"
result.quic_key = params.key
result.quic_security = params.quicSecurity or "none"
elseif params.type == 'grpc' then
if params.path then result.serviceName = params.path end
if params.serviceName then result.serviceName = params.serviceName end
result.grpc_mode = params.mode
end
result.vless_encryption = params.encryption or "none"
result.tls_flow = params.flow or nil
result.tls = "0"
if params.security == "tls" or params.security == "reality" then
result.tls = "1"
result.tls_host = (params.sni and params.sni ~= "") and params.sni or params.host
result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome"
if params.security == "reality" then
result.reality = "1"
result.tls = "0"
result.reality_publickey = params.pbk or nil
result.reality_shortId = params.sid or nil
result.reality_spiderX = params.spx or nil
end
end
result.xtls = (params.security == "xtls") and "1" or nil
result.tls_flow = (result.tls == "1" or result.xtls == "1" or result.reality == "1") and params.flow or nil
result.server_port = port
result.insecure = insecure and "1" or "0"
end
elseif szType == 'hysteria' then
local alias = ""