sync luci-app-ssr-plus upstream & add lua-neturl package

This commit is contained in:
sbwml 2022-08-14 01:10:29 +08:00
parent c8bc5a5bdb
commit 6b6d62eef8
12 changed files with 18791 additions and 13790 deletions

44
lua-neturl/Makefile Normal file
View File

@ -0,0 +1,44 @@
# SPDX-License-Identifier: GPL-3.0-only
#
# Copyright (C) 2022 ImmortalWrt.org
include $(TOPDIR)/rules.mk
PKG_NAME:=neturl
PKG_VERSION:=1.1-1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/golgote/neturl/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=25f3a94ba9f435ef1395555de2bf17d6f934d789fa515ed965405919e42be27b
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
PKG_LICENSE:=MIT
PKG_LICNESE_FILES:=LICENSE.txt
include $(INCLUDE_DIR)/package.mk
define Package/lua-neturl
SUBMENU:=Lua
SECTION:=lang
CATEGORY:=Languages
TITLE:=URL and Query string parser, builder, normalizer for Lua
URL:=https://github.com/golgote/neturl
DEPENDS:=+lua
PKGARCH:=all
endef
define Package/lua-neturl/description
This small Lua library provides a few functions to parse URL with
querystring and build new URL easily.
endef
define Build/Compile
endef
define Package/lua-neturl/install
$(INSTALL_DIR) $(1)/usr/lib/lua
$(CP) $(PKG_BUILD_DIR)/lib/net/url.lua $(1)/usr/lib/lua/
endef
$(eval $(call BuildPackage,lua-neturl))

View File

@ -0,0 +1,11 @@
--- a/lib/net/url.lua
+++ b/lib/net/url.lua
@@ -340,7 +340,7 @@ function M:setAuthority(authority)
self.password = v
return ''
end)
- if string.find(userinfo, "^[%w%+%.]+$") then
+ if string.find(userinfo, "^[%p%w%+%.]+$") then
self.user = userinfo
else
-- incorrect userinfo

View File

@ -2,9 +2,13 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-ssr-plus
PKG_VERSION:=186
PKG_RELEASE:=3
PKG_RELEASE:=6
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks \
@ -18,16 +22,21 @@ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin
LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/Socks5/Tun LuCI interface
LUCI_PKGARCH:=all
LUCI_DEPENDS:= \
@(PACKAGE_libustream-mbedtls||PACKAGE_libustream-openssl||PACKAGE_libustream-wolfssl) \
+coreutils +coreutils-base64 +dns2socks +dns2tcp +dnsmasq-full +ipset +kmod-ipt-nat \
+ip-full +iptables +iptables-mod-tproxy +lua +libuci-lua +microsocks +tcping \
+resolveip +shadowsocksr-libev-ssr-check +uclient-fetch \
+ip-full +iptables +iptables-mod-tproxy +lua +lua-neturl +libuci-lua +microsocks \
+tcping +resolveip +shadowsocksr-libev-ssr-check +uclient-fetch \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \
+PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core:sagernet-core \
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria:hysteria \
+PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks:ipt2socks \
@ -43,13 +52,29 @@ LUCI_DEPENDS:= \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server:shadowsocksr-libev-ssr-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs:simple-obfs \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin:v2ray-plugin \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin:v2ray-plugin
define Package/$(PKG_NAME)/config
select PACKAGE_luci-lib-ipkg if PACKAGE_$(PKG_NAME)
choice
prompt "V2ray-core Selection"
default PACKAGE_$(PKG_NAME)_INCLUDE_Xray if aarch64||arm||i386||x86_64
default PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY
config PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY
bool "None"
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
bool "Include V2ray-core"
config PACKAGE_$(PKG_NAME)_INCLUDE_Xray
bool "Include Xray-core"
config PACKAGE_$(PKG_NAME)_INCLUDE_SagerNet_Core
bool "Include SagerNet-core (An enhanced edition of v2ray-core)"
endchoice
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
bool "Include Kcptun"
default n
@ -59,7 +84,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks
bool "Include ipt2socks"
bool "Include IPT2Socks"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy
@ -111,10 +136,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin
bool "Include Shadowsocks V2ray Plugin"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Xray
bool "Include Xray"
default y if aarch64||arm||i386||x86_64
endef
define Package/$(PKG_NAME)/conffiles

