From a9612da342e445d928d3c526ce3ed9f809948525 Mon Sep 17 00:00:00 2001 From: action Date: Wed, 21 Oct 2026 17:03:19 +0800 Subject: [PATCH] update 2026-10-21 17:03:19 --- honk/Makefile | 4 +- luci-app-daede/Makefile | 2 +- .../resources/view/daede/updates.js | 5 +- luci-app-daede/po/zh-cn/daede.po | 3 - luci-app-honk/Makefile | 6 +- luci-app-ssr-plus/Makefile | 8 +-- .../model/cbi/shadowsocksr/client-config.lua | 71 +++++++++++++++++++ .../model/cbi/shadowsocksr/server-config.lua | 26 +++++++ .../luasrc/model/cbi/shadowsocksr/server.lua | 2 + .../root/etc/init.d/shadowsocksr | 16 +++++ .../usr/share/shadowsocksr/gen_config.lua | 39 ++++++++++ .../usr/share/shadowsocksr/gen_ssr_server.lua | 13 ++++ v2ray-core/Makefile | 4 +- v2ray-geodata/Makefile | 4 +- 14 files changed, 182 insertions(+), 21 deletions(-) create mode 100644 luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_ssr_server.lua diff --git a/honk/Makefile b/honk/Makefile index f883e4f9..e6413750 100644 --- a/honk/Makefile +++ b/honk/Makefile @@ -5,13 +5,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=honk -PKG_VERSION:=2026.10.20 +PKG_VERSION:=2026.10.21 PKG_RELEASE:=1 # Pinned honk-core revision (Glassyiris/honk feat/native-api), cross-compiled by # ci/build-core.sh. The per-architecture asset/hash are filled by that script; # keep a committed fallback so the feed still evaluates without a staging run. -CORE_COMMIT:=b71b6b65d4d81d4fa5795468b70ce9a37bb0e7dc +CORE_COMMIT:=aebc0d78d567cac1cd74ee9c56674857c5441451 -include $(CURDIR)/generated-stage.mk diff --git a/luci-app-daede/Makefile b/luci-app-daede/Makefile index abbf2cda..6514a54a 100644 --- a/luci-app-daede/Makefile +++ b/luci-app-daede/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-daede PKG_VERSION:=1.15 -PKG_RELEASE:=11 +PKG_RELEASE:=13 PKG_MAINTAINER:=kenzok8 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) diff --git a/luci-app-daede/htdocs/luci-static/resources/view/daede/updates.js b/luci-app-daede/htdocs/luci-static/resources/view/daede/updates.js index f4df1c52..c144f24e 100644 --- a/luci-app-daede/htdocs/luci-static/resources/view/daede/updates.js +++ b/luci-app-daede/htdocs/luci-static/resources/view/daede/updates.js @@ -425,14 +425,11 @@ return view.extend({ btn.disabled = true; } else if (updatable) { meta = _('installed') + ': ' + entry.r.installed + ' → ' + _('latest') + ': ' + entry.r.latest; - } else if (cmp < 0) { - meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('feed version older: %s').format(entry.r.latest); - btn.disabled = true; } else { meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('up to date'); btn.disabled = true; } - const uncertain = entry.r.installed && (indexState !== 'success' || !entry.r.latest || cmp < 0); + const uncertain = entry.r.installed && (indexState !== 'success' || !entry.r.latest); pkgBody.appendChild(mkRow( updatable ? '↑' : (uncertain ? '⚠' : (entry.r.installed ? '✓' : '✗')), updatable ? 'dd-up-new' : (uncertain ? 'dd-up-warn' : (entry.r.installed ? 'dd-up-ok' : 'dd-up-err')), diff --git a/luci-app-daede/po/zh-cn/daede.po b/luci-app-daede/po/zh-cn/daede.po index 82648e1f..dfcbc528 100644 --- a/luci-app-daede/po/zh-cn/daede.po +++ b/luci-app-daede/po/zh-cn/daede.po @@ -329,9 +329,6 @@ msgstr "正在刷新软件源" msgid "package not found in configured feeds" msgstr "当前软件源中没有此包" -msgid "feed version older: %s" -msgstr "软件源版本较旧:%s" - msgid "Unavailable" msgstr "不可用" diff --git a/luci-app-honk/Makefile b/luci-app-honk/Makefile index a5bfd618..f73039d7 100644 --- a/luci-app-honk/Makefile +++ b/luci-app-honk/Makefile @@ -5,14 +5,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-honk -PKG_VERSION:=2026.10.20 +PKG_VERSION:=2026.10.21 PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) -PKG_SOURCE:=doona-bc1cfbe5-be77900778e9.tar.gz +PKG_SOURCE:=doona-369aee8f-f6612106faf8.tar.gz PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-honk/releases/download/staging PKG_SOURCE_SUBDIR:=doona -PKG_HASH:=be77900778e980e3f396310631f20121140f6b54bd903345c515847fbed83081 +PKG_HASH:=f6612106faf8897178f91d464e0ba5f99eb46220eba0d984518104dd87fdcf57 -include $(CURDIR)/generated-doona-stage.mk diff --git a/luci-app-ssr-plus/Makefile b/luci-app-ssr-plus/Makefile index e07d2ff6..e48dfcb0 100644 --- a/luci-app-ssr-plus/Makefile +++ b/luci-app-ssr-plus/Makefile @@ -3,8 +3,8 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=luci-app-ssr-plus LUCI_PKGARCH:=all PKG_NAME:=luci-app-ssr-plus -PKG_VERSION:=196 -PKG_RELEASE:=24 +PKG_VERSION:=197 +PKG_RELEASE:=3 PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ @@ -114,7 +114,7 @@ endchoice config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG bool "Include ChinaDNS-NG" - default y if aarch64||arm||i386||x86_64 + default n config PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS bool "Include MosDNS" @@ -164,7 +164,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client bool "Include ShadowsocksR Libev Client" - default y + default n config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server bool "Include ShadowsocksR Libev Server" diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua index f5b46535..0938753a 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua @@ -1116,6 +1116,7 @@ end o = s:option(ListValue, "transport", translate("Transport")) o:value("raw", "RAW (TCP)") o:value("kcp", "mKCP") +o:value("kcptun", "Kcptun (Xray)") o:value("ws", "WebSocket") o:value("httpupgrade", "HTTPUpgrade") o:value("xhttp", "XHTTP (SplitHTTP)") @@ -1130,6 +1131,43 @@ o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) o:depends({type = "v2ray", v2ray_protocol = "socks"}) o:depends({type = "v2ray", v2ray_protocol = "http"}) +-- Native Kcptun transport (separate from mKCP and the external Kcptun client). +o = s:option(Value, "xray_kcptun_key", "Kcptun Key") +o:depends("transport", "kcptun") +o.password = true +o.rmempty = false +o = s:option(ListValue, "xray_kcptun_crypt", "Kcptun Encryption") +o:depends("transport", "kcptun") +for _, crypt in ipairs({"aes", "aes-128", "aes-192", "aes-128-gcm", "salsa20", "tea", "xor", "none", "null", "blowfish", "twofish", "cast5", "3des", "xtea"}) do o:value(crypt, crypt) end +o.default = "aes" +o = s:option(ListValue, "xray_kcptun_mode", "Kcptun Mode") +o:depends("transport", "kcptun") +for _, mode in ipairs({"normal", "fast", "fast2", "fast3", "manual"}) do o:value(mode, mode) end +o.default = "fast" +o = s:option(ListValue, "xray_kcptun_smuxver", "Kcptun smux Version") +o:depends("transport", "kcptun") +o:value("1", "v1") +o:value("2", "v2") +o.default = "1" +o = s:option(Flag, "xray_kcptun_nocomp", translate("Disable Compression")) +o:depends("transport", "kcptun") +o.default = "0" +o = s:option(Value, "xray_kcptun_conn", translate("Connections")) +o:depends("transport", "kcptun") +o.datatype = "range(1,256)" +o.default = "1" +o = s:option(TextValue, "xray_kcptun_options", "Kcptun Advanced Options (JSON)") +o:depends("transport", "kcptun") +o.rows = 4 +o.rmempty = true +o.description = translate("Optional MTU, FEC, windows and expiry settings. Encryption, key, compression and smux version must match the server. This transports streams over UDP; native proxy UDP is separate.") +function o.validate(self, value, section) + if not value or value:match("^%s*$") then return "" end + local ok, parsed = pcall(luci.jsonc.parse, value) + if ok and type(parsed) == "table" and value:match("^%s*{") then return value end + return nil, translate("Must be a JSON object") +end + -- [[ RAW部分 ]]-- -- TCP伪装 o = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) @@ -1493,6 +1531,39 @@ o.validate = function(self, value) end end +-- ShadowTLS wraps the existing TCP proxy protocol in Xray. +o = s:option(Flag, "xray_shadowtls", "ShadowTLS (Xray)") +o.default = "0" +for _, proto in ipairs({"vmess", "vless", "trojan", "shadowsocks"}) do + o:depends({type = "v2ray", v2ray_protocol = proto, transport = "raw", tls = false, reality = false}) +end +o.description = translate("ShadowTLS protects TCP connections. The inner proxy protocol must provide encryption.") +o = s:option(ListValue, "xray_shadowtls_version", "ShadowTLS Version") +o:depends("xray_shadowtls", "1") +o:value("3", "v3") +o:value("2", "v2") +o:value("1", "v1") +o.default = "3" +o = s:option(Value, "xray_shadowtls_password", "ShadowTLS Password") +o:depends({xray_shadowtls = "1", xray_shadowtls_version = "2"}) +o:depends({xray_shadowtls = "1", xray_shadowtls_version = "3"}) +o.password = true +o.rmempty = false +o = s:option(Value, "xray_shadowtls_sni", "ShadowTLS SNI") +o:depends("xray_shadowtls", "1") +o.datatype = "hostname" +o.rmempty = false +o = s:option(ListValue, "xray_shadowtls_fingerprint", translate("TLS Client Fingerprint")) +o:depends("xray_shadowtls", "1") +for _, fp in ipairs({"chrome", "firefox", "safari", "ios", "android", "edge", "none"}) do o:value(fp, fp) end +o.default = "chrome" +o = s:option(Flag, "xray_shadowtls_strict", translate("TLS 1.3 Strict mode")) +o:depends({xray_shadowtls = "1", xray_shadowtls_version = "3"}) +o.default = "1" +o = s:option(Flag, "xray_shadowtls_insecure", translate("Allow Insecure")) +o:depends("xray_shadowtls", "1") +o.default = "0" + -- [[ TLS ]]-- o = s:option(Flag, "tls", translate("TLS")) o.rmempty = true diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua index 72616683..13950ed6 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua @@ -77,6 +77,7 @@ if nixio.fs.access("/usr/bin/xray") or nixio.fs.access("/usr/libexec/xray") then o:value("tuic", "TUIC (Xray)") o:value("snell", "Snell (Xray)") o:value("anytls", "AnyTLS (Xray)") + o:value("ssr-xray", "ShadowsocksR (Xray)") end o.default = "socks5" @@ -108,6 +109,7 @@ o:depends("type", "ss") o:depends("type", "ssr") o:depends("type", "trojan") o:depends("type", "shadowsocks") +o:depends("type", "ssr-xray") -- ========== SS/SSR 协议特有 ========== o = s:option(ListValue, "encrypt_method", translate("Encrypt Method")) @@ -451,4 +453,28 @@ o.rows = 5 o.rmempty = true o:depends("type", "anytls") +-- Xray SSR has its own validated registry; keep legacy libev choices intact. +o = s:option(ListValue, "ssr_method", translate("Encrypt Method")) +for _, v in ipairs({"aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "rc4-md5", "chacha20", "chacha20-ietf", "xchacha20", "none"}) do o:value(v) end +o.default = "aes-128-cfb" +o.rmempty = false +o:depends("type", "ssr-xray") +o = s:option(ListValue, "ssr_protocol", translate("Protocol")) +for _, v in ipairs({"origin", "auth_sha1_v4", "auth_aes128_md5", "auth_aes128_sha1", "auth_chain_a", "auth_chain_b"}) do o:value(v) end +o.default = "auth_aes128_sha1" +o.rmempty = false +o:depends("type", "ssr-xray") +o = s:option(Value, "ssr_protocol_param", "SSR Protocol Param") +o.description = "1001:password1,1002:password2" +o:depends("type", "ssr-xray") +o = s:option(ListValue, "ssr_obfs", translate("Obfs")) +for _, v in ipairs({"plain", "http_simple", "http_post", "random_head", "tls1.2_ticket_auth", "tls1.2_ticket_fastauth"}) do o:value(v) end +o.default = "plain" +o.rmempty = false +o:depends("type", "ssr-xray") +o = s:option(Value, "ssr_obfs_param", translate("Obfs param (optional)")) +o.description = "HTTP Host: example.com,example.org" +o:depends({type = "ssr-xray", ssr_obfs = "http_simple"}) +o:depends({type = "ssr-xray", ssr_obfs = "http_post"}) + return m diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua index c2ac03c6..55390a65 100644 --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua @@ -111,6 +111,7 @@ function o.cfgvalue(self, section) elseif val == "vless" then return "VLESS (Xray)" elseif val == "trojan" then return "Trojan (Xray)" elseif val == "shadowsocks" then return "Shadowsocks (Xray)" + elseif val == "ssr-xray" then return "ShadowsocksR (Xray)" else return val end end @@ -126,6 +127,7 @@ end o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method")) function o.cfgvalue(self, section) + if self.map:get(section, "type") == "ssr-xray" then return (self.map:get(section, "ssr_method") or "-"):upper() end local method = self.map:get(section, "encrypt_method") or self.map:get(section, "encrypt_method_ss") return method and method:upper() or "-" end diff --git a/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr index 458b2319..bc43b4ce 100755 --- a/luci-app-ssr-plus/root/etc/init.d/shadowsocksr +++ b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr @@ -992,6 +992,8 @@ use_mihomo_for_ss_rust_server() { } start_v2ray_with_mihomo() { + [ "$(uci_get_by_name "$1" transport)" = "kcptun" ] && return 1 + [ "$(uci_get_by_name "$1" xray_shadowtls 0)" = "1" ] && return 1 # These nodes use Xray-specific settings. case "$(uci_get_by_name "$1" v2ray_protocol)" in naive|shadowsocksr|tuic) return 1 ;; esac local sid="$1" @@ -2247,6 +2249,10 @@ get_udp_relay_mode() { ;; v2ray) proto=$(uci_get_by_name "$node" v2ray_protocol) + if [ "$(uci_get_by_name "$node" transport)" = "kcptun" ]; then + case "$proto" in vmess|vless|trojan) echo "native" ;; *) echo "disabled" ;; esac + return + fi case "$proto" in snell) case "$(uci_get_by_name "$node" snell_version 4)" in 1|2) echo "disabled" ;; *) echo "native" ;; esac @@ -2749,6 +2755,16 @@ start_server() { echolog "Server: Xray NaiveProxy Server$server_count Started!" ;; + ssr-xray) + xray_bin="$(first_type xray)" + [ -x "$xray_bin" ] || return 1 + config_file="$TMP_PATH/xray-server-$server_count.json" + lua /usr/share/shadowsocksr/gen_ssr_server.lua "$1" > "$config_file" || return 1 + "$xray_bin" run -test -c "$config_file" >> /var/ssrplus.log 2>&1 || return 1 + ln_start_bin "$xray_bin" xray-server-$server_count run -c "$config_file" + echolog "Server: Xray ShadowsocksR Server$server_count Started!" + ;; + anytls) xray_bin="$(first_type xray)" [ -x "$xray_bin" ] || return 1 diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua b/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua index bf4a8cf3..4f0eabf5 100755 --- a/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua @@ -935,6 +935,45 @@ if server.v2ray_protocol == "naive" or server.v2ray_protocol == "shadowsocksr" o ob.mux = nil end +if server.type == "v2ray" and server.transport == "kcptun" then + local supported = {vmess = true, vless = true, trojan = true, shadowsocks = true, socks = true, http = true} + assert(supported[server.v2ray_protocol], "Kcptun requires a supported stream proxy protocol") + assert(server.tls ~= "1" and server.reality ~= "1" and server.xtls ~= "1", "Kcptun cannot be combined with stream TLS or REALITY") + assert(server.kcp_enable ~= "1", "Native Kcptun cannot be combined with the external Kcptun client") + assert(not server.tls_flow or server.tls_flow == "", "Kcptun cannot be combined with XTLS flow") + local options = {} + if server.xray_kcptun_options and server.xray_kcptun_options:match("%S") then + assert(server.xray_kcptun_options:match("^%s*{"), "Kcptun options must be a JSON object") + options = json.parse(server.xray_kcptun_options) + assert(type(options) == "table", "Kcptun options must be a JSON object") + end + options.key = server.xray_kcptun_key + options.crypt = server.xray_kcptun_crypt or "aes" + options.mode = server.xray_kcptun_mode or "fast" + options.smuxver = tonumber(server.xray_kcptun_smuxver) or 1 + options.nocomp = server.xray_kcptun_nocomp == "1" + options.conn = tonumber(server.xray_kcptun_conn) or 1 + Xray.outbounds[1].streamSettings.kcptunSettings = options +end + +if server.type == "v2ray" and server.xray_shadowtls == "1" then + local supported = {vmess = true, vless = true, trojan = true, shadowsocks = true} + assert(supported[server.v2ray_protocol], "ShadowTLS requires a supported TCP proxy protocol") + assert((server.transport or "raw") == "raw" or server.transport == "tcp", "ShadowTLS requires RAW/TCP") + assert(server.tls ~= "1" and server.reality ~= "1", "ShadowTLS cannot be combined with TLS or REALITY") + assert(not server.tls_flow or server.tls_flow == "", "ShadowTLS cannot be combined with XTLS flow") + local stream = Xray.outbounds[1].streamSettings + stream.security = "shadowtls" + stream.shadowtlsSettings = { + version = tonumber(server.xray_shadowtls_version) or 3, + password = server.xray_shadowtls_password, + serverName = server.xray_shadowtls_sni, + fingerprint = server.xray_shadowtls_fingerprint or "chrome", + strictMode = server.xray_shadowtls_strict ~= "0", + allowInsecure = server.xray_shadowtls_insecure == "1" + } +end + if xray_builtin_dns then table.insert(Xray.outbounds, { protocol = "dns", diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_ssr_server.lua b/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_ssr_server.lua new file mode 100644 index 00000000..bb22aaa4 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_ssr_server.lua @@ -0,0 +1,13 @@ +#!/usr/bin/lua +local uci = require("luci.model.uci").cursor() +local json = require "luci.jsonc" +local s = assert(uci:get_all("shadowsocksr", arg[1]), "missing server section") +print(json.stringify({ + log = {loglevel = "warning"}, + inbounds = {{listen = "::", port = assert(tonumber(s.server_port)), protocol = "shadowsocksr", + settings = {password = assert(s.password), method = s.ssr_method or "aes-128-cfb", + protocol = s.ssr_protocol or "auth_aes128_sha1", protocolParam = s.ssr_protocol_param or "", + obfs = s.ssr_obfs or "plain", obfsParam = s.ssr_obfs_param or "", network = "tcp,udp"} + }}, + outbounds = {{protocol = "freedom", settings = {}}} +}, 1)) diff --git a/v2ray-core/Makefile b/v2ray-core/Makefile index 35515230..e3c3a8cd 100644 --- a/v2ray-core/Makefile +++ b/v2ray-core/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=v2ray-core -PKG_VERSION:=5.54.2 +PKG_VERSION:=5.55.0 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/v2fly/v2ray-core/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=fd171b094376701aa07f1bb4ab9bf4dc67bd4df014673ec545ad362360341364 +PKG_HASH:=3ca056dbfffeed536d92b4a76f9984bc95aa13f4ded61cb85e43d9c283de0b5b PKG_LICENSE:=MIT PKG_LICENSE_FILES:=LICENSE diff --git a/v2ray-geodata/Makefile b/v2ray-geodata/Makefile index e63fe26a..908838cd 100644 --- a/v2ray-geodata/Makefile +++ b/v2ray-geodata/Makefile @@ -21,13 +21,13 @@ define Download/geoip HASH:=4ff4b2ec242a9e87b296ba27ddb85f8311e8d3e071eaebac5be9231c60e408dd endef -GEOSITE_VER:=20261020135944 +GEOSITE_VER:=20261021011254 GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) define Download/geosite URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL_FILE:=dlc.dat FILE:=$(GEOSITE_FILE) - HASH:=bddbeb5f0980a7c852a79e5ae403757199157bb61d7f3b6640cce8a4c83b8e7b + HASH:=ef725a08ba804effd5b5b6e747c8c28eabc54ed068d786d7366d067d2e1a3849 endef GEOSITE_IRAN_VER:=202610120242