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() --%> - - - -
- -
-
- 【 <%=trojan_go_version%> 】 - - -
-
-
\ No newline at end of file diff --git a/luci-app-bypass/po/zh-cn/bypass.po b/luci-app-bypass/po/zh-cn/bypass.po index fdf597a9..ca9d40c6 100644 --- a/luci-app-bypass/po/zh-cn/bypass.po +++ b/luci-app-bypass/po/zh-cn/bypass.po @@ -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无需任何设置" \ No newline at end of file +msgstr "请确保luci-app-adguardhome能正常启用,本插件会联动开启并配置ADG,ADG无需任何设置" + diff --git a/luci-app-bypass/root/etc/init.d/bypass b/luci-app-bypass/root/etc/init.d/bypass index 3a4e8e89..6d36e97f 100755 --- a/luci-app-bypass/root/etc/init.d/bypass +++ b/luci-app-bypass/root/etc/init.d/bypass @@ -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!" ;; diff --git a/luci-app-bypass/root/etc/uci-defaults/luci-bypass b/luci-app-bypass/root/etc/uci-defaults/luci-bypass index 4fbcd975..34568443 100755 --- a/luci-app-bypass/root/etc/uci-defaults/luci-bypass +++ b/luci-app-bypass/root/etc/uci-defaults/luci-bypass @@ -12,5 +12,16 @@ uci batch </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 diff --git a/luci-app-bypass/root/usr/share/bypass/by-switch b/luci-app-bypass/root/usr/share/bypass/by-switch index 18c74208..8b31b921 100755 --- a/luci-app-bypass/root/usr/share/bypass/by-switch +++ b/luci-app-bypass/root/usr/share/bypass/by-switch @@ -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 &;; diff --git a/luci-app-bypass/root/usr/share/bypass/gen_config b/luci-app-bypass/root/usr/share/bypass/gen_config new file mode 100644 index 00000000..4b3e5a71 --- /dev/null +++ b/luci-app-bypass/root/usr/share/bypass/gen_config @@ -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) diff --git a/luci-app-bypass/root/usr/share/bypass/gentrojanconfig b/luci-app-bypass/root/usr/share/bypass/gentrojanconfig deleted file mode 100755 index 94ce2925..00000000 --- a/luci-app-bypass/root/usr/share/bypass/gentrojanconfig +++ /dev/null @@ -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)) \ No newline at end of file diff --git a/luci-app-bypass/root/usr/share/bypass/genv2config b/luci-app-bypass/root/usr/share/bypass/genv2config deleted file mode 100755 index ba67cf43..00000000 --- a/luci-app-bypass/root/usr/share/bypass/genv2config +++ /dev/null @@ -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)) diff --git a/luci-app-bypass/root/usr/share/bypass/subscribe b/luci-app-bypass/root/usr/share/bypass/subscribe index 42c8b6b0..8c279fda 100755 --- a/luci-app-bypass/root/usr/share/bypass/subscribe +++ b/luci-app-bypass/root/usr/share/bypass/subscribe @@ -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 diff --git a/naiveproxy/Makefile b/naiveproxy/Makefile index 36764435..3c98c0f2 100644 --- a/naiveproxy/Makefile +++ b/naiveproxy/Makefile @@ -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