mirror of
https://github.com/kenzok8/openwrt-packages.git
synced 2025-01-08 11:37:36 +08:00
update 2022-07-07 20:18:42
This commit is contained in:
parent
395f5b23ac
commit
da8965e832
@ -14,13 +14,13 @@ PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan-Go \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Socks5_Proxy \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Socks_Server
|
||||
|
||||
LUCI_TITLE:=SS/SSR/Xray/Trojan/Trojan-Go/NaiveProxy/Socks5/Tun LuCI interface
|
||||
LUCI_TITLE:=SS/SSR/Xray/Trojan/NaiveProxy/Socks5/Tun LuCI interface
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+ipset +kmod-ipt-nat +ip-full +iptables-mod-tproxy +dnsmasq-full +smartdns +coreutils +coreutils-base64 +curl +tcping +chinadns-ng +lua +luci-compat +unzip +lua-maxminddb \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Server:shadowsocks-libev-ss-server \
|
||||
@ -33,9 +33,9 @@ LUCI_DEPENDS:=+ipset +kmod-ipt-nat +ip-full +iptables-mod-tproxy +dnsmasq-full +
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin:v2ray-plugin \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan-plus \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan-Go:trojan-go \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria:hysteria \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Socks5_Proxy:redsocks2 \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Socks_Server:microsocks
|
||||
|
||||
@ -43,7 +43,7 @@ define Package/$(PKG_NAME)/config
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client
|
||||
bool "Include Shadowsocks Libev Client"
|
||||
default y
|
||||
default y if i386||x86_64||arm
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Server
|
||||
bool "Include Shadowsocks Libev Server"
|
||||
@ -59,7 +59,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs
|
||||
bool "Include Shadowsocks Simple Obfs Plugin"
|
||||
default y
|
||||
default y if i386||x86_64||arm
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin
|
||||
bool "Include Shadowsocks V2ray Plugin"
|
||||
@ -71,10 +71,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Xray
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
|
||||
bool "Include Trojan"
|
||||
default y
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan-Go
|
||||
bool "Include Trojan Go"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy
|
||||
@ -86,9 +82,13 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
|
||||
bool "Include Kcptun"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria
|
||||
bool "Include Hysteria"
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Socks5_Proxy
|
||||
bool "Include Socks5 Transparent Proxy"
|
||||
default y
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Socks_Server
|
||||
bool "Include Socks Sever"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@ uci:foreach(bypass,"servers",function(s)
|
||||
server_count=server_count+1
|
||||
end)
|
||||
|
||||
m=Map(bypass,translate("Servers subscription and manage"),translate("Support SS/SSR/XRAY/TROJAN/TROJAN-GO/NAIVEPROXY/SOCKS5/TUN etc."))
|
||||
m=Map(bypass,translate("Servers subscription and manage"),translate("Support SS/SSR/XRAY/TROJAN/NAIVEPROXY/SOCKS5/TUN etc."))
|
||||
s=m:section(TypedSection,"server_subscribe")
|
||||
s.anonymous=true
|
||||
|
||||
|
@ -1,179 +0,0 @@
|
||||
module("luci.model.cbi.bypass.trojan_go", package.seeall)
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local util = require "luci.util"
|
||||
local i18n = require "luci.i18n"
|
||||
local api = require "luci.model.cbi.bypass.api"
|
||||
|
||||
local trojan_go_api = "https://api.github.com/repos/p4gefau1t/trojan-go/releases?per_page=1"
|
||||
|
||||
function to_check(arch)
|
||||
local app_path = api.get_trojan_go_path() or ""
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "Trojan-GO")
|
||||
}
|
||||
end
|
||||
if not arch or arch == "" then arch = api.auto_get_arch() end
|
||||
|
||||
local file_tree, sub_version = api.get_file_info(arch)
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Can't determine ARCH, or ARCH not supported.")
|
||||
}
|
||||
end
|
||||
|
||||
if file_tree == "mips" then file_tree = "mips%-hardfloat" end
|
||||
if file_tree == "mipsle" then file_tree = "mipsle%-hardfloat" end
|
||||
if file_tree == "arm64" then
|
||||
file_tree = "armv8"
|
||||
else
|
||||
if sub_version and sub_version:match("^[5-8]$") then file_tree = file_tree .. "v" .. sub_version end
|
||||
end
|
||||
|
||||
local json = api.get_api_json(trojan_go_api)
|
||||
|
||||
if #json > 0 then
|
||||
json = json[1]
|
||||
end
|
||||
|
||||
if json.tag_name == nil then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Get remote version info failed.")
|
||||
}
|
||||
end
|
||||
|
||||
local now_version = api.get_trojan_go_version()
|
||||
local remote_version = json.tag_name
|
||||
local needs_update = api.compare_versions(now_version:match("[^v]+"), "<", remote_version:match("[^v]+"))
|
||||
local html_url, download_url
|
||||
|
||||
if needs_update then
|
||||
html_url = json.html_url
|
||||
for _, v in ipairs(json.assets) do
|
||||
if v.name and v.name:match("linux%-" .. file_tree .. "%.zip") then
|
||||
download_url = v.browser_download_url
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if needs_update and not download_url then
|
||||
return {
|
||||
code = 1,
|
||||
now_version = now_version,
|
||||
version = remote_version,
|
||||
html_url = html_url,
|
||||
error = i18n.translate("New version found, but failed to get new version download url.") .. " [linux-" .. file_tree .. ".zip]"
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
code = 0,
|
||||
update = needs_update,
|
||||
now_version = now_version,
|
||||
version = remote_version,
|
||||
url = {html = html_url, download = download_url}
|
||||
}
|
||||
end
|
||||
|
||||
function to_download(url)
|
||||
local app_path = api.get_trojan_go_path() or ""
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "Trojan-GO")
|
||||
}
|
||||
end
|
||||
if not url or url == "" then
|
||||
return {code = 1, error = i18n.translate("Download url is required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/trojan-go_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t trojan-go_download.XXXXXX"))
|
||||
|
||||
local result = api.exec(api.curl, {api._unpack(api.curl_args), "-o", tmp_file, url}, nil, api.command_timeout) == 0
|
||||
|
||||
if not result then
|
||||
api.exec("/bin/rm", {"-f", tmp_file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {code = 0, file = tmp_file}
|
||||
end
|
||||
|
||||
function to_extract(file, subfix)
|
||||
local app_path = api.get_trojan_go_path() or ""
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "Trojan-GO")
|
||||
}
|
||||
end
|
||||
if sys.exec("echo -n $(opkg list-installed | grep -c unzip)") ~= "1" then
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Not installed unzip, Can't unzip!")
|
||||
}
|
||||
end
|
||||
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
return {code = 1, error = i18n.translate("File path required.")}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/trojan-go_extract.*")
|
||||
local tmp_dir = util.trim(util.exec("mktemp -d -t trojan-go_extract.XXXXXX"))
|
||||
|
||||
local output = {}
|
||||
api.exec("/usr/bin/unzip", {"-o", file, "-d", tmp_dir},
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
api.exec("/bin/rm", {"-f", file})
|
||||
|
||||
return {code = 0, file = tmp_dir}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
local app_path = api.get_trojan_go_path() or ""
|
||||
if app_path == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", "Trojan-GO")
|
||||
}
|
||||
end
|
||||
if not file or file == "" then
|
||||
sys.call("/bin/rm -rf /tmp/trojan-go_extract.*")
|
||||
return {code = 1, error = i18n.translate("Client file is required.")}
|
||||
end
|
||||
|
||||
local app_path_bak
|
||||
|
||||
if fs.access(app_path) then
|
||||
app_path_bak = app_path .. ".bak"
|
||||
api.exec("/bin/mv", {"-f", app_path, app_path_bak})
|
||||
end
|
||||
|
||||
local result = api.exec("/bin/mv", { "-f", file .. "/trojan-go", app_path }, nil, api.command_timeout) == 0
|
||||
sys.call("/bin/rm -rf /tmp/trojan-go_extract.*")
|
||||
if not result or not fs.access(app_path) then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s", app_path)
|
||||
}
|
||||
end
|
||||
|
||||
api.exec("/bin/chmod", {"-R", "755", app_path})
|
||||
|
||||
return {code = 0}
|
||||
end
|
@ -1,831 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<%
|
||||
local api = require "luci.model.cbi.bypass.api"
|
||||
-%>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
function padright(str, cnt, pad) {
|
||||
return str + Array(cnt + 1).join(pad);
|
||||
}
|
||||
|
||||
function b64EncodeUnicode(str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
}));
|
||||
}
|
||||
|
||||
function b64encutf8safe(str) {
|
||||
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
|
||||
}
|
||||
|
||||
function b64DecodeUnicode(str) {
|
||||
return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
|
||||
function b64decutf8safe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return b64DecodeUnicode(str);
|
||||
}
|
||||
|
||||
function b64encsafe(str) {
|
||||
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
|
||||
}
|
||||
|
||||
function b64decsafe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l)
|
||||
str = padright(str, l, "=");
|
||||
return atob(str);
|
||||
}
|
||||
|
||||
function dictvalue(d, key) {
|
||||
var v = d[key];
|
||||
if (typeof(v) === 'undefined' || v === '')
|
||||
return '';
|
||||
return b64decsafe(v);
|
||||
}
|
||||
function parseNodeUrl(url) {
|
||||
var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*)([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/),
|
||||
r = {
|
||||
hash: m[10] || "", // #asd
|
||||
host: m[3] || "", // localhost:257
|
||||
hostname: m[6] || "", // localhost
|
||||
href: m[0] || "", // http://username:password@localhost:257/deploy/?asd=asd#asd
|
||||
origin: m[1] || "", // http://username:password@localhost:257
|
||||
pathname: m[8] || (m[1] ? "/" : ""), // /deploy/
|
||||
port: m[7] || "", // 257
|
||||
protocol: m[2] || "", // http:
|
||||
search: m[9] || "", // ?asd=asd
|
||||
passwd: m[4] || "", // username
|
||||
removed: m[5] || "" // password
|
||||
};
|
||||
if (r.protocol.length === 2) {
|
||||
r.protocol = "file:///" + r.protocol.toUpperCase();
|
||||
r.origin = r.protocol + "//" + r.host;
|
||||
}
|
||||
r.href = r.origin + r.pathname + r.search + r.hash;
|
||||
return m && r;
|
||||
}
|
||||
|
||||
function buildUrl(btn, urlname, sid) {
|
||||
var opt = {
|
||||
base: "cbid.bypass",
|
||||
client : true,
|
||||
|
||||
get: function(opt) {
|
||||
var id = this.base + "." + opt;
|
||||
var obj = document.getElementsByName(id)[0] || document.getElementsByClassName(id)[0] || document.getElementById(id)
|
||||
if (obj) {
|
||||
return obj;
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
getlist: function(opt) {
|
||||
var id = this.base + "." + opt;
|
||||
var objs = document.getElementsByName(id) || document.getElementsByClassName(id);
|
||||
var ret = [];
|
||||
if (objs) {
|
||||
for (var i = 0; i < objs.length; i++) {
|
||||
ret[i] = objs[i].value;
|
||||
}
|
||||
} else {
|
||||
alert("<%:Faltal on get option, please help in debug: %>" + opt);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
query: function(param, src, tval = "1", fval = "0") {
|
||||
var ret = "&" + param + "=";
|
||||
var obj = this.get(src);
|
||||
if (obj) {
|
||||
if (obj.type === "checkbox") {
|
||||
return ret + (obj.checked === true ? tval : fval);
|
||||
} else {
|
||||
return ret + encodeURIComponent(obj.value);
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
var s = document.getElementById(urlname + "-status");
|
||||
if (!s) {
|
||||
alert("Never");
|
||||
return false;
|
||||
}
|
||||
opt.base = 'cbid.bypass.' + sid;
|
||||
opt.client = urlname.indexOf("server") === -1;
|
||||
|
||||
var v_type = opt.get("type").value;
|
||||
var v_alias = opt.get("alias");
|
||||
var url = null;
|
||||
if (v_type === "ss") {
|
||||
var v_server = opt.get("server");
|
||||
var v_port = opt.get("server_port");
|
||||
var v_method = opt.get("encrypt_method_ss");
|
||||
var v_password = opt.get("password");
|
||||
|
||||
url = b64encsafe(v_method.value + ":" + v_password.value) + "@" +
|
||||
v_server.value + ":" +
|
||||
v_port.value + "/?";
|
||||
|
||||
var params = "";
|
||||
var v_plugin = opt.get("plugin").value;
|
||||
if (v_plugin && v_plugin != "none") {
|
||||
if (v_plugin == "simple-obfs" || v_plugin == "obfs-local") {
|
||||
v_plugin = "obfs-local";
|
||||
}
|
||||
var v_plugin_opts = opt.get("plugin_opts").value;
|
||||
if (v_plugin_opts && v_plugin_opts != "") {
|
||||
v_plugin += encodeURI(";" + v_plugin_opts);
|
||||
}
|
||||
params += "&plugin=" + encodeURI(v_plugin);
|
||||
}
|
||||
params += "&group="
|
||||
params += "#" + encodeURI(v_alias.value);
|
||||
if (params[0] == "&") {
|
||||
params = params.substring(1);
|
||||
}
|
||||
url += params;
|
||||
} else if (v_type === "ssr") {
|
||||
var v_server = opt.get("server");
|
||||
var v_port = opt.get("server_port");
|
||||
var v_protocol = opt.get("protocol");
|
||||
var v_method = opt.get("encrypt_method");
|
||||
var v_obfs = opt.get("obfs");
|
||||
var v_password = opt.get("password");
|
||||
var v_obfs_param = opt.get("obfs_param");
|
||||
var v_protocol_param = opt.get("protocol_param");
|
||||
var ssr_str = v_server.value + ":" +
|
||||
v_port.value + ":" +
|
||||
v_protocol.value + ":" +
|
||||
v_method.value + ":" +
|
||||
v_obfs.value + ":" +
|
||||
b64encsafe(v_password.value) +
|
||||
"/?obfsparam=" + b64encsafe(v_obfs_param.value) +
|
||||
"&protoparam=" + b64encsafe(v_protocol_param.value) +
|
||||
"&remarks=" + b64encutf8safe(v_alias.value);
|
||||
url = b64encsafe(ssr_str);
|
||||
} else if (v_type === "vmess") {
|
||||
v_type = "vmess";
|
||||
var info = {};
|
||||
info.v = "2";
|
||||
info.ps = v_alias.value;
|
||||
info.add = opt.get("server").value;
|
||||
info.port = opt.get("server_port").value;
|
||||
info.id = opt.get("uuid").value;
|
||||
info.aid = opt.get("alter_id").value;
|
||||
|
||||
var v_transport = opt.get("transport").value;
|
||||
if (v_transport === "ws") {
|
||||
info.host = opt.get("ws_host").value;
|
||||
info.path = opt.get("ws_path").value;
|
||||
} else if (v_transport === "h2") {
|
||||
info.host = opt.get("h2_host").value;
|
||||
info.path = opt.get("h2_path").value;
|
||||
} else if (v_transport === "tcp") {
|
||||
info.type = opt.get("tcp_guise").value;
|
||||
info.host = opt.get("http_host").value;
|
||||
info.path = opt.get("http_path").value;
|
||||
} else if (v_transport === "mkcp") {
|
||||
v_transport = "kcp";
|
||||
info.type = opt.get("kcp_guise").value;
|
||||
} else if (v_transport === "quic") {
|
||||
info.type = opt.get("quic_guise").value;
|
||||
info.key = opt.get("quic_key").value;
|
||||
info.securty = opt.get("quic_security").value;
|
||||
} else if (v_transport === "grpc") {
|
||||
info.path = opt.get("grpc_serviceName").value;
|
||||
}
|
||||
if (info.path && info.path != "") {
|
||||
info.path = encodeURI(info.path);
|
||||
}
|
||||
info.net = v_transport;
|
||||
|
||||
info.security = opt.get("security").value || "auto";
|
||||
if (opt.get("tls").checked) {
|
||||
var v_security = "tls";
|
||||
info.tls = "tls";
|
||||
info.sni = opt.get("tls_host").value;
|
||||
}
|
||||
url = b64EncodeUnicode(JSON.stringify(info));
|
||||
} else if (v_type === "vless") {
|
||||
v_type = "vless";
|
||||
var v_password = opt.get("uuid");
|
||||
var v_server = opt.get("server");
|
||||
var v_port = opt.get("server_port");
|
||||
url = encodeURIComponent(v_password.value) +
|
||||
"@" + v_server.value +
|
||||
":" + v_port.value + "?";
|
||||
|
||||
var params = "";
|
||||
var v_transport = opt.get("transport").value;
|
||||
if (v_transport === "ws") {
|
||||
params += opt.query("host", "ws_host");
|
||||
params += opt.query("path", "ws_path");
|
||||
} else if (v_transport === "h2") {
|
||||
params += opt.query("host", "h2_host");
|
||||
params += opt.query("path", "h2_path");
|
||||
} else if (v_transport === "tcp") {
|
||||
params += opt.query("headerType", "tcp_guise");
|
||||
params += opt.query("host", "http_host");
|
||||
params += opt.query("path", "http_path");
|
||||
} else if (v_transport === "mkcp") {
|
||||
v_transport = "kcp";
|
||||
params += opt.query("headerType", "kcp_guise");
|
||||
} else if (v_transport === "quic") {
|
||||
params += opt.query("headerType", "quic_guise");
|
||||
params += opt.query("key", "quic_key");
|
||||
params += opt.query("quicSecurity", "quic_security");
|
||||
} else if (v_transport === "grpc") {
|
||||
//不知道是用path还是serviceName,这里先这样吧
|
||||
params += opt.query("path", "grpc_serviceName");
|
||||
params += opt.query("serviceName", "grpc_serviceName");
|
||||
}
|
||||
params += "&type=" + v_transport;
|
||||
|
||||
params += opt.query("encryption", "encryption");
|
||||
if (opt.get("tls")) {
|
||||
if (opt.get("tls").checked) {
|
||||
var v_security = "tls";
|
||||
params += "&security=" + v_security;
|
||||
params += opt.query("sni", "tls_host");
|
||||
}
|
||||
}
|
||||
if (opt.get("xtls")) {
|
||||
if (opt.get("xtls").checked) {
|
||||
v_security = "xtls";
|
||||
var v_flow = "xtls-rprx-direct";
|
||||
if (opt.get("vless_flow").value) {
|
||||
v_flow = opt.get("vless_flow").value;
|
||||
}
|
||||
params += "&flow=" + v_flow;
|
||||
params += "&security=" + v_security;
|
||||
params += opt.query("sni", "tls_host");
|
||||
}
|
||||
}
|
||||
params += "#" + encodeURI(v_alias.value);
|
||||
if (params[0] == "&") {
|
||||
params = params.substring(1);
|
||||
}
|
||||
url += params;
|
||||
} else if ((v_type === "xray" && opt.get("protocol").value === "trojan") || v_type === "trojan" || v_type === "trojan" || v_type === "trojan-go") {
|
||||
if (v_type === "xray" && opt.get("protocol").value === "trojan") {
|
||||
v_type = "trojan";
|
||||
}
|
||||
var v_password = opt.get(!opt.client && v_type === "trojan-go" ? "passwords" : "password");
|
||||
var v_server = opt.get("server");
|
||||
var v_port = opt.get("server_port");
|
||||
url = encodeURIComponent(v_password.value) +
|
||||
"@" + v_server.value +
|
||||
":" + v_port.value + "/?";
|
||||
var params = "";
|
||||
if (opt.get("tls").checked) {
|
||||
|
||||
params += opt.query("sni", "tls_host");
|
||||
if (v_type !== "trojan-go") {
|
||||
params += "&tls=1"
|
||||
params += opt.query("allowinsecure", "insecure");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
if (v_type === "trojan-go") {
|
||||
if (!opt.get("tls").checked && opt.get("trojan_transport").value === "original") {
|
||||
var plugin = {};
|
||||
plugin.type = opt.get("plugin_type").value;
|
||||
if (plugin.type !== "plaintext") {
|
||||
plugin.command = opt.get("plugin_cmd").value;
|
||||
plugin.option = opt.get("plugin_option").value;
|
||||
plugin.arg = opt.getlist("plugin_arg");
|
||||
}
|
||||
params += "&plugin=" + encodeURIComponent(JSON.stringify(plugin));
|
||||
}
|
||||
params += opt.query("type", "trojan_transport");
|
||||
var ws = (opt.get("trojan_transport").value.indexOf("ws") !== -1);
|
||||
var h2 = (opt.get("trojan_transport").value.indexOf("h2") !== -1);
|
||||
if (ws) {
|
||||
params += opt.query("host", "ws_host");
|
||||
params += opt.query("path", "ws_path");
|
||||
} else if (h2) {
|
||||
params += opt.query("host", "h2_host");
|
||||
params += opt.query("path", "h2_path");
|
||||
}
|
||||
var enc = "none";
|
||||
if (opt.get("ss_aead").checked === true) {
|
||||
enc = "ss;" +
|
||||
opt.get("ss_aead_method").value +
|
||||
":" + opt.get("ss_aead_pwd").value;
|
||||
}
|
||||
params += "&encryption=" + encodeURIComponent(enc);
|
||||
|
||||
}
|
||||
params += "#" + encodeURI(v_alias.value);
|
||||
if (params[0] == "&") {
|
||||
params = params.substring(1);
|
||||
}
|
||||
url += params;
|
||||
}
|
||||
if (url) {
|
||||
url = v_type.toLowerCase() + "://" + url;
|
||||
var textarea = document.createElement("textarea");
|
||||
textarea.textContent = url;
|
||||
textarea.style.position = "fixed";
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand("copy"); // Security exception may be thrown by some browsers.
|
||||
s.innerHTML = "<font color='green'><%:Share URL to clipboard successfully.%></font>";
|
||||
} catch (ex) {
|
||||
s.innerHTML = "<font color='red'><%:Share URL to clipboard unable.%></font>";
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
//alert(url);
|
||||
} else {
|
||||
alert("<%:Not a supported scheme:%> " + v_type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function fromUrl(btn, urlname, sid) {
|
||||
var opt = {
|
||||
base: 'cbid.bypass',
|
||||
client : true,
|
||||
|
||||
get: function(opt) {
|
||||
var obj;
|
||||
var id = this.base + '.' + opt;
|
||||
obj = document.getElementsByName(id)[0] || document.getElementById(id);
|
||||
if (obj) {
|
||||
return obj;
|
||||
} else {
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
set: function(opt, val) {
|
||||
var obj;
|
||||
obj = this.get(opt)
|
||||
if (obj) {
|
||||
if (obj.type === 'checkbox') {
|
||||
var event = document.createEvent("HTMLEvents");
|
||||
event.initEvent("change", true, true);
|
||||
obj.checked = val;
|
||||
obj.dispatchEvent(event);
|
||||
} else {
|
||||
obj.value = val;
|
||||
}
|
||||
} else {
|
||||
//alert('<%:Faltal on set option, please help in debug: %>' + opt + ' = ' + val);
|
||||
}
|
||||
},
|
||||
setlist: function(opt, vlist) {
|
||||
var id = this.base + "." + opt;
|
||||
var objs = document.getElementsByName(id) || document.getElementsByClassName(id);
|
||||
if (objs) {
|
||||
var values = "";
|
||||
for (var i = 0; i < vlist.length; i++) {
|
||||
values += vlist[i] + ", ";
|
||||
}
|
||||
alert("Manually input the option:\n" + opt + "s:\n[" + values + "]");
|
||||
} else {
|
||||
//alert("<%:Faltal on set option, please help in debug: %>" + opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s) {
|
||||
alert("Never");
|
||||
return false;
|
||||
}
|
||||
opt.base = 'cbid.bypass.' + sid;
|
||||
opt.client = urlname.indexOf("server") === -1;
|
||||
|
||||
var ssrurl = prompt('<%:Paste Share URL Here%>', '');
|
||||
if (ssrurl === null || ssrurl === "") {
|
||||
|
||||
return false;
|
||||
}
|
||||
s.innerHTML = "";
|
||||
var ssu = ssrurl.split('://');
|
||||
var event = document.createEvent("HTMLEvents");
|
||||
event.initEvent("change", true, true);
|
||||
if (ssu[0] === "ssr") {
|
||||
//var b64c = ssu[1].match(/([A-Za-z0-9_-]+)/);
|
||||
var sstr = b64decsafe(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
var url0 = "", param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
} else {
|
||||
var url0 = sstr;
|
||||
}
|
||||
console.log(param);
|
||||
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
|
||||
if (!ssm || ssm.length < 7) {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
|
||||
return false;
|
||||
}
|
||||
var pdict = {};
|
||||
if (param.length > 2) {
|
||||
var a = param.split('&');
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var b = a[i].split('=');
|
||||
pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
|
||||
}
|
||||
}
|
||||
opt.set('type', "ssr");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
opt.set('server', ssm[1]);
|
||||
opt.set('server_port', ssm[2]);
|
||||
opt.set('protocol', ssm[3]);
|
||||
opt.set('encrypt_method', ssm[4]);
|
||||
opt.set('obfs', ssm[5]);
|
||||
opt.set('password', b64decsafe(ssm[6]));
|
||||
opt.set('obfs_param', dictvalue(pdict, 'obfsparam'));
|
||||
opt.set('protocol_param', dictvalue(pdict, 'protoparam'));
|
||||
var rem = pdict['remarks'];
|
||||
if (typeof(rem) !== 'undefined' && rem !== '' && rem.length > 0)
|
||||
opt.set('alias', b64decutf8safe(rem));
|
||||
} else if (ssu[0] === "ss") {
|
||||
var url0 = "", param = "";
|
||||
var sipIndex = ssu[1].indexOf("@");
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1];
|
||||
}
|
||||
|
||||
if (sipIndex !== -1) {
|
||||
// SIP002
|
||||
var userInfo = b64decsafe(url0.substr(0, sipIndex));
|
||||
var temp = url0.substr(sipIndex + 1).split("/?");
|
||||
var serverInfo = temp[0].split(":");
|
||||
var server = serverInfo[0];
|
||||
var port = serverInfo[1];
|
||||
var method, password, plugin, pluginOpts;
|
||||
if (temp[1]) {
|
||||
var pluginInfo = decodeURIComponent(temp[1]);
|
||||
var pluginIndex = pluginInfo.indexOf(";");
|
||||
var pluginNameInfo = pluginInfo.substr(0, pluginIndex);
|
||||
plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1)
|
||||
pluginOpts = pluginInfo.substr(pluginIndex + 1);
|
||||
}
|
||||
var userInfoSplitIndex = userInfo.indexOf(":");
|
||||
if (userInfoSplitIndex !== -1) {
|
||||
method = userInfo.substr(0, userInfoSplitIndex);
|
||||
password = userInfo.substr(userInfoSplitIndex + 1);
|
||||
}
|
||||
opt.set('type', "ss");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
opt.set('server', server);
|
||||
opt.set('server_port', port);
|
||||
opt.set('password', password || "");
|
||||
opt.set('encrypt_method_ss', method || "");
|
||||
opt.set('plugin', plugin || "none");
|
||||
if (plugin && plugin != "none") {
|
||||
opt.get('plugin').dispatchEvent(event);
|
||||
opt.set('plugin_opts', pluginOpts || "");
|
||||
opt.get('plugin_opts').dispatchEvent(event);
|
||||
}
|
||||
if (param !== undefined) {
|
||||
opt.set('alias', decodeURI(param));
|
||||
}
|
||||
} else {
|
||||
var sstr = b64decsafe(url0);
|
||||
var team = sstr.split('@');
|
||||
opt.set('type', "ss");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
opt.set('server', part2[0]);
|
||||
opt.set('server_port', part2[1]);
|
||||
opt.set('password', part1[1]);
|
||||
opt.set('encrypt_method_ss', part1[0]);
|
||||
opt.set('plugin', "none");
|
||||
opt.get('plugin').dispatchEvent(event);
|
||||
//opt.set('ss_plugin_opts', "");
|
||||
if (param !== undefined) {
|
||||
opt.set('alias', decodeURI(param));
|
||||
}
|
||||
}
|
||||
} else if (ssu[0] === "trojan") {
|
||||
var stype = "trojan";
|
||||
var m = parseNodeUrl(ssrurl);
|
||||
console.log(m.search);
|
||||
var password = m.passwd;
|
||||
if (password === "") {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
|
||||
return false;
|
||||
}
|
||||
var queryParam = {};
|
||||
if (m.search.length > 1) {
|
||||
var query = m.search.split('?');
|
||||
var queryParams = query[1];
|
||||
var queryArray = queryParams.split('&');
|
||||
var params;
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
if (queryParam.mux || queryParam.ws || queryParam.h2 || queryParam.ss || queryParam.plugin) {
|
||||
stype = "trojan-go";
|
||||
}
|
||||
opt.set('type', stype);
|
||||
opt.get('type').dispatchEvent(event);
|
||||
opt.set('server', m.hostname);
|
||||
opt.set('server_port', m.port || "443");
|
||||
opt.set(!opt.client && stype === "trojan-go" ? 'passwords' : 'password', decodeURIComponent(password));
|
||||
var tls = true;
|
||||
if (stype === "trojan-go") {
|
||||
tls = queryParam.plugin === undefined;
|
||||
}
|
||||
if (tls === false) { alert("TODO: plugin params for trojan-go."); }
|
||||
opt.set('tls', tls);
|
||||
opt.get('tls').dispatchEvent(event);
|
||||
if (tls) {
|
||||
opt.set('tls_host', queryParam.peer || queryParam.sni || '');
|
||||
opt.set('insecure', queryParam.allowinsecure === '1');
|
||||
}
|
||||
var tran = 'original';
|
||||
var ws = queryParam.type.indexOf('ws') !== -1;
|
||||
var h2 = queryParam.type.indexOf('h2') !== -1;
|
||||
if (ws && h2) {
|
||||
tran = 'h2+ws'
|
||||
} else {
|
||||
if (ws) tran = 'ws';
|
||||
if (h2) tran = 'h2';
|
||||
}
|
||||
opt.set('trojan_transport', 'tran');
|
||||
opt.get('trojan_transport').dispatchEvent(event);
|
||||
if (ws) {
|
||||
opt.set('ws_host', queryParam.wshost || '');
|
||||
opt.set('ws_path', queryParam.wspath || '/');
|
||||
}
|
||||
if (h2) {
|
||||
opt.set('h2_host', queryParam.h2host || '');
|
||||
opt.set('h2_path', queryParam.h2path || '/');
|
||||
}
|
||||
var ss = queryParam.ss === '1';
|
||||
opt.set('ss_aead', ss);
|
||||
if (ss) {
|
||||
opt.set('ss_aead_method', queryParam.ssmethod.toLowerCase() || '');
|
||||
opt.set('ss_aead_pwd', queryParam.sspasswd || '');
|
||||
}
|
||||
opt.set('mux', queryParam.mux === '1');
|
||||
if (m.hash) {
|
||||
opt.set('alias', decodeURI(m.hash.substr(1)));
|
||||
}
|
||||
} else if (ssu[0] === "trojan-go") {
|
||||
var m = parseNodeUrl(ssrurl);
|
||||
console.log(m.search);
|
||||
var password = m.passwd;
|
||||
if (password === "") {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
|
||||
return false;
|
||||
}
|
||||
var queryParam = {};
|
||||
if (m.search.length > 1) {
|
||||
var query = m.search.split('?');
|
||||
var queryParams = query[1];
|
||||
var queryArray = queryParams.split('&');
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
var params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
opt.set('type', 'trojan-go');
|
||||
opt.get('type').dispatchEvent(event);
|
||||
opt.set('server', m.hostname);
|
||||
opt.set('server_port', m.port || "443");
|
||||
opt.set(opt.client ? 'password' : 'passwords', decodeURIComponent(password));
|
||||
opt.set('tls', '1');
|
||||
opt.get('tls').dispatchEvent(event);
|
||||
opt.set('insecure', '0');
|
||||
opt.set('tls_host', queryParam.peer || queryParam.sni || '');
|
||||
var plugin = queryParam.plugin !== undefined;
|
||||
if (plugin) {
|
||||
opt.set('trojan_transport', 'original');
|
||||
opt.get('trojan_transport').dispatchEvent(event);
|
||||
var plugin = JSON.parse(queryParam.plugin);
|
||||
if (plugin) {
|
||||
opt.set('plugin_type', plugin.type);
|
||||
opt.get('plugin_type').dispatchEvent(event);
|
||||
if (plugin.type !== "plaintext") {
|
||||
opt.set('plugin_cmd', plugin.command);
|
||||
opt.set('plugin_option', plugin.option);
|
||||
opt.setlist('plugin_arg', plugin.arg);
|
||||
}
|
||||
} else
|
||||
alert(queryParam.plugin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var tran = 'original';
|
||||
var or = queryParam.type === undefined || queryParam.type === 'original';
|
||||
var ws = queryParam.type.indexOf('ws') !== -1;
|
||||
var h2 = queryParam.type.indexOf('h2') !== -1;
|
||||
if (ws && h2) {
|
||||
tran = 'h2+ws'
|
||||
} else {
|
||||
if (ws) tran = 'ws';
|
||||
if (h2) tran = 'h2';
|
||||
}
|
||||
opt.set('trojan_transport', tran);
|
||||
opt.get('trojan_transport').dispatchEvent(event);
|
||||
if (ws) {
|
||||
opt.set('ws_host', queryParam.host || '');
|
||||
opt.set('ws_path', queryParam.path || '/');
|
||||
}
|
||||
if (h2){
|
||||
opt.set('h2_host', queryParam.host || '');
|
||||
opt.set('h2_path', queryParam.path || '/');
|
||||
}
|
||||
var enc = {};
|
||||
var ss = false;
|
||||
if (queryParam.encryption) {
|
||||
var r = queryParam.encryption.match(/^(ss);([^;:]*)[;:](.*)$/),
|
||||
enc = {type: r[1], method: r[2], password: r[3]};
|
||||
}
|
||||
ss = enc.type === 'ss';
|
||||
opt.set('ss_aead', ss);
|
||||
if (ss) {
|
||||
opt.set('ss_aead_method', enc.method.toLowerCase() || '');
|
||||
opt.set('ss_aead_pwd', enc.password || '');
|
||||
}
|
||||
opt.set('mux', '1');
|
||||
if (m.hash) {
|
||||
opt.set('alias', decodeURI(m.hash.substr(1)));
|
||||
}
|
||||
} else if (ssu[0] === "vmess") {
|
||||
var sstr = b64DecodeUnicode(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
opt.set('type', "vmess");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = JSON.parse(sstr);
|
||||
console.log(ssm);
|
||||
opt.set('alias', ssm.ps);
|
||||
opt.set('server', ssm.add);
|
||||
opt.set('server_port', ssm.port);
|
||||
opt.set('alter_id', ssm.aid);
|
||||
opt.set('uuid', ssm.id);
|
||||
opt.set('tls', ssm.tls === "tls");
|
||||
opt.get('tls').dispatchEvent(event);
|
||||
if (ssm.tls === "tls") {
|
||||
var tls_host = ssm.host;
|
||||
if (ssm.sni) {
|
||||
tls_host = ssm.sni
|
||||
}
|
||||
opt.set('tls_host', tls_host);
|
||||
}
|
||||
ssm.net = ssm.net.toLowerCase();
|
||||
if (ssm.net === "kcp" || ssm.net === "mkcp")
|
||||
ssm.net = "mkcp"
|
||||
opt.set('transport', ssm.net);
|
||||
opt.get('transport').dispatchEvent(event);
|
||||
if (ssm.net === "tcp") {
|
||||
opt.set('tcp_guise', (ssm.host && ssm.path) ? "http" : "none");
|
||||
opt.get('tcp_guise').dispatchEvent(event);
|
||||
if (ssm.host && ssm.path) {
|
||||
opt.set('http_host', ssm.host);
|
||||
opt.set('http_path', ssm.path);
|
||||
}
|
||||
} else if (ssm.net === "ws") {
|
||||
opt.set('ws_host', ssm.host);
|
||||
opt.set('ws_path', ssm.path);
|
||||
} else if (ssm.net === "h2") {
|
||||
opt.set('h2_host', ssm.host);
|
||||
opt.set('h2_path', ssm.path);
|
||||
} else if (ssm.net === "quic") {
|
||||
opt.set('quic_security', ssm.securty);
|
||||
opt.set('quic_key', ssm.key);
|
||||
} else if (ssm.net === "kcp" || ssm.net === "mkcp") {
|
||||
opt.set('kcp_guise', ssm.type);
|
||||
opt.get('kcp_guise').dispatchEvent(event);
|
||||
} else if (ssm.net === "grpc") {
|
||||
opt.set('grpc_serviceName', ssm.path);
|
||||
}
|
||||
} else if (ssu[0] === "vless") {
|
||||
opt.set('type', "vless");
|
||||
opt.get('type').dispatchEvent(event);
|
||||
var m = parseNodeUrl(ssrurl);
|
||||
console.log(m.search);
|
||||
var password = m.passwd;
|
||||
if (password === "") {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>";
|
||||
return false;
|
||||
}
|
||||
opt.set('uuid', password);
|
||||
opt.set('server', m.hostname);
|
||||
opt.set('server_port', m.port || "443");
|
||||
var queryParam = {};
|
||||
if (m.search.length > 1) {
|
||||
var query = m.search.split('?');
|
||||
var queryParams = query[1];
|
||||
var queryArray = queryParams.split('&');
|
||||
var params;
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
|
||||
opt.set('encryption', queryParam.encryption);
|
||||
if (queryParam.security) {
|
||||
if (queryParam.security == "tls" || queryParam.security == "xtls") {
|
||||
if (queryParam.security == "tls") {
|
||||
opt.set('tls', true);
|
||||
opt.get('tls').dispatchEvent(event);
|
||||
}
|
||||
if (queryParam.security == "xtls") {
|
||||
opt.set('xtls', true);
|
||||
opt.get('xtls').dispatchEvent(event);
|
||||
opt.set('vless_flow', queryParam.flow || "xtls-rprx-direct");
|
||||
}
|
||||
opt.set('tls_host', queryParam.sni || '');
|
||||
|
||||
opt.set('insecure', true);
|
||||
if (queryParam.allowinsecure === '0') {
|
||||
opt.set('insecure', false);
|
||||
}
|
||||
opt.get('insecure').dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
queryParam.type = queryParam.type.toLowerCase();
|
||||
if (queryParam.type === "kcp" || queryParam.type === "mkcp")
|
||||
queryParam.type = "mkcp"
|
||||
opt.set('transport', queryParam.type);
|
||||
opt.get('transport').dispatchEvent(event);
|
||||
if (queryParam.type === "tcp") {
|
||||
opt.set('tcp_guise', queryParam.headerType || "none");
|
||||
opt.get('tcp_guise').dispatchEvent(event);
|
||||
if (queryParam.headerType && queryParam.headerType != "none") {
|
||||
opt.set('http_host', queryParam.host || "");
|
||||
opt.set('http_path', queryParam.path || "");
|
||||
}
|
||||
} else if (queryParam.type === "ws") {
|
||||
opt.set('ws_host', queryParam.host || "");
|
||||
opt.set('ws_path', queryParam.path || "");
|
||||
} else if (queryParam.type === "h2") {
|
||||
opt.set('h2_host', queryParam.host || "");
|
||||
opt.set('h2_path', queryParam.path || "");
|
||||
} else if (queryParam.type === "quic") {
|
||||
opt.set('quic_guise', queryParam.headerType || "none");
|
||||
opt.get('quic_guise').dispatchEvent(event);
|
||||
opt.set('quic_security', queryParam.quicSecurity);
|
||||
opt.set('quic_key', queryParam.key);
|
||||
} else if (queryParam.type === "kcp" || queryParam.type === "mkcp") {
|
||||
opt.set('kcp_guise', queryParam.headerType || "none");
|
||||
opt.get('kcp_guise').dispatchEvent(event);
|
||||
} else if (queryParam.type === "grpc") {
|
||||
opt.set('grpc_serviceName', (queryParam.serviceName || queryParam.path) || "");
|
||||
}
|
||||
|
||||
if (m.hash) {
|
||||
opt.set('alias', decodeURI(m.hash.substr(1)));
|
||||
}
|
||||
} else {
|
||||
s.innerHTML = "<font color='red'><%:Invalid Share URL Format%></font>: " + ssu[0];
|
||||
return false;
|
||||
}
|
||||
s.innerHTML = "<font color='green'><%:Import Finished %></font>";
|
||||
return false;
|
||||
}
|
||||
|
||||
//]]></script>
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:From Share URL%>' onclick="return fromUrl(this, '<%=self.option%>', '<%=self.value%>')" />
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:Build Share URL%>' onclick="return buildUrl(this, '<%=self.option%>', '<%=self.value%>')" />
|
||||
<span id="<%=self.option%>-status"></span>
|
||||
<%+cbi/valuefooter%>
|
366
luci-app-bypass/luasrc/view/bypass/ssrurl.htm
Normal file
366
luci-app-bypass/luasrc/view/bypass/ssrurl.htm
Normal file
@ -0,0 +1,366 @@
|
||||
<%+cbi/valueheader%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function padright(str, cnt, pad) {
|
||||
return str + Array(cnt + 1).join(pad);
|
||||
}
|
||||
|
||||
function b64EncodeUnicode(str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
}));
|
||||
}
|
||||
|
||||
function b64encutf8safe(str) {
|
||||
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
|
||||
}
|
||||
|
||||
function b64DecodeUnicode(str) {
|
||||
return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
|
||||
function b64decutf8safe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l) str = padright(str, l, "=");
|
||||
return b64DecodeUnicode(str);
|
||||
}
|
||||
|
||||
function b64encsafe(str) {
|
||||
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
|
||||
}
|
||||
|
||||
function b64decsafe(str) {
|
||||
var l;
|
||||
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
||||
l = str.length;
|
||||
l = (4 - l % 4) % 4;
|
||||
if (l) str = padright(str, l, "=");
|
||||
return atob(str);
|
||||
}
|
||||
|
||||
function dictvalue(d, key) {
|
||||
var v = d[key];
|
||||
if (typeof (v) == 'undefined' || v == '') return '';
|
||||
return b64decsafe(v);
|
||||
}
|
||||
|
||||
function export_ssr_url(btn, urlname, sid) {
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s) return false;
|
||||
var v_server = document.getElementsByName('cbid.bypass.' + sid + '.server')[0];
|
||||
var v_port = document.getElementsByName('cbid.bypass.' + sid + '.server_port')[0];
|
||||
var v_protocol = document.getElementsByName('cbid.bypass.' + sid + '.protocol')[0];
|
||||
var v_method = document.getElementsByName('cbid.bypass.' + sid + '.encrypt_method')[0];
|
||||
var v_obfs = document.getElementsByName('cbid.bypass.' + sid + '.obfs')[0];
|
||||
var v_password = document.getElementsByName('cbid.bypass.' + sid + '.password')[0];
|
||||
var v_obfs_param = document.getElementsByName('cbid.bypass.' + sid + '.obfs_param')[0];
|
||||
var v_protocol_param = document.getElementsByName('cbid.bypass.' + sid + '.protocol_param')[0];
|
||||
var v_alias = document.getElementsByName('cbid.bypass.' + sid + '.alias')[0];
|
||||
var ssr_str = v_server.value + ":" + v_port.value + ":" + v_protocol.value + ":" + v_method.value + ":" + v_obfs.value + ":" + b64encsafe(v_password.value) + "/?obfsparam=" + b64encsafe(v_obfs_param.value) + "&protoparam=" + b64encsafe(v_protocol_param.value) + "&remarks=" + b64encutf8safe(v_alias.value);
|
||||
var textarea = document.createElement("textarea");
|
||||
textarea.textContent = "ssr://" + b64encsafe(ssr_str);
|
||||
textarea.style.position = "fixed";
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand("copy"); // Security exception may be thrown by some browsers.
|
||||
s.innerHTML = "<font color='green'><%:Copy SSR to clipboard successfully.%></font>";
|
||||
} catch (ex) {
|
||||
s.innerHTML = "<font color='red'><%:Unable to copy SSR to clipboard.%></font>";
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function import_ssr_url(btn, urlname, sid) {
|
||||
var s = document.getElementById(urlname + '-status');
|
||||
if (!s) return false;
|
||||
var ssrurl = prompt("<%:Paste sharing link here%>", "");
|
||||
if (ssrurl == null || ssrurl == "") {
|
||||
s.innerHTML = "<font color='red'><%:User cancelled.%></font>";
|
||||
return false;
|
||||
}
|
||||
s.innerHTML = "";
|
||||
//var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
|
||||
var ssu = ssrurl.split('://');
|
||||
//console.log(ssu.length);
|
||||
var event = document.createEvent("HTMLEvents");
|
||||
event.initEvent("change", true, true);
|
||||
switch (ssu[0]) {
|
||||
case "ss":
|
||||
var url0, param = "";
|
||||
var sipIndex = ssu[1].indexOf("@");
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1];
|
||||
}
|
||||
if (sipIndex != -1) {
|
||||
// SIP002
|
||||
var userInfo = b64decsafe(url0.substr(0, sipIndex));
|
||||
var temp = url0.substr(sipIndex + 1).split("/?");
|
||||
var serverInfo = temp[0].split(":");
|
||||
var server = serverInfo[0];
|
||||
var port = serverInfo[1].replace("/","");
|
||||
var method, password, plugin, pluginOpts;
|
||||
if (temp[1]) {
|
||||
var pluginInfo = decodeURIComponent(temp[1]);
|
||||
var pluginIndex = pluginInfo.indexOf(";");
|
||||
var pluginNameInfo = pluginInfo.substr(0, pluginIndex);
|
||||
plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1);
|
||||
pluginOpts = pluginInfo.substr(pluginIndex + 1);
|
||||
}
|
||||
var userInfoSplitIndex = userInfo.indexOf(":");
|
||||
if (userInfoSplitIndex != -1) {
|
||||
method = userInfo.substr(0, userInfoSplitIndex);
|
||||
password = userInfo.substr(userInfoSplitIndex + 1);
|
||||
}
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].value = ssu[0];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].dispatchEvent(event);
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server')[0].value = server;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server_port')[0].value = port;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.password')[0].value = password || "";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.encrypt_method_ss')[0].value = method || "";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.plugin')[0].value = plugin || "none";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.plugin')[0].dispatchEvent(event);
|
||||
if (plugin != undefined) {
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.plugin_opts')[0].value = pluginOpts || "";
|
||||
}
|
||||
if (param != undefined) {
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.alias')[0].value = decodeURI(param);
|
||||
}
|
||||
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
|
||||
} else {
|
||||
var sstr = b64decsafe(url0);
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].value = ssu[0];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server')[0].value = part2[0];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server_port')[0].value = part2[1];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.password')[0].value = part1[1];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.encrypt_method_ss')[0].value = part1[0];
|
||||
if (param != undefined) {
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.alias')[0].value = decodeURI(param);
|
||||
}
|
||||
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
|
||||
}
|
||||
return false;
|
||||
case "ssr":
|
||||
var sstr = b64decsafe(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].value = ssu[0];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.type')[0].dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
|
||||
if (!ssm || ssm.length < 7) return false;
|
||||
var pdict = {};
|
||||
if (param.length > 2) {
|
||||
var a = param.split('&');
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var b = a[i].split('=');
|
||||
pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
|
||||
}
|
||||
}
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server')[0].value = ssm[1];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server_port')[0].value = ssm[2];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.protocol')[0].value = ssm[3];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.encrypt_method')[0].value = ssm[4];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.obfs')[0].value = ssm[5];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.password')[0].value = b64decsafe(ssm[6]);
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.obfs_param')[0].value = dictvalue(pdict, 'obfsparam');
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.protocol_param')[0].value = dictvalue(pdict, 'protoparam');
|
||||
var rem = pdict['remarks'];
|
||||
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementsByName('cbid.bypass.' + sid + '.alias')[0].value = b64decutf8safe(rem);
|
||||
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
|
||||
return false;
|
||||
case "trojan":
|
||||
var url0, param = "";
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = ssu[1].substr(ploc + 1);
|
||||
} else {
|
||||
url0 = ssu[1]
|
||||
}
|
||||
var sstr = url0;
|
||||
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 = "trojan";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.v2ray_protocol')[0].dispatchEvent(event);
|
||||
var team = sstr.split('@');
|
||||
var password = team[0]
|
||||
var serverPart = team[1].split(':');
|
||||
var others = serverPart[1].split('?');
|
||||
var port = parseInt(others[0]);
|
||||
var queryParam = {}
|
||||
if (others.length > 1) {
|
||||
var queryParams = others[1]
|
||||
var queryArray = queryParams.split('&');
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
var params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server')[0].value = serverPart[0];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server_port')[0].value = port || '443';
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.password')[0].value = password;
|
||||
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 = queryParam.sni || '';
|
||||
if (param != undefined) {
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.alias')[0].value = decodeURI(param);
|
||||
}
|
||||
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
|
||||
return false;
|
||||
case "vmess":
|
||||
var sstr = b64DecodeUnicode(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
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 = "vmess";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.v2ray_protocol')[0].dispatchEvent(event);
|
||||
var url0, param = "";
|
||||
if (ploc > 0) {
|
||||
url0 = sstr.substr(0, ploc);
|
||||
param = sstr.substr(ploc + 2);
|
||||
}
|
||||
var ssm = JSON.parse(sstr);
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.alias')[0].value = ssm.ps;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server')[0].value = ssm.add;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server_port')[0].value = ssm.port;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.vmess_id')[0].value = ssm.id;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].value = ssm.net;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].dispatchEvent(event);
|
||||
if (ssm.net == "tcp") {
|
||||
if (ssm.type && ssm.type != "http") {
|
||||
ssm.type = "none"
|
||||
}
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].value = ssm.type;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.tcp_guise')[0].dispatchEvent(event);
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.http_host')[0].value = ssm.host;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.http_path')[0].value = ssm.path;
|
||||
}
|
||||
if (ssm.net == "ws") {
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.ws_host')[0].value = ssm.host;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.ws_path')[0].value = ssm.path;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (ssm.net == "quic") {
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.quic_security')[0].value = ssm.securty;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.quic_key')[0].value = ssm.key;
|
||||
}
|
||||
if (ssm.net == "kcp") {
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.kcp_guise')[0].value = ssm.type;
|
||||
}
|
||||
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 + '.tls_host')[0].value = ssm.host;
|
||||
}
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.mux')[0].checked = true;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.mux')[0].dispatchEvent(event);
|
||||
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
|
||||
return false;
|
||||
case "vless":
|
||||
var url0, param = "";
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
if (ploc > 0) {
|
||||
url0 = ssu[1].substr(0, ploc);
|
||||
param = decodeURIComponent(ssu[1].substr(ploc + 1));
|
||||
} else {
|
||||
url0 = ssu[1]
|
||||
}
|
||||
var sstr = url0;
|
||||
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);
|
||||
var team = sstr.split('@');
|
||||
var uuid = team[0]
|
||||
var serverPart = team[1].split(':');
|
||||
var others = serverPart[1].split('?');
|
||||
var port = others[0]
|
||||
var queryParam = {}
|
||||
if (others.length > 1) {
|
||||
var queryParams = others[1]
|
||||
var queryArray = queryParams.split('&');
|
||||
for (i = 0; i < queryArray.length; i++) {
|
||||
var params = queryArray[i].split('=');
|
||||
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server')[0].value = serverPart[0];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.server_port')[0].value = port;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.vmess_id')[0].value = uuid;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].value = queryParam.type ? (queryParam.type == "http" ? "h2" : queryParam.type) : "tcp";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.transport')[0].dispatchEvent(event);
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.vless_encryption')[0].value = queryParam.encryption || "none";
|
||||
if (queryParam.security == "tls") {
|
||||
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 = queryParam.sni || serverPart[0];
|
||||
}
|
||||
switch (queryParam.type) {
|
||||
case "ws":
|
||||
//document.getElementsByName('cbid.bypass.' + sid + '.ws_host')[0].value = queryParam.host;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.ws_path')[0].value = queryParam.path || "/";
|
||||
break;
|
||||
case "kcp":
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.kcp_guise')[0].value = queryParam.headerType || "none";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.kcp_guise')[0].dispatchEvent(event);
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.seed')[0].value = queryParam.seed;
|
||||
break;
|
||||
case "http":
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.h2_host')[0].value = queryParam.host || serverPart[0];
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.h2_path')[0].value = queryParam.path || "/";
|
||||
break;
|
||||
case "quic":
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.quic_guise')[0].value = queryParam.headerType || "none";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.quic_guise')[0].dispatchEvent(event);
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.quic_security')[0].value = queryParam.quicSecurity || "none";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.quic_key')[0].value = queryParam.key;
|
||||
break;
|
||||
case "grpc":
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.serviceName')[0].value = queryParam.serviceName;
|
||||
break;
|
||||
default:
|
||||
if (queryParam.security == "xtls") {
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.xtls')[0].checked = true;
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.xtls')[0].dispatchEvent(event);
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.vless_flow')[0].value = queryParam.flow || "xtls-rprx-splice";
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.tls_host')[0].value = queryParam.sni || serverPart[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (param != undefined) {
|
||||
document.getElementsByName('cbid.bypass.' + sid + '.alias')[0].value = decodeURI(param);
|
||||
}
|
||||
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
|
||||
return false;
|
||||
default:
|
||||
s.innerHTML = "<font color='red'><%:Invalid format.%></font>";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:Import%>" onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" />
|
||||
<span id="<%=self.option%>-status"></span>
|
||||
<%+cbi/valuefooter%>
|
@ -1,172 +0,0 @@
|
||||
<%
|
||||
local trojan_go_version = require "luci.model.cbi.bypass.api".get_trojan_go_version()
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var trojanInfo;
|
||||
var tokenStr = '<%=token%>';
|
||||
var manuallyUpdateText = '<%:Check update%>';
|
||||
var noUpdateText = '<%:It is the latest version%>';
|
||||
var updateSuccessText = '<%:Update successful%>';
|
||||
var clickToUpdateText = '<%:Click to update%>';
|
||||
var inProgressText = '<%:Updating...%>';
|
||||
var unexpectedErrorText = '<%:Unexpected error%>';
|
||||
var updateInProgressNotice = '<%:Updating, are you sure to close?%>';
|
||||
var downloadingText = '<%:Downloading...%>';
|
||||
var decompressioningText = '<%:Unpacking...%>';
|
||||
var movingText = '<%:Moving...%>';
|
||||
|
||||
window.onload = function() {
|
||||
var trojanCheckBtn = document.getElementById('_trojan-check_btn');
|
||||
var trojanDetailElm = document.getElementById('_trojan-check_btn-detail');
|
||||
};
|
||||
|
||||
function addPageNotice_trojan() {
|
||||
window.onbeforeunload = function(e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice_trojan() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess_trojan(btn) {
|
||||
alert(updateSuccessText);
|
||||
|
||||
if(btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function() {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError_trojan(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = manuallyUpdateText;
|
||||
|
||||
if(errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function onBtnClick_trojan(btn) {
|
||||
if(trojanInfo === undefined) {
|
||||
checkUpdate_trojan(btn);
|
||||
} else {
|
||||
doUpdate_trojan(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate_trojan(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice_trojan();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
XHR.get('<%=url([[admin]], [[services]], [[bypass]], [[trojan_go_check]])%>', {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function(x,json) {
|
||||
removePageNotice_trojan();
|
||||
|
||||
if(json.code) {
|
||||
trojanInfo = undefined;
|
||||
onRequestError_trojan(btn, json.error);
|
||||
} else {
|
||||
if(json.update) {
|
||||
trojanInfo = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if(ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if(json.version) {
|
||||
urlNode = '<em style="color:red;">最新版本号:' + json.version + '</em>';
|
||||
if(json.url && json.url.html) {
|
||||
urlNode = '<a href="' + json.url.html + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
},300);
|
||||
}
|
||||
|
||||
function doUpdate_trojan(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = downloadingText;
|
||||
|
||||
addPageNotice_trojan();
|
||||
|
||||
var trojanUpdateUrl = '<%=url([[admin]], [[services]], [[bypass]], [[trojan_go_update]])%>';
|
||||
// Download file
|
||||
XHR.get(trojanUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: trojanInfo ? trojanInfo.url.download : ''
|
||||
}, function(x,json) {
|
||||
if(json.code) {
|
||||
removePageNotice_trojan();
|
||||
onRequestError_trojan(btn, json.error);
|
||||
} else {
|
||||
btn.value = decompressioningText;
|
||||
|
||||
// Extract file
|
||||
XHR.get(trojanUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'extract',
|
||||
file: json.file,
|
||||
subfix: trojanInfo ? trojanInfo.type : ''
|
||||
}, function(x,json) {
|
||||
if(json.code) {
|
||||
removePageNotice_trojan();
|
||||
onRequestError_trojan(btn, json.error);
|
||||
} else {
|
||||
btn.value = movingText;
|
||||
|
||||
// Move file to target dir
|
||||
XHR.get(trojanUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function(x,json) {
|
||||
removePageNotice_trojan();
|
||||
if(json.code) {
|
||||
onRequestError_trojan(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess_trojan(btn);
|
||||
}
|
||||
},300)
|
||||
}
|
||||
},300)
|
||||
}
|
||||
},300)
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">Trojan-Go
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<span>【 <%=trojan_go_version%> 】</span>
|
||||
<input class="cbi-button cbi-input-apply" type="button" id="_trojan-check_btn" onclick="onBtnClick_trojan(this);" value="<%:Check update%>" />
|
||||
<span id="_trojan-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -4,8 +4,8 @@ msgstr "基本设置"
|
||||
msgid "Bypass Settings"
|
||||
msgstr "Bypass 设置"
|
||||
|
||||
msgid "Support SS/SSR/XRAY/TROJAN/TROJAN-GO/NAIVEPROXY/SOCKS5/TUN etc."
|
||||
msgstr "支持 SS/SSR/Xray/Trojan/Trojan-Go/NavieProxy/Socks5/TUN 等协议"
|
||||
msgid "Support SS/SSR/XRAY/TROJAN/NAIVEPROXY/SOCKS5/TUN etc."
|
||||
msgstr "支持 SS/SSR/Xray/Trojan/NavieProxy/Socks5/TUN 等协议"
|
||||
|
||||
msgid "Bypass RUNNING"
|
||||
msgstr "Bypass 客户端运行中"
|
||||
@ -304,13 +304,28 @@ msgstr "插件参数"
|
||||
msgid "Protocol"
|
||||
msgstr "传输协议"
|
||||
|
||||
msgid "Protocol param(optional)"
|
||||
msgid "Protocol param (optional)"
|
||||
msgstr "传输协议参数(可选)"
|
||||
|
||||
msgid "Authentication type"
|
||||
msgstr "验证类型"
|
||||
|
||||
msgid "Authentication payload"
|
||||
msgstr "验证载荷"
|
||||
|
||||
msgid "QUIC connection receive window"
|
||||
msgstr "QUIC 连接接收窗口"
|
||||
|
||||
msgid "QUIC stream receive window"
|
||||
msgstr "QUIC 流接收窗口"
|
||||
|
||||
msgid "Disable Path MTU discovery"
|
||||
msgstr "禁用 MTU 探测"
|
||||
|
||||
msgid "Obfs"
|
||||
msgstr "混淆插件"
|
||||
|
||||
msgid "Obfs param(optional)"
|
||||
msgid "Obfs param (optional)"
|
||||
msgstr "混淆参数(可选)"
|
||||
|
||||
msgid "VLESS Encryption"
|
||||
@ -722,4 +737,5 @@ msgid "Used with AdGuardHome"
|
||||
msgstr "与AdGuardHome搭配使用"
|
||||
|
||||
msgid "Luci-app-adguardhome require"
|
||||
msgstr "请确保luci-app-adguardhome能正常启用,本插件会联动开启并配置ADG,ADG无需任何设置"
|
||||
msgstr "请确保luci-app-adguardhome能正常启用,本插件会联动开启并配置ADG,ADG无需任何设置"
|
||||
|
||||
|
@ -72,9 +72,9 @@ f_bin(){
|
||||
ssr) ret=$(which ssr-redir);;
|
||||
ssr-local) ret=$(which ssr-local);;
|
||||
ssr-server) ret=$(which ssr-server);;
|
||||
vmess|vless) ret=$(which xray);;
|
||||
v2ray) ret=$(which xray);;
|
||||
hysteria) ret=$(which hysteria);;
|
||||
trojan) ret=$(which trojan-plus);;
|
||||
trojan-go) ret=$(which trojan-go);;
|
||||
naiveproxy) ret=$(which naive);;
|
||||
socks5|tun) ret=$(which redsocks2);;
|
||||
esac
|
||||
@ -150,13 +150,13 @@ gen_config_file(){
|
||||
}
|
||||
EOF
|
||||
;;
|
||||
vmess|vless)
|
||||
v2ray|hysteria)
|
||||
[ $rtype = udp ] && smode=udp || smode=tcp
|
||||
[ $rtype = socks ] && lport=0
|
||||
lua $BIN_DIR/genv2config $1 $smode $lport $ssport $serv_ip >$config_file
|
||||
lua $BIN_DIR/gen_config $1 $smode $lport $ssport $serv_ip >$config_file
|
||||
sed -i 's/\\//g' $config_file
|
||||
;;
|
||||
trojan|trojan-go)
|
||||
trojan)
|
||||
case $rtype in
|
||||
tcp|udp|nf) smode=nat;;
|
||||
socks) smode=client;;
|
||||
@ -397,7 +397,7 @@ start_retcp(){
|
||||
[ $ttype = ss ] && name=Shadowsocks || name=ShadowsocksR
|
||||
log "Main Node: $name $threads Threads Started!"
|
||||
;;
|
||||
vmess|vless)
|
||||
v2ray|hysteria)
|
||||
if [ $SO_SERVER = $GLOBAL_SERVER ];then
|
||||
port=$(uci_get_by_type socks5_proxy local_port 1080)
|
||||
socks5_start=1
|
||||
@ -412,20 +412,14 @@ start_retcp(){
|
||||
log "Socks5 Node: $($cmd -version | head -1 | awk '{print$1,$2}') Started!"
|
||||
fi
|
||||
;;
|
||||
trojan|trojan-go)
|
||||
trojan)
|
||||
gen_config_file $GLOBAL_SERVER $rtype "" $server
|
||||
if [ $type = trojan ];then
|
||||
redir_tcp=$threads
|
||||
for i in $(seq 1 $threads);do
|
||||
$cmd --config $config_file >$log_file 2>&1 &
|
||||
done
|
||||
name=Trojan-Plus
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$3}')"
|
||||
else
|
||||
redir_tcp=$threads
|
||||
for i in $(seq 1 $threads);do
|
||||
$cmd --config $config_file >$log_file 2>&1 &
|
||||
name=Trojan-Go
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$2}')"
|
||||
fi
|
||||
done
|
||||
name=Trojan-Plus
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$3}')"
|
||||
log "Main Node: $name (Ver $ver) $threads Threads Started!"
|
||||
;;
|
||||
naiveproxy)
|
||||
@ -468,21 +462,16 @@ start_reudp(){
|
||||
[ $utype = ss ] && name=Shadowsocks || name=ShadowsocksR
|
||||
log "UDP Relay: $name Started!"
|
||||
;;
|
||||
vmess|vless)
|
||||
v2ray|hysteria)
|
||||
gen_config_file $UDP_RELAY_SERVER $rtype 0 $udp_server
|
||||
$cmd -c $config_file >$log_file 2>&1 &
|
||||
log "UDP Relay: $($cmd -version | head -1 | awk '{print$1,$2}') Started!"
|
||||
;;
|
||||
trojan|trojan-go)
|
||||
trojan)
|
||||
gen_config_file $UDP_RELAY_SERVER $rtype "" $udp_server
|
||||
$cmd --config $config_file >$log_file 2>&1 &
|
||||
[ $utype = trojan ] && {
|
||||
name=Trojan-Plus
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$3}')"
|
||||
} || {
|
||||
name=Trojan-Go
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$2}')"
|
||||
}
|
||||
name=Trojan-Plus
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$3}')"
|
||||
log "UDP Relay: $name (Ver $ver) Started!"
|
||||
;;
|
||||
naiveproxy)
|
||||
@ -518,20 +507,17 @@ start_renf(){
|
||||
[ $ntype = ss ] && name=Shadowsocks || name=ShadowsocksR
|
||||
log "NF Shunt : $name Started!"
|
||||
;;
|
||||
vmess|vless)
|
||||
v2ray|hysteria)
|
||||
gen_config_file $NF_SERVER $rtype 0 $nf_ip
|
||||
$cmd -c $config_file >$log_file 2>&1 &
|
||||
log "NF Shunt : $($cmd -version | head -1 | awk '{print$1,$2}') Started!"
|
||||
;;
|
||||
trojan|trojan-go)
|
||||
trojan)
|
||||
gen_config_file $NF_SERVER $rtype "" $nf_ip
|
||||
$cmd --config $config_file >$log_file 2>&1 &
|
||||
[ $ntype = trojan ] && {
|
||||
name=Trojan-Plus
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$3}')"
|
||||
} || {
|
||||
name=Trojan-Go
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$2}')"
|
||||
}
|
||||
log "NF Shunt : $name (Ver $ver) Started!"
|
||||
;;
|
||||
@ -572,20 +558,17 @@ start_local(){
|
||||
[ $type = ss ] && name=Shadowsocks || name=ShadowsocksR
|
||||
log "Socks5 Node: $name Started!"
|
||||
;;
|
||||
vmess|vless)
|
||||
v2ray|hysteria)
|
||||
gen_config_file $SO_SERVER $rtype $socks5_port $socks5_ip
|
||||
$cmd -c $config_file >$log_file 2>&1 &
|
||||
log "Socks5 Node: $($cmd -version | head -1 | awk '{print$1,$2}') Started!"
|
||||
;;
|
||||
trojan|trojan-go)
|
||||
trojan)
|
||||
gen_config_file $SO_SERVER $rtype "" $socks5_ip
|
||||
$cmd --config $config_file >$log_file 2>&1 &
|
||||
[ $type = trojan ] && {
|
||||
name=Trojan-Plus
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$3}')"
|
||||
} || {
|
||||
name=Trojan-Go
|
||||
ver="$($cmd --version 2>&1 | head -1 | awk '{print$2}')"
|
||||
}
|
||||
log "Socks5 Node: $name (Ver $ver) Started!"
|
||||
;;
|
||||
|
@ -12,5 +12,16 @@ uci batch <<EOF
|
||||
chmod +x /etc/init.d/bypass /usr/share/bypass/* >/dev/null 2>&1
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
killall -HUP rpcd 2>/dev/null
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
if [[ "$(grep "option type 'vless'" /etc/config/bypass)" || "$(grep "option type 'vmess'" /etc/config/bypass)" ]]; then
|
||||
sed -i "s/option uuid/option vmess_id/" /etc/config/bypass
|
||||
for i in {1..100}
|
||||
do
|
||||
uci -q set bypass.@servers[$i].type='v2ray'
|
||||
[ "$(uci -q get bypass.@servers[$i].type)" == 'vless' ] && uci -q set bypass.@servers[$i].v2ray_protocol='vless' || uci -q set bypass.@servers[$i].v2ray_protocol='vmess'
|
||||
done
|
||||
uci commit bypass
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
@ -33,9 +33,8 @@ f_bin(){
|
||||
case $1 in
|
||||
ss)w=$(which ss-local);;
|
||||
ssr)w=$(which ssr-local);;
|
||||
vmess|vless)w=$(which xray);;
|
||||
v2ray)w=$(which xray);;
|
||||
trojan)w=$(which trojan-plus);;
|
||||
trojan-go)w=$(which trojan-go);;
|
||||
naiveproxy)w=$(which naive);;
|
||||
esac
|
||||
echo ${w:=0}
|
||||
@ -123,11 +122,11 @@ curl_check(){
|
||||
case $type in
|
||||
ss|ssr)
|
||||
$cmd -c $J >/dev/null 2>&1 &;;
|
||||
vmess|vless)
|
||||
v2ray)
|
||||
$S/genv2config $1 tcp 0 $lport $ip > $J
|
||||
sed -i 's/\\//g' $J
|
||||
$cmd -c $J >/dev/null 2>&1 &;;
|
||||
trojan|trojan-go)
|
||||
trojan)
|
||||
$S/gentrojanconfig $1 client $lport $ip > $J
|
||||
sed -i 's/\\//g' $J
|
||||
$cmd --config $J >/dev/null 2>&1 &;;
|
||||
|
369
luci-app-bypass/root/usr/share/bypass/gen_config
Normal file
369
luci-app-bypass/root/usr/share/bypass/gen_config
Normal file
@ -0,0 +1,369 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
local json = require "luci.jsonc"
|
||||
|
||||
local server_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local local_port = arg[3] or "0"
|
||||
local socks_port = arg[4] or "0"
|
||||
local ip_addr = arg[5]
|
||||
|
||||
local server = ucursor:get_all("bypass", server_section)
|
||||
local outbound_settings = nil
|
||||
|
||||
local tls_host = (server.tls_host) and server.tls_host or server.server
|
||||
|
||||
function vmess_vless()
|
||||
outbound_settings = {
|
||||
vnext = {
|
||||
{
|
||||
address = ip_addr,
|
||||
port = tonumber(server.server_port),
|
||||
users = {
|
||||
{
|
||||
id = server.vmess_id,
|
||||
security = (server.v2ray_protocol == "vmess" or not server.v2ray_protocol) and server.security or nil,
|
||||
encryption = (server.v2ray_protocol == "vless") and server.vless_encryption or nil,
|
||||
flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-splice") or nil
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
packetEncoding = server.packet_encoding or nil
|
||||
}
|
||||
end
|
||||
function trojan_shadowsocks()
|
||||
outbound_settings = {
|
||||
plugin = ((server.v2ray_protocol == "shadowsocks") and server.plugin ~= "none" and server.plugin) or (server.v2ray_protocol == "shadowsocksr" and "shadowsocksr") or nil,
|
||||
pluginOpts = (server.v2ray_protocol == "shadowsocks") and server.plugin_opts or nil,
|
||||
pluginArgs = (server.v2ray_protocol == "shadowsocksr") and {
|
||||
"--protocol=" .. server.protocol,
|
||||
"--protocol-param=" .. (server.protocol_param or ""),
|
||||
"--obfs=" .. server.obfs,
|
||||
"--obfs-param=" .. (server.obfs_param or "")
|
||||
} or nil,
|
||||
servers = {
|
||||
{
|
||||
address = ip_addr,
|
||||
port = tonumber(server.server_port),
|
||||
password = server.password,
|
||||
method = ((server.v2ray_protocol == "shadowsocks") and server.encrypt_method_ss) or ((server.v2ray_protocol == "shadowsocksr") and server.encrypt_method) or nil,
|
||||
uot = (server.v2ray_protocol == "shadowsocks") and (server.uot == '1') or nil,
|
||||
ivCheck = (server.v2ray_protocol == "shadowsocks") and (server.ivCheck == '1') or nil,
|
||||
flow = (server.v2ray_protocol == "trojan") and (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-splice") or nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if server.v2ray_protocol == "shadowsocksr" then
|
||||
server.v2ray_protocol = "shadowsocks"
|
||||
--[[ elseif (server.v2ray_protocol == "shadowsocks") and (server.mux ~= "1") and (not (outbound_settings.plugin or server.transport ~= "tcp" or server.tls or server.xtls)) then
|
||||
server.v2ray_protocol = "shadowsocks_sing"
|
||||
outbound_settings = outbound_settings.servers[1]
|
||||
elseif (server.v2ray_protocol == "trojan") and (server.tls and server.mux ~= "1") and (not (server.transport ~= "tcp" or server.xtls)) then
|
||||
server.v2ray_protocol = "trojan_sing"
|
||||
outbound_settings = outbound_settings.servers[1]
|
||||
outbound_settings.serverName = tls_host
|
||||
outbound_settings.insecure = (server.insecure == "1") and true or false
|
||||
]]
|
||||
end
|
||||
end
|
||||
function socks_http()
|
||||
outbound_settings = {
|
||||
version = server.socks_ver or nil,
|
||||
servers = {
|
||||
{
|
||||
address = ip_addr,
|
||||
port = tonumber(server.server_port),
|
||||
users = (server.auth_enable == "1") and {
|
||||
{
|
||||
user = server.username,
|
||||
pass = server.password
|
||||
}
|
||||
} or nil
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
function wireguard()
|
||||
outbound_settings = {
|
||||
address = ip_addr,
|
||||
port = tonumber(server.server_port),
|
||||
localAddresses = server.local_addresses,
|
||||
privateKey = server.private_key,
|
||||
peerPublicKey = server.peer_pubkey,
|
||||
preSharedKey = server.preshared_key or nil,
|
||||
mtu = tonumber(server.mtu) or 1500
|
||||
}
|
||||
end
|
||||
local outbound = {}
|
||||
function outbound:new(o)
|
||||
o = o or {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
function outbound:handleIndex(index)
|
||||
local switch = {
|
||||
vmess = function()
|
||||
vmess_vless()
|
||||
end,
|
||||
vless = function()
|
||||
vmess_vless()
|
||||
end,
|
||||
trojan = function()
|
||||
trojan_shadowsocks()
|
||||
end,
|
||||
shadowsocks = function()
|
||||
trojan_shadowsocks()
|
||||
end,
|
||||
shadowsocksr = function()
|
||||
trojan_shadowsocks()
|
||||
end,
|
||||
socks = function()
|
||||
socks_http()
|
||||
end,
|
||||
http = function()
|
||||
socks_http()
|
||||
end,
|
||||
wireguard = function()
|
||||
wireguard()
|
||||
end
|
||||
}
|
||||
if switch[index] then
|
||||
switch[index]()
|
||||
end
|
||||
end
|
||||
local settings = outbound:new()
|
||||
settings:handleIndex(server.v2ray_protocol)
|
||||
local Xray = {
|
||||
log = {
|
||||
-- error = "/var/ssrplus.log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
inbound = (local_port ~= "0") and {
|
||||
-- listening
|
||||
port = tonumber(local_port),
|
||||
protocol = "dokodemo-door",
|
||||
settings = {network = proto, followRedirect = true},
|
||||
sniffing = {enabled = true, destOverride = {"http", "tls"}}
|
||||
} or nil,
|
||||
-- 开启 socks 代理
|
||||
inboundDetour = (proto:find("tcp") and socks_port ~= "0") and {
|
||||
{
|
||||
-- socks
|
||||
protocol = "socks",
|
||||
port = tonumber(socks_port),
|
||||
settings = {auth = "noauth", udp = true}
|
||||
}
|
||||
} or nil,
|
||||
-- 传出连接
|
||||
outbound = {
|
||||
protocol = server.v2ray_protocol,
|
||||
settings = outbound_settings,
|
||||
-- 底层传输配置
|
||||
streamSettings = (server.v2ray_protocol and server.v2ray_protocol:sub(-#"_sing") ~= "_sing") and {
|
||||
network = server.transport or "tcp",
|
||||
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or nil,
|
||||
tlsSettings = (server.tls == '1' and (server.insecure == "1" or tls_host or server.fingerprint)) and {
|
||||
-- tls
|
||||
fingerprint = server.fingerprint,
|
||||
allowInsecure = (server.insecure == "1") and true or nil,
|
||||
serverName = tls_host
|
||||
} or nil,
|
||||
xtlsSettings = (server.xtls == '1' and (server.insecure == "1" or tls_host)) and {
|
||||
-- xtls
|
||||
allowInsecure = (server.insecure == "1") and true or nil,
|
||||
serverName = tls_host
|
||||
} or nil,
|
||||
tcpSettings = (server.transport == "tcp" and server.tcp_guise == "http") and {
|
||||
-- tcp
|
||||
header = {
|
||||
type = server.tcp_guise,
|
||||
request = {
|
||||
-- request
|
||||
path = {server.http_path} or {"/"},
|
||||
headers = {Host = {server.http_host} or {}}
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
kcpSettings = (server.transport == "kcp") and {
|
||||
mtu = tonumber(server.mtu),
|
||||
tti = tonumber(server.tti),
|
||||
uplinkCapacity = tonumber(server.uplink_capacity),
|
||||
downlinkCapacity = tonumber(server.downlink_capacity),
|
||||
congestion = (server.congestion == "1") and true or false,
|
||||
readBufferSize = tonumber(server.read_buffer_size),
|
||||
writeBufferSize = tonumber(server.write_buffer_size),
|
||||
header = {type = server.kcp_guise},
|
||||
seed = server.seed or nil
|
||||
} or nil,
|
||||
wsSettings = (server.transport == "ws") and (server.ws_path or server.ws_host or tls_host) and {
|
||||
-- ws
|
||||
headers = (server.ws_host or tls_host) and {
|
||||
-- headers
|
||||
Host = server.ws_host or tls_host
|
||||
} or nil,
|
||||
path = server.ws_path,
|
||||
maxEarlyData = tonumber(server.ws_ed) or nil,
|
||||
earlyDataHeaderName = server.ws_ed_header or nil
|
||||
} or nil,
|
||||
httpSettings = (server.transport == "h2") and {
|
||||
-- h2
|
||||
path = server.h2_path or "",
|
||||
host = {server.h2_host} or nil,
|
||||
read_idle_timeout = tonumber(server.read_idle_timeout) or nil,
|
||||
health_check_timeout = tonumber(server.health_check_timeout) or nil
|
||||
} or nil,
|
||||
quicSettings = (server.transport == "quic") and {
|
||||
-- quic
|
||||
security = server.quic_security,
|
||||
key = server.quic_key,
|
||||
header = {type = server.quic_guise}
|
||||
} or nil,
|
||||
grpcSettings = (server.transport == "grpc") and {
|
||||
-- grpc
|
||||
serviceName = server.serviceName or "",
|
||||
mode = (server.grpc_mode ~= "gun") and server.grpc_mode or nil,
|
||||
multiMode = (server.grpc_mode == "multi") and true or false,
|
||||
idle_timeout = tonumber(server.idle_timeout) or nil,
|
||||
health_check_timeout = tonumber(server.health_check_timeout) or nil,
|
||||
permit_without_stream = (server.permit_without_stream == "1") and true or nil,
|
||||
initial_windows_size = tonumber(server.initial_windows_size) or nil
|
||||
} or nil
|
||||
} or nil,
|
||||
mux = (server.mux == "1" and server.xtls ~= "1" and server.transport ~= "grpc") and {
|
||||
-- mux
|
||||
enabled = true,
|
||||
concurrency = tonumber(server.concurrency),
|
||||
packetEncoding = (server.v2ray_protocol == "vmess" or server.v2ray_protocol == "vless") and server.packet_encoding or nil
|
||||
} or nil
|
||||
} or nil
|
||||
}
|
||||
local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
|
||||
local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"
|
||||
local trojan = {
|
||||
log_level = 3,
|
||||
run_type = (proto == "nat" or proto == "tcp") and "nat" or "client",
|
||||
local_addr = "0.0.0.0",
|
||||
local_port = tonumber(local_port),
|
||||
remote_addr = ip_addr,
|
||||
remote_port = tonumber(server.server_port),
|
||||
udp_timeout = 60,
|
||||
-- 传入连接
|
||||
password = {server.password},
|
||||
-- 传出连接
|
||||
ssl = {
|
||||
verify = (server.insecure == "0") and true or false,
|
||||
verify_hostname = (server.tls == "1") and true or false,
|
||||
cert = (server.certificate) and server.certpath or nil,
|
||||
cipher = cipher,
|
||||
cipher_tls13 = cipher13,
|
||||
sni = tls_host,
|
||||
alpn = {"h2", "http/1.1"},
|
||||
curve = "",
|
||||
reuse_session = true,
|
||||
session_ticket = (server.tls_sessionTicket == "1") and true or false
|
||||
},
|
||||
udp_timeout = 60,
|
||||
tcp = {
|
||||
-- tcp
|
||||
no_delay = true,
|
||||
keep_alive = true,
|
||||
reuse_port = true,
|
||||
fast_open = (server.fast_open == "1") and true or false,
|
||||
fast_open_qlen = 20
|
||||
}
|
||||
}
|
||||
local naiveproxy = {
|
||||
proxy = (server.username and server.password and server.server and server.server_port) and "https://" .. server.username .. ":" .. server.password .. "@" .. ip_addr .. ":" .. server.server_port,
|
||||
listen = (proto == "redir") and "redir" .. "://0.0.0.0:" .. tonumber(local_port) or "socks" .. "://0.0.0.0:" .. tonumber(local_port),
|
||||
["insecure-concurrency"] = tonumber(server.concurrency) or 1
|
||||
}
|
||||
local ss = {
|
||||
server = (server.kcp_enable == "1") and "127.0.0.1" or ip_addr,
|
||||
server_port = tonumber(server.server_port),
|
||||
local_address = "0.0.0.0",
|
||||
local_port = tonumber(local_port),
|
||||
mode = (proto == "tcp,udp") and "tcp_and_udp" or proto .. "_only",
|
||||
password = server.password,
|
||||
method = server.encrypt_method_ss,
|
||||
timeout = tonumber(server.timeout),
|
||||
fast_open = (server.fast_open == "1") and true or false,
|
||||
reuse_port = true
|
||||
}
|
||||
local hysteria = {
|
||||
server = ip_addr .. ":" .. server.server_port,
|
||||
protocol = server.hysteria_protocol,
|
||||
up_mbps = tonumber(server.uplink_capacity),
|
||||
down_mbps = tonumber(server.downlink_capacity),
|
||||
socks5 = (proto:find("tcp") and tonumber(socks_port) and tonumber(socks_port) ~= "0") and {
|
||||
listen = "0.0.0.0:" .. tonumber(socks_port),
|
||||
timeout = 300,
|
||||
disable_udp = false
|
||||
} or nil,
|
||||
redirect_tcp = (proto:find("tcp") and local_port ~= "0") and {
|
||||
listen = "0.0.0.0:" .. tonumber(local_port),
|
||||
timeout = 300
|
||||
} or nil,
|
||||
tproxy_udp = (proto:find("udp") and local_port ~= "0") and {
|
||||
listen = "0.0.0.0:" .. tonumber(local_port),
|
||||
timeout = 60
|
||||
} or nil,
|
||||
obfs = server.seed,
|
||||
auth = (server.auth_type == "1") and server.auth_payload or nil,
|
||||
auth_str = (server.auth_type == "2") and server.auth_payload or nil,
|
||||
alpn = server.quic_tls_alpn,
|
||||
server_name = tls_host,
|
||||
insecure = (server.insecure == "1") and true or false,
|
||||
ca = (server.certificate) and server.certpath or nil,
|
||||
recv_window_conn = tonumber(server.recv_window_conn),
|
||||
recv_window = tonumber(server.recv_window),
|
||||
disable_mtu_discovery = (server.disable_mtu_discovery == "1") and true or false
|
||||
}
|
||||
local config = {}
|
||||
function config:new(o)
|
||||
o = o or {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
function config:handleIndex(index)
|
||||
local switch = {
|
||||
ss = function()
|
||||
ss.protocol = socks_port
|
||||
if server.plugin and server.plugin ~= "none" then
|
||||
ss.plugin = server.plugin
|
||||
ss.plugin_opts = server.plugin_opts or nil
|
||||
end
|
||||
print(json.stringify(ss, 1))
|
||||
end,
|
||||
ssr = function()
|
||||
ss.protocol = server.protocol
|
||||
ss.protocol_param = server.protocol_param
|
||||
ss.method = server.encrypt_method
|
||||
ss.obfs = server.obfs
|
||||
ss.obfs_param = server.obfs_param
|
||||
print(json.stringify(ss, 1))
|
||||
end,
|
||||
v2ray = function()
|
||||
print(json.stringify(Xray, 1))
|
||||
end,
|
||||
trojan = function()
|
||||
print(json.stringify(trojan, 1))
|
||||
end,
|
||||
naiveproxy = function()
|
||||
print(json.stringify(naiveproxy, 1))
|
||||
end,
|
||||
hysteria = function()
|
||||
print(json.stringify(hysteria, 1))
|
||||
end
|
||||
}
|
||||
if switch[index] then
|
||||
switch[index]()
|
||||
end
|
||||
end
|
||||
local f = config:new()
|
||||
f:handleIndex(server.type)
|
@ -1,73 +0,0 @@
|
||||
#!/usr/bin/lua
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
local json = require "luci.jsonc"
|
||||
local node_section = arg[1]
|
||||
local run_type = arg[2]
|
||||
local local_port = arg[3]
|
||||
local ip_addr=arg[4]
|
||||
local threads = tonumber(arg[5]) or 2
|
||||
|
||||
local node = ucursor:get_all("bypass", node_section)
|
||||
|
||||
local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
|
||||
local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"
|
||||
local trojan = {
|
||||
run_type = run_type,
|
||||
local_addr = "0.0.0.0",
|
||||
local_port = tonumber(local_port),
|
||||
remote_addr = ip_addr,
|
||||
remote_port = tonumber(node.server_port),
|
||||
password = {node.password},
|
||||
log_level = 3,
|
||||
ssl = {
|
||||
verify = (node.insecure ~= "1") and true or false,
|
||||
verify_hostname = true,
|
||||
cert = "",
|
||||
cipher = cipher,
|
||||
cipher_tls13 = cipher13,
|
||||
sni = node.tls_host or node.server,
|
||||
alpn = {"h2", "http/1.1"},
|
||||
reuse_session = true,
|
||||
session_ticket = (node.tls_sessionTicket and node.tls_sessionTicket == "1") and true or false,
|
||||
curves = ""
|
||||
},
|
||||
udp_timeout = 60,
|
||||
mux = (node.mux == "1") and {
|
||||
enabled = true,
|
||||
concurrency = tonumber(node.concurrency),
|
||||
idle_timeout = 60,
|
||||
} or nil,
|
||||
tcp = {
|
||||
no_delay = true,
|
||||
keep_alive = true,
|
||||
reuse_port = (threads > 1) and true or false,
|
||||
fast_open = (node.fast_open == "1") and true or false,
|
||||
fast_open_qlen = 20
|
||||
}
|
||||
}
|
||||
if node.type == "trojan-go" then
|
||||
trojan.ssl.cipher = node.fingerprint == nil and cipher or (node.fingerprint == "disable" and cipher13 .. ":" .. cipher or "")
|
||||
trojan.ssl.cipher_tls13 = node.fingerprint == nil and cipher13 or nil
|
||||
trojan.ssl.fingerprint = (node.fingerprint ~= nil and node.fingerprint ~= "disable" ) and node.fingerprint or ""
|
||||
trojan.ssl.alpn = node.trojan_transport == 'ws' and {} or {"h2", "http/1.1"}
|
||||
if node.tls ~= "1" and node.trojan_transport == "original" then trojan.ssl = nil end
|
||||
trojan.transport_plugin = node.tls ~= "1" and node.trojan_transport == "original" and {
|
||||
enabled = node.plugin_type ~= nil,
|
||||
type = node.plugin_type or "plaintext",
|
||||
command = node.plugin_type ~= "plaintext" and node.plugin_cmd or nil,
|
||||
option = node.plugin_type ~= "plaintext" and node.plugin_option or nil,
|
||||
arg = node.plugin_type ~= "plaintext" and { node.plugin_arg } or nil,
|
||||
env = {}
|
||||
} or nil
|
||||
trojan.websocket = node.trojan_transport and node.trojan_transport:find('ws') and {
|
||||
enabled = true,
|
||||
path = node.ws_path or "/",
|
||||
host = node.ws_host or (node.tls_serverName or node.address)
|
||||
} or nil
|
||||
trojan.shadowsocks = (node.ss_aead == "1") and {
|
||||
enabled = true,
|
||||
method = node.ss_aead_method or "aead_aes_128_gcm",
|
||||
password = node.ss_aead_pwd or ""
|
||||
} or nil
|
||||
end
|
||||
print(json.stringify(trojan, 1))
|
@ -1,123 +0,0 @@
|
||||
#!/usr/bin/lua
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
local json = require "luci.jsonc"
|
||||
local server_section = arg[1]
|
||||
local proto = arg[2]
|
||||
local local_port = arg[3] or "0"
|
||||
local socks_port = arg[4] or "0"
|
||||
local ip_addr = arg[5]
|
||||
local server = ucursor:get_all("bypass", server_section)
|
||||
local Xray = {
|
||||
log = {
|
||||
-- error = "/var/bypass.log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
inbound = (local_port ~= "0") and {
|
||||
port = tonumber(local_port),
|
||||
protocol = "dokodemo-door",
|
||||
settings = {
|
||||
network = proto,
|
||||
followRedirect = true
|
||||
},
|
||||
sniffing = {
|
||||
enabled = true,
|
||||
destOverride = { "http", "tls" }
|
||||
}
|
||||
} or nil,
|
||||
-- 开启 socks 代理
|
||||
inboundDetour = (proto == "tcp" and socks_port ~= "0") and {
|
||||
{
|
||||
protocol = "socks",
|
||||
port = socks_port,
|
||||
settings = {
|
||||
auth = "noauth",
|
||||
udp = true
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
-- 传出连接
|
||||
outbound = {
|
||||
protocol = server.type,
|
||||
settings = {
|
||||
vnext = {
|
||||
{
|
||||
address = ip_addr,
|
||||
port = tonumber(server.server_port),
|
||||
users = {
|
||||
{
|
||||
id = server.uuid,
|
||||
alterId = (server.type == "vmess") and tonumber(server.alter_id) or nil,
|
||||
security = (server.type == "vmess") and server.security or nil,
|
||||
encryption = (server.type == "vless") and server.vless_encryption or nil,
|
||||
flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-splice") or nil,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
-- 底层传输配置
|
||||
streamSettings = {
|
||||
network = server.transport,
|
||||
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or "none",
|
||||
tlsSettings = (server.tls == '1') and {
|
||||
allowInsecure = (server.insecure == "1") and true or nil,
|
||||
serverName = (server.tls_host) and server.tls_host or server.server
|
||||
} or nil,
|
||||
xtlsSettings = (server.xtls == '1') and {
|
||||
allowInsecure = (server.insecure == "1") and true or nil,
|
||||
serverName = (server.tls_host) and server.tls_host or server.server
|
||||
} or nil,
|
||||
tcpSettings = (server.transport == "tcp" and server.tcp_guise == "http") and {
|
||||
header = {
|
||||
type = server.tcp_guise,
|
||||
request = {
|
||||
path = {server.http_path} or {"/"},
|
||||
headers = {
|
||||
Host = {server.http_host} or {}
|
||||
}
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
kcpSettings = (server.transport == "kcp") and {
|
||||
mtu = tonumber(server.mtu),
|
||||
tti = tonumber(server.tti),
|
||||
uplinkCapacity = tonumber(server.uplink_capacity),
|
||||
downlinkCapacity = tonumber(server.downlink_capacity),
|
||||
congestion = (server.congestion == "1") and true or false,
|
||||
readBufferSize = tonumber(server.read_buffer_size),
|
||||
writeBufferSize = tonumber(server.write_buffer_size),
|
||||
header = {
|
||||
type = server.kcp_guise
|
||||
},
|
||||
seed = server.seed or nil
|
||||
} or nil,
|
||||
wsSettings = (server.transport == "ws") and (server.ws_path or server.ws_host or server.tls_host) and {
|
||||
path = server.ws_path,
|
||||
headers = (server.ws_host or server.tls_host) and {
|
||||
Host = server.ws_host or server.tls_host
|
||||
} or nil,
|
||||
} or nil,
|
||||
httpSettings = (server.transport == "h2") and {
|
||||
path = server.h2_path or "",
|
||||
host = {server.h2_host} or nil
|
||||
} or nil,
|
||||
quicSettings = (server.transport == "quic") and {
|
||||
security = server.quic_security,
|
||||
key = server.quic_key,
|
||||
header = {
|
||||
type = server.quic_guise
|
||||
}
|
||||
} or nil,
|
||||
grpcSettings = (server.transport == "grpc") and {
|
||||
serviceName = server.grpc_serviceName,
|
||||
MultiMode = (server.gRPC_MultiMode == "1") and true or nil
|
||||
} or nil
|
||||
},
|
||||
mux = (server.mux == "1" and server.xtls ~= "1") and {
|
||||
enabled = true,
|
||||
concurrency = tonumber(server.concurrency)
|
||||
} or nil
|
||||
} or nil
|
||||
}
|
||||
print(json.stringify(Xray,1))
|
@ -9,6 +9,7 @@ require "nixio"
|
||||
require "luci.util"
|
||||
require "luci.sys"
|
||||
require "luci.jsonc"
|
||||
require "luci.model.ipkg"
|
||||
-- these global functions are accessed all the time by the event handler
|
||||
-- so caching them is worth the effort
|
||||
local tinsert = table.insert
|
||||
@ -16,31 +17,41 @@ local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.
|
||||
local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
|
||||
local b64decode = nixio.bin.b64decode
|
||||
local cache = {}
|
||||
local nodeResult = setmetatable({}, { __index = cache }) -- update result
|
||||
local nodeResult = setmetatable({}, {__index = cache}) -- update result
|
||||
local name = 'bypass'
|
||||
local uciType = 'servers'
|
||||
local ucic = luci.model.uci.cursor()
|
||||
local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0')
|
||||
local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1')
|
||||
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
|
||||
local filter_mode = ucic:get_first(name, 'server_subscribe', 'filter_mode', '0')
|
||||
|
||||
local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量')
|
||||
local save_words = ucic:get_first(name, 'server_subscribe', 'save_words', '')
|
||||
local packet_encoding = luci.model.ipkg.installed("sagernet-core") and ucic:get_first(name, 'global', 'default_packet_encoding', 'xudp') or nil
|
||||
local v2_ss = luci.sys.exec('type -t -p ss-redir sslocal') ~= "" and "ss" or "v2ray"
|
||||
local v2_tj = luci.sys.exec('type -t -p trojan-plus') ~= "" and "trojan" or "v2ray"
|
||||
local v2_ssr = luci.sys.exec('type -t -p ssr-redir') ~= "" and "ssr" or "v2ray"
|
||||
local v2_tj = luci.sys.exec('type -t -p trojan') ~= "" and "trojan" or "v2ray"
|
||||
local log = function(...)
|
||||
local file = io.open("/var/log/bypass.log", "a")
|
||||
io.output(file)
|
||||
io.write(os.date("%Y-%m-%d %H:%M:%S ") .. "Subscribe : " .. table.concat({ ... }, " ") .. "\n")
|
||||
io.close(file)
|
||||
|
||||
|
||||
print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " "))
|
||||
|
||||
end
|
||||
local encrypt_methods_ss = {
|
||||
-- plain
|
||||
"none",
|
||||
"plain",
|
||||
-- aead
|
||||
"aes-128-gcm",
|
||||
"aes-192-gcm",
|
||||
"aes-256-gcm",
|
||||
"chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305",
|
||||
--stream
|
||||
-- aead 2022
|
||||
"2022-blake3-aes-128-gcm",
|
||||
"2022-blake3-aes-256-gcm",
|
||||
"2022-blake3-chacha20-poly1305"
|
||||
--[[ stream
|
||||
"table",
|
||||
"rc4",
|
||||
"rc4-md5",
|
||||
@ -56,7 +67,7 @@ local encrypt_methods_ss = {
|
||||
"camellia-256-cfb",
|
||||
"salsa20",
|
||||
"chacha20",
|
||||
"chacha20-ietf"
|
||||
"chacha20-ietf" ]]
|
||||
}
|
||||
-- 分割字符串
|
||||
local function split(full, sep)
|
||||
@ -135,7 +146,7 @@ end
|
||||
-- https://www.04007.cn/article/135.html
|
||||
local function checkTabValue(tab)
|
||||
local revtab = {}
|
||||
for k, v in pairs(tab) do
|
||||
for k,v in pairs(tab) do
|
||||
revtab[v] = true
|
||||
end
|
||||
return revtab
|
||||
@ -143,10 +154,12 @@ end
|
||||
|
||||
-- 处理数据
|
||||
local function processData(szType, content)
|
||||
local result = { type = szType, local_port = 1234, kcp_param = '--nocomp' }
|
||||
local result = {type = szType, local_port = 1234, kcp_param = '--nocomp'}
|
||||
if szType == 'ssr' then
|
||||
local dat = split(content, "/%?")
|
||||
local hostInfo = split(dat[1], ':')
|
||||
result.type = v2_ssr
|
||||
result.v2ray_protocol = (v2_ssr == "v2ray") and "shadowsocksr" or nil
|
||||
result.server = hostInfo[1]
|
||||
result.server_port = hostInfo[2]
|
||||
result.protocol = hostInfo[3]
|
||||
@ -167,14 +180,15 @@ local function processData(szType, content)
|
||||
result.alias = result.alias .. base64Decode(params.remarks)
|
||||
elseif szType == 'vmess' then
|
||||
local info = jsonParse(content)
|
||||
result.type = 'vmess'
|
||||
result.type = 'v2ray'
|
||||
result.v2ray_protocol = 'vmess'
|
||||
result.server = info.add
|
||||
result.server_port = info.port
|
||||
result.transport = info.net
|
||||
result.alter_id = info.aid
|
||||
result.uuid = info.id
|
||||
result.vmess_id = info.id
|
||||
|
||||
result.alias = info.ps
|
||||
result.packet_encoding = packet_encoding
|
||||
-- result.mux = 1
|
||||
-- result.concurrency = 8
|
||||
if info.net == 'ws' then
|
||||
@ -202,24 +216,39 @@ local function processData(szType, content)
|
||||
result.read_buffer_size = 2
|
||||
result.write_buffer_size = 2
|
||||
end
|
||||
if info.net == 'grpc' then
|
||||
if info.path then
|
||||
result.serviceName = info.path
|
||||
elseif info.serviceName then
|
||||
result.serviceName = info.serviceName
|
||||
end
|
||||
end
|
||||
if info.net == 'quic' then
|
||||
result.quic_guise = info.type
|
||||
result.quic_key = info.key
|
||||
result.quic_security = info.securty
|
||||
end
|
||||
if info.net == 'grpc' then
|
||||
result.grpc_serviceName = info.path
|
||||
end
|
||||
|
||||
|
||||
|
||||
if info.security then
|
||||
result.security = info.security
|
||||
end
|
||||
if info.tls == "tls" or info.tls == "1" then
|
||||
result.tls = "1"
|
||||
result.tls_host = info.host
|
||||
if info.host then
|
||||
result.tls_host = info.host
|
||||
elseif info.sni then
|
||||
result.tls_host = info.sni
|
||||
end
|
||||
result.insecure = 1
|
||||
else
|
||||
result.tls = "0"
|
||||
end
|
||||
-- https://www.v2fly.org/config/protocols/vmess.html#vmess-md5-认证信息-淘汰机制
|
||||
if info.aid and (tonumber(info.aid) > 0) then
|
||||
result.server = nil
|
||||
end
|
||||
elseif szType == "ss" then
|
||||
local idx_sp = 0
|
||||
local alias = ""
|
||||
@ -235,7 +264,9 @@ local function processData(szType, content)
|
||||
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
|
||||
result.alias = UrlDecode(alias)
|
||||
result.type = v2_ss
|
||||
result.v2ray_protocol = "shadowsocks"
|
||||
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], "/%?")
|
||||
@ -260,18 +291,18 @@ local function processData(szType, content)
|
||||
end
|
||||
end
|
||||
else
|
||||
result.server_port = host[2]
|
||||
result.server_port = host[2]:gsub("/","")
|
||||
end
|
||||
if checkTabValue(encrypt_methods_ss)[method] then
|
||||
result.encrypt_method_ss = method
|
||||
result.password = password
|
||||
else
|
||||
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 = "shadowsocks"
|
||||
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
|
||||
result.server = content.server
|
||||
result.server_port = content.server_port
|
||||
result.password = content.password
|
||||
@ -284,18 +315,23 @@ local function processData(szType, content)
|
||||
end
|
||||
elseif szType == "ssd" then
|
||||
result.type = v2_ss
|
||||
result.v2ray_protocol = "shadowsocks"
|
||||
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
|
||||
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 checkTabValue(encrypt_methods_ss)[result.encrypt_method_ss] then
|
||||
result.server = nil
|
||||
elseif result.plugin == "simple-obfs" then
|
||||
|
||||
|
||||
if content.plugin == "simple-obfs" then
|
||||
result.plugin = "obfs-local"
|
||||
else
|
||||
result.plugin = content.plugin
|
||||
end
|
||||
if not checkTabValue(encrypt_methods_ss)[content.encryption] then
|
||||
result.server = nil
|
||||
end
|
||||
elseif szType == "trojan" then
|
||||
local idx_sp = 0
|
||||
@ -351,13 +387,14 @@ local function processData(szType, content)
|
||||
params[t[1]] = t[2]
|
||||
end
|
||||
result.alias = UrlDecode(alias)
|
||||
result.type = 'vless'
|
||||
result.type = 'v2ray'
|
||||
result.v2ray_protocol = 'vless'
|
||||
result.server = host[1]
|
||||
result.server_port = query[1]
|
||||
result.uuid = uuid
|
||||
result.vmess_id = uuid
|
||||
result.vless_encryption = params.encryption or "none"
|
||||
result.transport = params.type and (params.type == 'http' and 'h2' or params.type) or "tcp"
|
||||
result.packet_encoding = packet_encoding
|
||||
if not params.type or params.type == "tcp" then
|
||||
if params.security == "xtls" then
|
||||
result.xtls = "1"
|
||||
@ -391,8 +428,8 @@ local function processData(szType, content)
|
||||
result.quic_security = params.quicSecurity or "none"
|
||||
end
|
||||
if params.type == 'grpc' then
|
||||
if params.path then result.grpc_serviceName = params.path end
|
||||
if params.serviceName then result.grpc_serviceName = params.serviceName end
|
||||
|
||||
result.serviceName = params.serviceName
|
||||
end
|
||||
if params.security == "tls" then
|
||||
result.tls = "1"
|
||||
@ -421,22 +458,54 @@ local function processData(szType, content)
|
||||
result.switch_enable = switch_enable
|
||||
return result
|
||||
end
|
||||
|
||||
-- curl
|
||||
local function curl(url)
|
||||
local stdout = luci.sys.exec('curl --retry 3 -m 10 -LfskA "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36" "' .. url .. '"')
|
||||
-- wget
|
||||
|
||||
local function wget(url)
|
||||
local stdout = luci.sys.exec('wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36" --no-check-certificate -O- "' .. url .. '"')
|
||||
return trim(stdout)
|
||||
end
|
||||
|
||||
local function check_filer(result)
|
||||
local filter_word = split(filter_words, "/")
|
||||
for i, v in pairs(filter_word) do
|
||||
if result.alias:find(v) then
|
||||
-- log('命中关键词:“'..v..'” pwd')
|
||||
return filter_mode == '0'
|
||||
do
|
||||
-- 过滤的关键词列表
|
||||
local filter_word = split(filter_words, "/")
|
||||
-- 保留的关键词列表
|
||||
local check_save = false
|
||||
if save_words ~= nil and save_words ~= "" and save_words ~= "NULL" then
|
||||
check_save = true
|
||||
end
|
||||
local save_word = split(save_words, "/")
|
||||
|
||||
-- 检查结果
|
||||
local filter_result = false
|
||||
local save_result = true
|
||||
|
||||
-- 检查是否存在过滤关键词
|
||||
for i, v in pairs(filter_word) do
|
||||
if tostring(result.alias):find(v, nil, true) then
|
||||
filter_result = true
|
||||
end
|
||||
end
|
||||
|
||||
-- 检查是否打开了保留关键词检查,并且进行过滤
|
||||
if check_save == true then
|
||||
for i, v in pairs(save_word) do
|
||||
if tostring(result.alias):find(v, nil, true) then
|
||||
save_result = false
|
||||
end
|
||||
end
|
||||
else
|
||||
save_result = false
|
||||
end
|
||||
|
||||
-- 不等时返回
|
||||
if filter_result == true or save_result == true then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
return filter_mode == '1'
|
||||
|
||||
end
|
||||
|
||||
local execute = function()
|
||||
@ -447,7 +516,7 @@ local execute = function()
|
||||
luci.sys.init.stop(name)
|
||||
end
|
||||
for k, url in ipairs(subscribe_url) do
|
||||
local raw = curl(url)
|
||||
local raw = wget(url)
|
||||
if #raw > 0 then
|
||||
local nodes, szType
|
||||
local groupHash = md5(url)
|
||||
@ -460,16 +529,16 @@ local execute = function()
|
||||
local nEnd = select(2, raw:find('ssd://'))
|
||||
nodes = base64Decode(raw:sub(nEnd + 1, #raw))
|
||||
nodes = jsonParse(nodes)
|
||||
local extra = { airport = nodes.airport, port = nodes.port, encryption = nodes.encryption, password = nodes.password }
|
||||
local extra = {airport = nodes.airport, port = nodes.port, encryption = nodes.encryption, password = nodes.password}
|
||||
local servers = {}
|
||||
-- SS里面包着 干脆直接这样
|
||||
for _, server in ipairs(nodes.servers) do
|
||||
tinsert(servers, setmetatable(server, { __index = extra }))
|
||||
tinsert(servers, setmetatable(server, {__index = extra}))
|
||||
end
|
||||
nodes = servers
|
||||
-- SS SIP008 直接使用 Json 格式
|
||||
-- SS SIP008 直接使用 Json 格式
|
||||
elseif jsonParse(raw) then
|
||||
nodes = jsonParse(raw)
|
||||
nodes = jsonParse(raw).servers or jsonParse(raw)
|
||||
if nodes[1].server and nodes[1].method then
|
||||
szType = 'sip008'
|
||||
end
|
||||
@ -539,7 +608,7 @@ local execute = function()
|
||||
local dat = nodeResult[old.grouphashkey][old.hashkey]
|
||||
ucic:tset(name, old['.name'], dat)
|
||||
-- 标记一下
|
||||
setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index = { _ignore = true } })
|
||||
setmetatable(nodeResult[old.grouphashkey][old.hashkey], {__index = {_ignore = true}})
|
||||
end
|
||||
else
|
||||
if not old.alias then
|
||||
|
@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=naiveproxy
|
||||
PKG_VERSION:=103.0.5060.53-2
|
||||
PKG_VERSION:=103.0.5060.53-3
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/klzgrad/naiveproxy/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=68830ad9d363e24bf1006fe6781c22c00fe6fdafe6c6faf98fb6cbdb80810499
|
||||
PKG_HASH:=29ffeb8ee5354739f5445f82665d03fbc78aa34c967d4a5a1d106ae7fa23a918
|
||||
|
||||
PKG_LICENSE:=BSD 3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
Loading…
Reference in New Issue
Block a user