View File

@ -186,6 +186,7 @@ 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"))
@ -237,8 +238,9 @@ o:depends("type", "trojan")
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: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"))
@ -247,6 +249,7 @@ for _, v in ipairs(encrypt_methods) do
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
@ -270,7 +273,7 @@ o.default = "1"
-- Shadowsocks Plugin
o = s:option(Value, "plugin", translate("Obfs"))
o:value("none", translate("None"))
if is_finded("obfs-local") then
if is_finded("obfs-local") or is_installed("sagernet-core") then
o:value("obfs-local", translate("obfs-local"))
end
if is_finded("v2ray-plugin") or is_installed("sagernet-core") then
@ -281,12 +284,16 @@ if is_finded("xray-plugin") then
end
o.rmempty = true
o:depends("type", "ss")
o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
if is_installed("sagernet-core") then
o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
end
o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
o.rmempty = true
o:depends("type", "ss")
o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
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
@ -294,9 +301,11 @@ for _, v in ipairs(protocol) do
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:depends("type", "ssr")
o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"})
o = s:option(ListValue, "obfs", translate("Obfs"))
for _, v in ipairs(obfs) do
@ -304,9 +313,11 @@ for _, v in ipairs(obfs) do
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:depends("type", "ssr")
o:depends({type = "v2ray", v2ray_protocol = "shadowsocksr"})
-- [[ Hysteria ]]--
o = s:option(ListValue, "hysteria_protocol", translate("Protocol"))
@ -364,6 +375,15 @@ end
o.rmempty = true
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"))
o:value("tcp", "TCP")
@ -410,18 +430,20 @@ o = s:option(Value, "ws_path", translate("WebSocket Path"))
o:depends("transport", "ws")
o.rmempty = true
-- WS前置数据
o = s:option(Value, "ws_ed", translate("Max Early Data"))
o:depends("transport", "ws")
o.datatype = "uinteger"
o.default = 2048
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
-- 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部分 ]]--
@ -440,48 +462,54 @@ o = s:option(Value, "serviceName", translate("gRPC Service Name"))
o:depends("transport", "grpc")
o.rmempty = true
-- gPRC模式
o = s:option(ListValue, "grpc_mode", translate("gRPC Mode"))
o:depends("transport", "grpc")
o:value("gun", translate("Gun"))
o:value("multi", translate("Multi"))
o:value("raw", translate("Raw"))
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
-- 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
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
-- 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, "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, "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(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
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"))
@ -556,7 +584,7 @@ o.default = 2
o.rmempty = true
o = s:option(Value, "seed", translate("Obfuscate password (optional)"))
o:depends({v2ray_protocol = "vless", transport = "kcp"})
o:depends("transport", "kcp")
o:depends("type", "hysteria")
o.rmempty = true
@ -591,7 +619,7 @@ 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 = "socks", socks_ver = "5", xtls = false})
o:depends({type = "v2ray", v2ray_protocol = "http", xtls = false})
o:depends("type", "trojan")
@ -620,15 +648,17 @@ o = s:option(Flag, "tls_sessionTicket", translate("Session Ticket"))
o:depends({type = "trojan", tls = true})
o.default = "0"
-- [[ 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"
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"

View File

@ -4,6 +4,7 @@
local m, s, sec, o
local uci = luci.model.uci.cursor()
m = Map("shadowsocksr", translate("ShadowSocksR Plus+ Settings"))
m:section(SimpleSection).template = "shadowsocksr/status"

View File

@ -93,6 +93,33 @@ function import_ssr_url(btn, urlname, sid) {
var event = document.createEvent("HTMLEvents");
event.initEvent("change", true, true);
switch (ssu[0]) {
case "hysteria":
try {
var url = new URL("http://" + ssu[1]);
var params = url.searchParams;
} catch(e) {
alert(e);
return false;
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "80";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.hysteria_protocol')[0].value = params.get("protocol") || "udp";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.auth_type')[0].value = params.get("auth") ? "1" : "0";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.auth_type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.auth_payload')[0].value = params.get("auth") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.uplink_capacity')[0].value = params.get("upmbps") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.downlink_capacity')[0].value = params.get("downmbps") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = params.get("obfsParam") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("peer") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_tls_alpn')[0].value = params.get("alpn") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = (params.get("insecure") === "1");
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
return false;
case "ss":
var url0, param = "";
var sipIndex = ssu[1].indexOf("@");
@ -279,79 +306,66 @@ function import_ssr_url(btn, urlname, sid) {
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
return false;
case "vless":
var url0, param = "";
var ploc = ssu[1].indexOf("#");
if (ploc > 0) {
url0 = ssu[1].substr(0, ploc);
param = decodeURIComponent(ssu[1].substr(ploc + 1));
} else {
url0 = ssu[1]
try {
var url = new URL("http://" + ssu[1]);
var params = url.searchParams;
} catch(e) {
alert(e)
return false;
}
var sstr = url0;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "v2ray";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].value = "vless";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].dispatchEvent(event);
var team = sstr.split('@');
var uuid = team[0]
var serverPart = team[1].split(':');
var others = serverPart[1].split('?');
var port = others[0]
var queryParam = {}
if (others.length > 1) {
var queryParams = others[1]
var queryArray = queryParams.split('&');
for (i = 0; i < queryArray.length; i++) {
var params = queryArray[i].split('=');
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
}
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = serverPart[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.vmess_id')[0].value = uuid;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value = queryParam.type ? (queryParam.type == "http" ? "h2" : queryParam.type) : "tcp";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "80";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.vmess_id')[0].value = url.username;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value = params.get("type") == "http" ? "h2" : params.get("type") || "tcp";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.vless_encryption')[0].value = queryParam.encryption || "none";
if (queryParam.security == "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = queryParam.sni || serverPart[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.vless_encryption')[0].value = params.get("encryption") || "none";
if ([ "tls", "xtls" ].includes(params.get("security"))) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.' + params.get("security"))[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.' + params.get("security"))[0].dispatchEvent(event);
if (params.get("security") === "xtls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.vless_flow')[0].value = params.get("flow") || "xtls-rprx-splice";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.vless_flow')[0].dispatchEvent(event);
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("sni") || "";
}
switch (queryParam.type) {
switch (params.get("type")) {
case "ws":
//document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_host')[0].value = queryParam.host;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_path')[0].value = queryParam.path || "/";
if (params.get("security") !== "tls")
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
break;
case "kcp":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = queryParam.headerType || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = queryParam.seed;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = params.get("seed") || "";
break;
case "http":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_host')[0].value = queryParam.host || serverPart[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_path')[0].value = queryParam.path || "/";
break;
case "quic":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_guise')[0].value = queryParam.headerType || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_guise')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_security')[0].value = queryParam.quicSecurity || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_key')[0].value = queryParam.key;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_security')[0].value = params.get("quicSecurity") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_key')[0].value = params.get("key") || "";
break;
case "grpc":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.serviceName')[0].value = queryParam.serviceName;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.serviceName')[0].value = params.get("serviceName") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.grpc_mode')[0].value = params.get("mode") || "gun";
break;
default:
if (queryParam.security == "xtls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xtls')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xtls')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.vless_flow')[0].value = queryParam.flow || "xtls-rprx-splice";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = queryParam.sni || serverPart[0];
case "tcp":
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].value = params.get("headerType") || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].dispatchEvent(event);
if (params.get("headerType") === "http") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
}
break;
}
if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
}
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
return false;
default:

