From da8965e832c3f25dafe4d9a43ccdf962fc8bbae2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Jul 2022 20:18:42 +0800 Subject: [PATCH] update 2022-07-07 20:18:42 --- luci-app-bypass/Makefile | 20 +- .../luasrc/model/cbi/bypass/client-config.lua | 771 +++++++++------- .../luasrc/model/cbi/bypass/servers.lua | 2 +- .../luasrc/model/cbi/bypass/trojan_go.lua | 179 ---- luci-app-bypass/luasrc/view/bypass/link.htm | 831 ------------------ luci-app-bypass/luasrc/view/bypass/ssrurl.htm | 366 ++++++++ .../luasrc/view/bypass/trojan_go_version.htm | 172 ---- luci-app-bypass/po/zh-cn/bypass.po | 26 +- luci-app-bypass/root/etc/init.d/bypass | 57 +- .../root/etc/uci-defaults/luci-bypass | 13 +- .../root/usr/share/bypass/by-switch | 7 +- .../root/usr/share/bypass/gen_config | 369 ++++++++ .../root/usr/share/bypass/gentrojanconfig | 73 -- .../root/usr/share/bypass/genv2config | 123 --- .../root/usr/share/bypass/subscribe | 171 ++-- naiveproxy/Makefile | 4 +- 16 files changed, 1401 insertions(+), 1783 deletions(-) delete mode 100644 luci-app-bypass/luasrc/model/cbi/bypass/trojan_go.lua delete mode 100644 luci-app-bypass/luasrc/view/bypass/link.htm create mode 100644 luci-app-bypass/luasrc/view/bypass/ssrurl.htm delete mode 100644 luci-app-bypass/luasrc/view/bypass/trojan_go_version.htm create mode 100644 luci-app-bypass/root/usr/share/bypass/gen_config delete mode 100755 luci-app-bypass/root/usr/share/bypass/gentrojanconfig delete mode 100755 luci-app-bypass/root/usr/share/bypass/genv2config diff --git a/luci-app-bypass/Makefile b/luci-app-bypass/Makefile index ddd962b7..821eb728 100644 --- a/luci-app-bypass/Makefile +++ b/luci-app-bypass/Makefile @@ -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" diff --git a/luci-app-bypass/luasrc/model/cbi/bypass/client-config.lua b/luci-app-bypass/luasrc/model/cbi/bypass/client-config.lua index 2cb5a4a1..7011d940 100644 --- a/luci-app-bypass/luasrc/model/cbi/bypass/client-config.lua +++ b/luci-app-bypass/luasrc/model/cbi/bypass/client-config.lua @@ -4,134 +4,131 @@ require "nixio.fs" require "luci.sys" require "luci.http" -local m, s, o, kcp_enable -local bypass = "bypass" +require "luci.model.ipkg" + +local m, s, o local sid = arg[1] local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid") -local A=luci.sys.call("which obfs-local >/dev/null") -local B=luci.sys.call("which v2ray-plugin >/dev/null") -local function isKcptun(file) -if not nixio.fs.access(file, "rwx", "rx", "rx") then -nixio.fs.chmod(file, 755) +local function is_finded(e) + return luci.sys.exec('type -t -p "%s"' % e) ~= "" and true or false end -local str = luci.sys.exec(file .. " -v | awk '{printf $1}'") -return (str:lower() == "kcptun") + +local function is_installed(e) + return luci.model.ipkg.installed(e) end local server_table = {} local encrypt_methods = { -"none", -"table", -"rc4", -"rc4-md5-6", -"rc4-md5", -"aes-128-cfb", -"aes-192-cfb", -"aes-256-cfb", -"aes-128-ctr", -"aes-192-ctr", -"aes-256-ctr", -"bf-cfb", -"camellia-128-cfb", -"camellia-192-cfb", -"camellia-256-cfb", -"cast5-cfb", -"des-cfb", -"idea-cfb", -"rc2-cfb", -"seed-cfb", -"salsa20", -"chacha20", -"chacha20-ietf", + -- ssr + "none", + "table", + "rc4", + "rc4-md5-6", + "rc4-md5", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "cast5-cfb", + "des-cfb", + "idea-cfb", + "rc2-cfb", + "seed-cfb", + "salsa20", + "chacha20", + "chacha20-ietf" } local encrypt_methods_ss = { --- aead -"aes-128-gcm", -"aes-192-gcm", -"aes-256-gcm", -"chacha20-ietf-poly1305", -"xchacha20-ietf-poly1305", --- stream -"table", -"rc4", -"rc4-md5", -"aes-128-cfb", -"aes-192-cfb", -"aes-256-cfb", -"aes-128-ctr", -"aes-192-ctr", -"aes-256-ctr", -"bf-cfb", -"camellia-128-cfb", -"camellia-192-cfb", -"camellia-256-cfb", -"salsa20", -"chacha20", -"chacha20-ietf", + -- plain + "none", + "plain", + -- aead + "aes-128-gcm", + "aes-192-gcm", + "aes-256-gcm", + "chacha20-ietf-poly1305", + "xchacha20-ietf-poly1305", + -- aead 2022 + "2022-blake3-aes-128-gcm", + "2022-blake3-aes-256-gcm", + "2022-blake3-chacha20-poly1305" + --[[ stream + "none", + "plain", + "table", + "rc4", + "rc4-md5", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "salsa20", + "chacha20", + "chacha20-ietf" ]] } local protocol = { -"origin", -"verify_deflate", -"auth_sha1_v4", -"auth_aes128_sha1", -"auth_aes128_md5", -"auth_chain_a", -"auth_chain_b", -"auth_chain_c", -"auth_chain_d", -"auth_chain_e", -"auth_chain_f", + -- ssr + "origin", + "verify_deflate", + "auth_sha1_v4", + "auth_aes128_sha1", + "auth_aes128_md5", + "auth_chain_a", + "auth_chain_b", + "auth_chain_c", + "auth_chain_d", + "auth_chain_e", + "auth_chain_f" } -obfs = { -"plain", -"http_simple", -"http_post", -"random_head", -"tls1.2_ticket_auth", +local obfs = { + -- ssr + "plain", + "http_simple", + "http_post", + "random_head", + "tls1.2_ticket_auth" } local securitys = { -"auto", -"none", -"aes-128-gcm", -"chacha20-poly1305" + -- vmess + "auto", + "none", + "zero", + "aes-128-gcm", + "chacha20-poly1305" } local flows = { -"xtls-rprx-origin", -"xtls-rprx-origin-udp443", -"xtls-rprx-direct", -"xtls-rprx-direct-udp443", -"xtls-rprx-splice", -"xtls-rprx-splice-udp443" + -- xtls + "xtls-rprx-origin", + "xtls-rprx-origin-udp443", + "xtls-rprx-direct", + "xtls-rprx-direct-udp443", + "xtls-rprx-splice", + "xtls-rprx-splice-udp443" } -local force_fp = { - "disable", - "firefox", - "chrome", - "ios", -} - -local encrypt_methods_ss_aead = { - "dummy", - "aead_chacha20_poly1305", - "aead_aes_128_gcm", - "aead_aes_256_gcm", - "chacha20-ietf-poly1305", - "aes-128-gcm", - "aes-256-gcm", -} - -m = Map(bypass, translate("Edit Server")) +m = Map("bypass", translate("Edit Bypass Server")) m.redirect = luci.dispatcher.build_url("admin/services/bypass/servers") -if m.uci:get(bypass, sid) ~= "servers" then -luci.http.redirect(m.redirect) -return +if m.uci:get("bypass", sid) ~= "servers" then + luci.http.redirect(m.redirect) + return end -- [[ Servers Setting ]]-- @@ -139,52 +136,72 @@ s = m:section(NamedSection, sid, "servers") s.anonymous = true s.addremove = false -o = s:option(DummyValue, "ssr_url", "SS/SSR/VLESS/VMESS/TROJAN URL") +o = s:option(DummyValue, "ssr_url", "SS/SSR/V2RAY/TROJAN URL") o.rawhtml = true -o.template = "bypass/link" +o.template = "bypass/ssrurl" o.value = sid o = s:option(ListValue, "type", translate("Server Node Type")) -o:value("ssr", translate("ShadowsocksR")) -if nixio.fs.access("/usr/bin/ss-redir") then -o:value("ss", translate("Shadowsocks New Version")) +if is_finded("xray") or is_finded("v2ray") then + o:value("v2ray", translate("V2Ray/XRay")) end -if nixio.fs.access("/usr/bin/xray") or nixio.fs.access("/usr/bin/v2ray") then -o:value("vmess", translate("Vmess")) -o:value("vless", translate("Vless")) +if is_finded("ssr-redir") then + o:value("ssr", translate("ShadowsocksR")) end -if nixio.fs.access("/usr/sbin/trojan-plus") then -o:value("trojan", translate("Trojan")) +if is_finded("sslocal") or is_finded("ss-redir") then + o:value("ss", translate("Shadowsocks New Version")) end -if nixio.fs.access("/usr/bin/trojan-go") then -o:value("trojan-go", translate("Trojan-Go")) +if is_finded("trojan-plus") then + o:value("trojan", translate("Trojan")) end -if nixio.fs.access("/usr/bin/naive") then -o:value("naiveproxy", translate("NaiveProxy")) +if is_finded("naive") then + o:value("naiveproxy", translate("NaiveProxy")) end -if nixio.fs.access("/usr/sbin/redsocks2") then -o:value("socks5", translate("Socks5")) -o:value("tun", translate("Network Tunnel")) +if is_finded("hysteria") then + o:value("hysteria", translate("Hysteria")) end +if is_finded("ipt2socks") then + o:value("socks5", translate("Socks5")) +end +if is_finded("redsocks2") then + o:value("tun", translate("Network Tunnel")) +end + o.description = translate("Using incorrect encryption mothod may causes service fail to start") o = s:option(Value, "alias", translate("Alias(optional)")) o = s:option(ListValue, "iface", translate("Network interface to use")) -for _, e in ipairs(luci.sys.net.devices()) do if e ~= "lo" then o:value(e) end end +for _, e in ipairs(luci.sys.net.devices()) do + if e ~= "lo" then + o:value(e) + end +end o:depends("type", "tun") o.description = translate("Redirect traffic to this network interface") +o = s:option(ListValue, "v2ray_protocol", translate("V2Ray/XRay protocol")) +o:value("vless", translate("VLESS")) +o:value("vmess", translate("VMess")) +o:value("trojan", translate("Trojan")) +o:value("shadowsocks", translate("Shadowsocks")) +if is_installed("sagernet-core") then + o:value("shadowsocksr", translate("ShadowsocksR")) + o:value("wireguard", translate("WireGuard")) +end +o:value("socks", translate("Socks")) +o:value("http", translate("HTTP")) +o:depends("type", "v2ray") + o = s:option(Value, "server", translate("Server Address")) o.datatype = "host" o.rmempty = false o:depends("type", "ssr") o:depends("type", "ss") -o:depends("type", "vmess") -o:depends("type", "vless") +o:depends("type", "v2ray") o:depends("type", "trojan") -o:depends("type", "trojan-go") o:depends("type", "naiveproxy") +o:depends("type", "hysteria") o:depends("type", "socks5") o = s:option(Value, "server_port", translate("Server Port")) @@ -192,22 +209,25 @@ o.datatype = "port" o.rmempty = false o:depends("type", "ssr") o:depends("type", "ss") -o:depends("type", "vmess") -o:depends("type", "vless") +o:depends("type", "v2ray") o:depends("type", "trojan") -o:depends("type", "trojan-go") o:depends("type", "naiveproxy") +o:depends("type", "hysteria") o:depends("type", "socks5") o = s:option(Flag, "auth_enable", translate("Enable Authentication")) o.rmempty = false o.default = "0" o:depends("type", "socks5") +o:depends({type = "v2ray", v2ray_protocol = "http"}) +o:depends({type = "v2ray", v2ray_protocol = "socks"}) o = s:option(Value, "username", translate("Username")) o.rmempty = true o:depends("type", "naiveproxy") o:depends({type = "socks5", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "http", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "socks", auth_enable = true}) o = s:option(Value, "password", translate("Password")) o.password = true @@ -215,78 +235,154 @@ o.rmempty = true o:depends("type", "ssr") o:depends("type", "ss") o:depends("type", "trojan") -o:depends("type", "trojan-go") o:depends("type", "naiveproxy") o:depends({type = "socks5", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "http", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"}) +o:depends({type = "v2ray", v2ray_protocol = "trojan"}) o = s:option(ListValue, "encrypt_method", translate("Encrypt Method")) -for _, v in ipairs(encrypt_methods) do o:value(v) end +for _, v in ipairs(encrypt_methods) do + o:value(v) +end o.rmempty = true o:depends("type", "ssr") +o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"}) o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method")) -for _, v in ipairs(encrypt_methods_ss) do o:value(v) end +for _, v in ipairs(encrypt_methods_ss) do + o:value(v) +end o.rmempty = true o:depends("type", "ss") +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) + +o = s:option(Flag, "uot", translate("UDP over TCP")) +o.description = translate("Enable the SUoT protocol, requires server support.") +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o.default = "0" + +o = s:option(Flag, "ivCheck", translate("Bloom Filter")) +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o.default = "1" -- Shadowsocks Plugin -if A==0 or B==0 then -o=s:option(ListValue,"plugin",translate("Plugin")) -o:value("",translate("Disable")) -if A==0 then -o:value("obfs-local",translate("simple-obfs")) +o = s:option(Value, "plugin", translate("Obfs")) +o:value("none", translate("None")) +if is_finded("obfs-local") or is_installed("sagernet-core") then + o:value("obfs-local", translate("obfs-local")) end -if B==0 then -o:value("v2ray-plugin",translate("v2ray-plugin")) +if is_finded("v2ray-plugin") or is_installed("sagernet-core") then + o:value("v2ray-plugin", translate("v2ray-plugin")) end -o:depends("type","ss") +if is_finded("xray-plugin") then + o:value("xray-plugin", translate("xray-plugin")) +end +o.rmempty = true +o:depends("type", "ss") +if is_installed("sagernet-core") then + o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) end -o=s:option(Value,"plugin_opts",translate("Plugin Opts")) -o:depends("plugin","obfs-local") -o:depends("plugin","v2ray-plugin") +o = s:option(Value, "plugin_opts", translate("Plugin Opts")) +o.rmempty = true +o:depends("type", "ss") +if is_installed("sagernet-core") then + o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +end o = s:option(ListValue, "protocol", translate("Protocol")) -for _, v in ipairs(protocol) do o:value(v) end +for _, v in ipairs(protocol) do + o:value(v) +end o.rmempty = true o:depends("type", "ssr") +o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"}) -o = s:option(Value, "protocol_param", translate("Protocol param(optional)")) +o = s:option(Value, "protocol_param", translate("Protocol param (optional)")) o:depends("type", "ssr") +o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"}) o = s:option(ListValue, "obfs", translate("Obfs")) -for _, v in ipairs(obfs) do o:value(v) end +for _, v in ipairs(obfs) do + o:value(v) +end o.rmempty = true o:depends("type", "ssr") +o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"}) -o = s:option(Value, "obfs_param", translate("Obfs param(optional)")) +o = s:option(Value, "obfs_param", translate("Obfs param (optional)")) o:depends("type", "ssr") +o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"}) --- AlterId -o = s:option(Value, "alter_id", translate("AlterId")) -o.datatype = "port" -o.default = 16 +-- [[ Hysteria ]]-- +o = s:option(ListValue, "hysteria_protocol", translate("Protocol")) +o:depends("type", "hysteria") +o:value("udp", translate("udp")) +o:value("wechat-video", translate("wechat-video")) +o:value("faketcp", translate("faketcp")) +o.default = "udp" o.rmempty = true -o:depends("type", "vmess") --- UUID -o = s:option(Value, "uuid", translate("Vmess/VLESS ID (UUID)")) +o = s:option(ListValue, "auth_type", translate("Authentication type")) +o:depends("type", "hysteria") +o:value("0", translate("disabled")) +o:value("1", translate("base64")) +o:value("2", translate("string")) +o.rmempty = true + +o = s:option(Value, "auth_payload", translate("Authentication payload")) +o:depends({type = "hysteria", auth_type = "1"}) +o:depends({type = "hysteria", auth_type = "2"}) +o.rmempty = true + +o = s:option(Value, "recv_window", translate("QUIC connection receive window")) +o.datatype = "uinteger" +o:depends("type", "hysteria") +o.rmempty = true + +o = s:option(Value, "recv_window_conn", translate("QUIC stream receive window")) +o.datatype = "uinteger" +o:depends("type", "hysteria") +o.rmempty = true + +o = s:option(Flag, "disable_mtu_discovery", translate("Disable Path MTU discovery")) +o:depends("type", "hysteria") +o.rmempty = true + +-- VmessId +o = s:option(Value, "vmess_id", translate("Vmess/VLESS ID (UUID)")) o.rmempty = true o.default = uuid -o:depends("type", "vmess") -o:depends("type", "vless") +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) +o:depends({type = "v2ray", v2ray_protocol = "vless"}) -- VLESS Encryption o = s:option(Value, "vless_encryption", translate("VLESS Encryption")) o.rmempty = true o.default = "none" -o:depends("type", "vless") +o:depends({type = "v2ray", v2ray_protocol = "vless"}) -- 加密方式 o = s:option(ListValue, "security", translate("Encrypt Method")) -for _, v in ipairs(securitys) do o:value(v, v:upper()) end +for _, v in ipairs(securitys) do + o:value(v, v:upper()) +end o.rmempty = true -o:depends("type", "vmess") +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) + +-- SOCKS Version +o = s:option(ListValue, "socks_ver", translate("Socks Version")) +o:value("4", "Socks4") +o:value("4a", "Socks4A") +o:value("5", "Socks5") +o.rmempty = true +o.default = "5" +o:depends({type = "v2ray", v2ray_protocol = "socks"}) -- 传输协议 o = s:option(ListValue, "transport", translate("Transport")) @@ -297,22 +393,14 @@ o:value("h2", "HTTP/2") o:value("quic", "QUIC") o:value("grpc", "gRPC") o.rmempty = true -o:depends("type", "vmess") -o:depends("type", "vless") - --- For Trojan-Go - - -o = s:option(ListValue, "trojan_transport", translate("Transport")) -o:value("original", "Original") -o:value("ws", "WebSocket") -o:value("h2", "HTTP/2") -o:value("h2+ws", "HTTP/2 & WebSocket") -o.default = "ws" -o:depends("type", "trojan-go") +o:depends({type = "v2ray", v2ray_protocol = "vless"}) +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) +o:depends({type = "v2ray", v2ray_protocol = "trojan"}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o:depends({type = "v2ray", v2ray_protocol = "socks"}) +o:depends({type = "v2ray", v2ray_protocol = "http"}) -- [[ TCP部分 ]]-- - -- TCP伪装 o = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) o:depends("transport", "tcp") @@ -331,40 +419,99 @@ o:depends("tcp_guise", "http") o.rmempty = true -- [[ WS部分 ]]-- - -- WS域名 o = s:option(Value, "ws_host", translate("WebSocket Host")) -o:depends("transport", "ws") -o:depends("trojan_transport", "h2+ws") -o:depends("trojan_transport", "ws") -o.datatype = "host" +o:depends({transport = "ws", tls = false}) +o.datatype = "hostname" o.rmempty = true -- WS路径 o = s:option(Value, "ws_path", translate("WebSocket Path")) o:depends("transport", "ws") -o:depends("trojan_transport", "h2+ws") -o:depends("trojan_transport", "ws") o.rmempty = true +if is_finded("v2ray") then + -- WS前置数据 + o = s:option(Value, "ws_ed", translate("Max Early Data")) + o:depends("transport", "ws") + o.datatype = "uinteger" + o.default = 2048 + o.rmempty = true + + -- WS前置数据标头 + o = s:option(Value, "ws_ed_header", translate("Early Data Header Name")) + o:depends("transport", "ws") + o.default = "Sec-WebSocket-Protocol" + o.rmempty = true +end + -- [[ H2部分 ]]-- -- H2域名 o = s:option(Value, "h2_host", translate("HTTP/2 Host")) o:depends("transport", "h2") -o:depends("trojan_transport", "h2+ws") -o:depends("trojan_transport", "h2") o.rmempty = true -- H2路径 o = s:option(Value, "h2_path", translate("HTTP/2 Path")) o:depends("transport", "h2") -o:depends("trojan_transport", "h2+ws") -o:depends("trojan_transport", "h2") o.rmempty = true --- [[ QUIC部分 ]]-- +-- gRPC +o = s:option(Value, "serviceName", translate("gRPC Service Name")) +o:depends("transport", "grpc") +o.rmempty = true +if is_finded("xray") or is_installed("sagernet-core") then + -- gPRC模式 + o = s:option(ListValue, "grpc_mode", translate("gRPC Mode")) + o:depends("transport", "grpc") + o:value("gun", translate("Gun")) + o:value("multi", translate("Multi")) + if is_installed("sagernet-core") then + o:value("raw", translate("Raw")) + end + o.rmempty = true +end + +if is_finded("xray") or is_installed("sagernet-core") then + -- gRPC初始窗口 + o = s:option(Value, "initial_windows_size", translate("Initial Windows Size")) + o.datatype = "uinteger" + o:depends("transport", "grpc") + o.default = 0 + o.rmempty = true + + -- H2/gRPC健康检查 + o = s:option(Flag, "health_check", translate("H2/gRPC Health Check")) + o:depends("transport", "h2") + o:depends("transport", "grpc") + o.rmempty = true + + o = s:option(Value, "read_idle_timeout", translate("H2 Read Idle Timeout")) + o.datatype = "uinteger" + o:depends({health_check = true, transport = "h2"}) + o.default = 60 + o.rmempty = true + + o = s:option(Value, "idle_timeout", translate("gRPC Idle Timeout")) + o.datatype = "uinteger" + o:depends({health_check = true, transport = "grpc"}) + o.default = 60 + o.rmempty = true + + o = s:option(Value, "health_check_timeout", translate("Health Check Timeout")) + o.datatype = "uinteger" + o:depends("health_check", 1) + o.default = 20 + o.rmempty = true + + o = s:option(Flag, "permit_without_stream", translate("Permit Without Stream")) + o:depends({health_check = true, transport = "grpc"}) + o.rmempty = true +end + +-- [[ QUIC部分 ]]-- o = s:option(ListValue, "quic_security", translate("QUIC Security")) o:depends("transport", "quic") o:value("none", translate("None")) @@ -383,33 +530,25 @@ o:value("none", translate("None")) o:value("srtp", translate("VideoCall (SRTP)")) o:value("utp", translate("BitTorrent (uTP)")) o:value("wechat-video", translate("WechatVideo")) -o:value("dtls", "DTLS 1.2") -o:value("wireguard", "WireGuard") - --- [[ gRPC部分 ]]-- -o = s:option(Value, "grpc_serviceName", "ServiceName") -o:depends("transport", "grpc") - -o = s:option(Flag, "gRPC_MultiMode", "MultiMode") -o.rmempty = true -o:depends("transport", "grpc") +o:value("dtls", translate("DTLS 1.2")) +o:value("wireguard", translate("WireGuard")) -- [[ mKCP部分 ]]-- - o = s:option(ListValue, "kcp_guise", translate("Camouflage Type")) o:depends("transport", "kcp") o:value("none", translate("None")) o:value("srtp", translate("VideoCall (SRTP)")) o:value("utp", translate("BitTorrent (uTP)")) o:value("wechat-video", translate("WechatVideo")) -o:value("dtls", "DTLS 1.2") -o:value("wireguard", "WireGuard") +o:value("dtls", translate("DTLS 1.2")) +o:value("wireguard", translate("WireGuard")) o.rmempty = true o = s:option(Value, "mtu", translate("MTU")) o.datatype = "uinteger" o:depends("transport", "kcp") -o.default = 1350 +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +-- o.default = 1350 o.rmempty = true o = s:option(Value, "tti", translate("TTI")) @@ -421,12 +560,14 @@ o.rmempty = true o = s:option(Value, "uplink_capacity", translate("Uplink Capacity")) o.datatype = "uinteger" o:depends("transport", "kcp") +o:depends("type", "hysteria") o.default = 5 o.rmempty = true o = s:option(Value, "downlink_capacity", translate("Downlink Capacity")) o.datatype = "uinteger" o:depends("transport", "kcp") +o:depends("type", "hysteria") o.default = 20 o.rmempty = true @@ -443,124 +584,169 @@ o.default = 2 o.rmempty = true o = s:option(Value, "seed", translate("Obfuscate password (optional)")) -o:depends({type = "vless", transport = "kcp"}) +o:depends("transport", "kcp") +o:depends("type", "hysteria") o.rmempty = true o = s:option(Flag, "congestion", translate("Congestion")) o:depends("transport", "kcp") o.rmempty = true +-- [[ WireGuard 部分 ]]-- +o = s:option(DynamicList, "local_addresses", translate("Local addresses")) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.rmempty = true + +o = s:option(Value, "private_key", translate("Private key")) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.password = true +o.rmempty = true + +o = s:option(Value, "peer_pubkey", translate("Peer public key")) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.rmempty = true + +o = s:option(Value, "preshared_key", translate("Pre-shared key")) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.password = true +o.rmempty = true + -- [[ TLS ]]-- o = s:option(Flag, "tls", translate("TLS")) o.rmempty = true o.default = "0" -o:depends("type", "vmess") -o:depends({type = "vless", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "vless", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "vmess", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "trojan", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "http", xtls = false}) o:depends("type", "trojan") -o:depends("type", "trojan-go") -- XTLS -if nixio.fs.access("/usr/bin/xray") then -o = s:option(Flag, "xtls", translate("XTLS")) -o.rmempty = true -o.default = "0" -o:depends({type = "vless", transport = "tcp", tls = false}) +if is_finded("xray") then + o = s:option(Flag, "xtls", translate("XTLS")) + o.rmempty = true + o.default = "0" + o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "tcp", tls = false}) + o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "kcp", tls = false}) + o:depends({type = "v2ray", v2ray_protocol = "trojan", transport = "tcp", tls = false}) + o:depends({type = "v2ray", v2ray_protocol = "trojan", transport = "kcp", tls = false}) end -- Flow o = s:option(Value, "vless_flow", translate("Flow")) -for _, v in ipairs(flows) do o:value(v, v) end +for _, v in ipairs(flows) do + o:value(v, translate(v)) +end o.rmempty = true o.default = "xtls-rprx-splice" o:depends("xtls", true) +-- [[ TLS部分 ]] -- +o = s:option(Flag, "tls_sessionTicket", translate("Session Ticket")) +o:depends({type = "trojan", tls = true}) +o.default = "0" + +if is_finded("xray") then + -- [[ uTLS ]]-- + o = s:option(ListValue, "fingerprint", translate("Finger Print")) + o:value("disable", translate("disable")) + o:value("firefox", translate("firefox")) + o:value("chrome", translate("chrome")) + o:value("safari", translate("safari")) + o:value("randomized", translate("randomized")) + o:depends({type = "v2ray", tls = true}) + o.default = "disable" +end + o = s:option(Value, "tls_host", translate("TLS Host")) +o.datatype = "hostname" o:depends("tls", true) o:depends("xtls", true) +o:depends("type", "hysteria") o.rmempty = true -o = s:option(ListValue, "fingerprint", translate("Finger Print")) -for _, v in ipairs(force_fp) do o:value(v) end -o:depends({ type = "trojan-go", tls = "tls" }) -o.default = "firefox" +o = s:option(Value, "quic_tls_alpn", translate("QUIC TLS ALPN")) +o:depends("type", "hysteria") +o.rmempty = true -- [[ allowInsecure ]]-- o = s:option(Flag, "insecure", translate("allowInsecure")) o.rmempty = false o:depends("tls", true) o:depends("xtls", true) +o:depends("type", "hysteria") o.description = translate("If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates.") +-- [[ Mux ]]-- +o = s:option(Flag, "mux", translate("Mux")) +o.rmempty = false +o:depends({type = "v2ray", v2ray_protocol = "vless", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "vmess", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "trojan", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "socks", xtls = false}) +o:depends({type = "v2ray", v2ray_protocol = "http", xtls = false}) + +o = s:option(Value, "concurrency", translate("Concurrency")) +o.datatype = "uinteger" +o.rmempty = true +o.default = "4" +o:depends("mux", "1") +o:depends("type", "naiveproxy") + -- [[ Cert ]]-- o = s:option(Flag, "certificate", translate("Self-signed Certificate")) o.rmempty = true o.default = "0" -o:depends({ tls = true, insecure = false }) -o:depends({ xtls = true, insecure = false }) +o:depends({type = "hysteria", insecure = false}) +o:depends({type = "trojan", tls = true, insecure = false}) +o:depends({type = "v2ray", v2ray_protocol = "vmess", tls = true, insecure = false}) +o:depends({type = "v2ray", v2ray_protocol = "vless", tls = true, insecure = false}) +o:depends({type = "v2ray", v2ray_protocol = "vmess", xtls = true, insecure = false}) +o:depends({type = "v2ray", v2ray_protocol = "vless", xtls = true, insecure = false}) o.description = translate("If you have a self-signed certificate,please check the box") o = s:option(DummyValue, "upload", translate("Upload")) -o.template = "bypass/certupload" +o.template = "shadowsocksr/certupload" o:depends("certificate", 1) cert_dir = "/etc/ssl/private/" local path luci.http.setfilehandler(function(meta, chunk, eof) -if not fd then -if (not meta) or (not meta.name) or (not meta.file) then return end -fd = nixio.open(cert_dir .. meta.file, "w") -if not fd then -path = translate("Create upload file error.") -return -end -end -if chunk and fd then fd:write(chunk) end -if eof and fd then -fd:close() -fd = nil -path = '/etc/ssl/private/' .. meta.file .. '' -end + if not fd then + if (not meta) or (not meta.name) or (not meta.file) then + return + end + fd = nixio.open(cert_dir .. meta.file, "w") + if not fd then + path = translate("Create upload file error.") + return + end + end + if chunk and fd then + fd:write(chunk) + end + if eof and fd then + fd:close() + fd = nil + path = '/etc/ssl/private/' .. meta.file .. '' + end end) if luci.http.formvalue("upload") then -local f = luci.http.formvalue("ulfile") -if #f <= 0 then path = translate("No specify upload file.") end + local f = luci.http.formvalue("ulfile") + if #f <= 0 then + path = translate("No specify upload file.") + end end o = s:option(Value, "certpath", translate("Current Certificate Path")) o:depends("certificate", 1) -o:value("/etc/ssl/private/") +o:value("/etc/ssl/private/ca.pem") o.description = translate("Please confirm the current certificate path") -o.default = "/etc/ssl/private/" - -o = s:option(Flag, "ss_aead", translate("Shadowsocks2")) -o:depends("type", "trojan-go") -o.default = "0" -o.rmempty = false - -o = s:option(ListValue, "ss_aead_method", translate("Encrypt Method")) -for _, v in ipairs(encrypt_methods_ss_aead) do o:value(v, v) end -o.default = "aead_aes_128_gcm" -o.rmempty = false -o:depends("ss_aead", "1") - -o = s:option(Value, "ss_aead_pwd", translate("Password")) -o.password = true -o.rmempty = true -o:depends("ss_aead", "1") - --- [[ Mux ]]-- -o = s:option(Flag, "mux", translate("Mux")) -o.rmempty = false -o:depends("type", "vmess") -o:depends({type = "vless", xtls = false}) -o:depends("type", "trojan-go") - -o = s:option(Value, "concurrency", translate("Concurrency")) -o.datatype = "uinteger" -o.rmempty = true -o.default = "8" -o:depends("mux", "1") +o.default = "/etc/ssl/private/ca.pem" o = s:option(Flag, "fast_open", translate("TCP Fast Open")) o.rmempty = true @@ -568,7 +754,17 @@ o.default = "0" o:depends("type", "ssr") o:depends("type", "ss") o:depends("type", "trojan") -o:depends("type", "trojan-go") + +if is_installed("sagernet-core") then + o = s:option(ListValue, "packet_encoding", translate("Packet Encoding")) + o:value("none", translate("none")) + o:value("packet", translate("packet (v2ray-core v5+)")) + o:value("xudp", translate("xudp (Xray-core)")) + o.default = "xudp" + o.rmempty = true + o:depends({type = "v2ray", v2ray_protocol = "vless"}) + o:depends({type = "v2ray", v2ray_protocol = "vmess"}) +end o = s:option(Flag, "switch_enable", translate("Enable Auto Switch")) o.rmempty = false @@ -579,41 +775,28 @@ o.datatype = "port" o.default = 1234 o.rmempty = false -if nixio.fs.access("/usr/bin/kcptun-client") then -kcp_enable = s:option(Flag, "kcp_enable", translate("KcpTun Enable"), translate("bin:/usr/bin/kcptun-client")) -kcp_enable.rmempty = true -kcp_enable.default = "0" -kcp_enable:depends("type", "ssr") -kcp_enable:depends("type", "ss") +if is_finded("kcptun-client") then + o = s:option(Flag, "kcp_enable", translate("KcpTun Enable")) + o.rmempty = true + o.default = "0" + o:depends("type", "ssr") + o:depends("type", "ss") -o = s:option(Value, "kcp_port", translate("KcpTun Port")) -o.datatype = "port" -o.default = 4000 -function o.validate(self, value, section) -local kcp_file = "/usr/bin/kcptun-client" -local enable = kcp_enable:formvalue(section) or kcp_enable.disabled -if enable == kcp_enable.enabled then -if not nixio.fs.access(kcp_file) then -return nil, translate("Haven't a Kcptun executable file") -elseif not isKcptun(kcp_file) then -return nil, translate("Not a Kcptun executable file") -end -end + o = s:option(Value, "kcp_port", translate("KcpTun Port")) + o.datatype = "port" + o.default = 4000 + o:depends("type", "ssr") + o:depends("type", "ss") -return value -end -o:depends("type", "ssr") -o:depends("type", "ss") + o = s:option(Value, "kcp_password", translate("KcpTun Password")) + o.password = true + o:depends("type", "ssr") + o:depends("type", "ss") -o = s:option(Value, "kcp_password", translate("KcpTun Password")) -o.password = true -o:depends("type", "ssr") -o:depends("type", "ss") - -o = s:option(Value, "kcp_param", translate("KcpTun Param")) -o.default = "--nocomp" -o:depends("type", "ssr") -o:depends("type", "ss") + o = s:option(Value, "kcp_param", translate("KcpTun Param")) + o.default = "--nocomp" + o:depends("type", "ssr") + o:depends("type", "ss") end return m diff --git a/luci-app-bypass/luasrc/model/cbi/bypass/servers.lua b/luci-app-bypass/luasrc/model/cbi/bypass/servers.lua index 219ab82b..3d3a2c4e 100644 --- a/luci-app-bypass/luasrc/model/cbi/bypass/servers.lua +++ b/luci-app-bypass/luasrc/model/cbi/bypass/servers.lua @@ -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 diff --git a/luci-app-bypass/luasrc/model/cbi/bypass/trojan_go.lua b/luci-app-bypass/luasrc/model/cbi/bypass/trojan_go.lua deleted file mode 100644 index a28631e0..00000000 --- a/luci-app-bypass/luasrc/model/cbi/bypass/trojan_go.lua +++ /dev/null @@ -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 diff --git a/luci-app-bypass/luasrc/view/bypass/link.htm b/luci-app-bypass/luasrc/view/bypass/link.htm deleted file mode 100644 index 23d034de..00000000 --- a/luci-app-bypass/luasrc/view/bypass/link.htm +++ /dev/null @@ -1,831 +0,0 @@ -<%+cbi/valueheader%> -<% -local api = require "luci.model.cbi.bypass.api" --%> - - - - - -<%+cbi/valuefooter%> diff --git a/luci-app-bypass/luasrc/view/bypass/ssrurl.htm b/luci-app-bypass/luasrc/view/bypass/ssrurl.htm new file mode 100644 index 00000000..95d63932 --- /dev/null +++ b/luci-app-bypass/luasrc/view/bypass/ssrurl.htm @@ -0,0 +1,366 @@ +<%+cbi/valueheader%> + + + +<%+cbi/valuefooter%> diff --git a/luci-app-bypass/luasrc/view/bypass/trojan_go_version.htm b/luci-app-bypass/luasrc/view/bypass/trojan_go_version.htm deleted file mode 100644 index 75bd990e..00000000 --- a/luci-app-bypass/luasrc/view/bypass/trojan_go_version.htm +++ /dev/null @@ -1,172 +0,0 @@ -<% -local trojan_go_version = require "luci.model.cbi.bypass.api".get_trojan_go_version() --%> - - - -