View File

@ -70,6 +70,9 @@ msgstr "布隆过滤器"
msgid "VLESS Encryption"
msgstr "VLESS 加密"
msgid "Socks Version"
msgstr "Socks 版本"
msgid "Flow"
msgstr "流控 (Flow)"

View File

@ -328,8 +328,8 @@ start_udp() {
;;
v2ray)
gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_port
ln_start_bin $(first_type xray v2ray) v2ray run -config $udp_config_file
echolog "UDP TPROXY Relay:$($(first_type "xray" "v2ray") version | head -1) Started!"
ln_start_bin $(first_type v2ray xray) v2ray run -config $udp_config_file
echolog "UDP TPROXY Relay:$($(first_type "v2ray" "xray") version | head -1) Started!"
;;
trojan) #client
gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_local_port
@ -383,9 +383,9 @@ start_shunt() {
v2ray)
local tmp_port=${tmp_local_port:-$tmp_shunt_local_port}
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port $tmp_port
ln_start_bin $(first_type xray v2ray) v2ray run -config $shunt_config_file
ln_start_bin $(first_type v2ray xray) v2ray run -config $shunt_config_file
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
echolog "shunt:$($(first_type xray v2ray) version | head -1) Started!"
echolog "shunt:$($(first_type v2ray xray) version | head -1) Started!"
;;
trojan)
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port
@ -471,9 +471,9 @@ start_local() {
v2ray)
if [ "$_local" == "2" ]; then
gen_config_file $LOCAL_SERVER $type 4 0 $local_port
ln_start_bin $(first_type xray v2ray) v2ray run -config $local_config_file
ln_start_bin $(first_type v2ray xray) v2ray run -config $local_config_file
fi
echolog "Global_Socks5:$($(first_type "xray" "v2ray") version | head -1) Started!"
echolog "Global_Socks5:$($(first_type "v2ray" "xray") version | head -1) Started!"
;;
trojan) #client
gen_config_file $LOCAL_SERVER $type 4 $local_port
@ -540,8 +540,8 @@ Start_Run() {
;;
v2ray)
gen_config_file $GLOBAL_SERVER $type 1 $tcp_port $socks_port
ln_start_bin $(first_type xray v2ray) v2ray run -config $tcp_config_file
echolog "Main node:$($(first_type xray v2ray) version | head -1) Started!"
ln_start_bin $(first_type v2ray xray) v2ray run -config $tcp_config_file
echolog "Main node:$($(first_type v2ray xray) version | head -1) Started!"
;;
trojan)
gen_config_file $GLOBAL_SERVER $type 1 $tcp_port

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -32,14 +32,20 @@ function vmess_vless()
end
function trojan_shadowsocks()
outbound_settings = {
plugin = (server.v2ray_protocol == "shadowsocks") and server.plugin ~= "none" and server.plugin or nil,
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 = server.server,
port = tonumber(server.server_port),
password = server.password,
method = (server.v2ray_protocol == "shadowsocks") and server.encrypt_method_ss or nil,
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
@ -47,7 +53,9 @@ function trojan_shadowsocks()
}
}
if (server.v2ray_protocol == "shadowsocks") and (server.mux ~= "1") and (not (outbound_settings.plugin or server.transport ~= "tcp" or server.tls or server.xtls)) then
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
@ -55,10 +63,12 @@ function trojan_shadowsocks()
outbound_settings = outbound_settings.servers[1]
outbound_settings.serverName = server.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 = server.server,
@ -105,6 +115,9 @@ function outbound:handleIndex(index)
shadowsocks = function()
trojan_shadowsocks()
end,
shadowsocksr = function()
trojan_shadowsocks()
end,
socks = function()
socks_http()
end,
@ -160,7 +173,8 @@ local Xray = {
xtlsSettings = (server.xtls == '1' and (server.insecure == "1" or server.tls_host)) and {
-- xtls
allowInsecure = (server.insecure == "1") and true or nil,
serverName = server.tls_host
serverName = server.tls_host,
minVersion = "1.3"
} or nil,
tcpSettings = (server.transport == "tcp" and server.tcp_guise == "http") and {
-- tcp
@ -211,6 +225,7 @@ local Xray = {
-- 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,

View File

@ -16,6 +16,7 @@ local tinsert = table.insert
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
local b64decode = nixio.bin.b64decode
local URL = require "url"
local cache = {}
local nodeResult = setmetatable({}, {__index = cache}) -- update result
local name = 'shadowsocksr'
@ -28,6 +29,7 @@ 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_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(...)
print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " "))
@ -147,6 +149,8 @@ local function processData(szType, content)
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]
@ -346,75 +350,51 @@ local function processData(szType, content)
end
result.password = password
elseif szType == "vless" then
local idx_sp = 0
local alias = ""
if content:find("#") then
idx_sp = content:find("#")
alias = content:sub(idx_sp + 1, -1)
end
local info = content:sub(1, idx_sp - 1)
local hostInfo = split(info, "@")
local host = split(hostInfo[2], ":")
local uuid = hostInfo[1]
if host[2]:find("?") then
local query = split(host[2], "?")
local params = {}
for _, v in pairs(split(UrlDecode(query[2]), '&')) do
local t = split(v, '=')
params[t[1]] = t[2]
local url = URL.parse("http://" .. content)
local params = url.query
result.alias = url.fragment and UrlDecode(url.fragment) or nil
result.type = "v2ray"
result.v2ray_protocol = "vless"
result.server = url.host
result.port = url.port
result.vmess_id = url.user
result.vless_encryption = params.encryption or "none"
result.transport = params.type or "tcp"
result.packet_encoding = packet_encoding
result.tls = (params.security == "tls") and "1" or "0"
result.tls_host = params.sni
result.xtls = params.security == "xtls" and "1" or nil
result.vless_flow = params.flow
if result.transport == "ws" then
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
result.ws_path = params.path and UrlDecode(params.path) or "/"
elseif result.transport == "http" then
result.transport = "h2"
result.h2_host = params.host and UrlDecode(params.host) or nil
result.h2_path = params.path and UrlDecode(params.path) or nil
elseif result.transport == "kcp" then
result.kcp_guise = params.headerType or "none"
result.seed = params.seed
result.mtu = 1350
result.tti = 50
result.uplink_capacity = 5
result.downlink_capacity = 20
result.read_buffer_size = 2
result.write_buffer_size = 2
elseif result.transport == "quic" then
result.quic_guise = params.headerType or "none"
result.quic_security = params.quicSecurity or "none"
result.quic_key = params.key
elseif result.transport == "grpc" then
result.serviceName = params.serviceName
result.grpc_mode = params.mode or "gun"
elseif result.transport == "tcp" then
result.tcp_guise = params.headerType or "none"
if result.tcp_guise == "http" then
result.tcp_host = params.host and UrlDecode(params.host) or nil
result.tcp_path = params.path and UrlDecode(params.path) or nil
end
result.alias = UrlDecode(alias)
result.type = 'v2ray'
result.v2ray_protocol = 'vless'
result.server = host[1]
result.server_port = query[1]
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"
result.tls_host = params.sni
result.vless_flow = params.flow
else
result.xtls = "0"
end
end
if params.type == 'ws' then
result.ws_host = params.host
result.ws_path = params.path or "/"
end
if params.type == 'http' then
result.h2_host = params.host
result.h2_path = params.path or "/"
end
if params.type == 'kcp' then
result.kcp_guise = params.headerType or "none"
result.mtu = 1350
result.tti = 50
result.uplink_capacity = 5
result.downlink_capacity = 20
result.read_buffer_size = 2
result.write_buffer_size = 2
result.seed = params.seed
end
if params.type == 'quic' then
result.quic_guise = params.headerType or "none"
result.quic_key = params.key
result.quic_security = params.quicSecurity or "none"
end
if params.type == 'grpc' then
result.serviceName = params.serviceName
end
if params.security == "tls" then
result.tls = "1"
result.tls_host = params.sni
else
result.tls = "0"
end
else
result.server_port = host[2]
end
end
if not result.alias then