From 3dfbec421510806564cbe2071cf101614f759842 Mon Sep 17 00:00:00 2001 From: fscarmen <62703343+fscarmen@users.noreply.github.com> Date: Wed, 1 Jul 2026 06:44:10 +0000 Subject: [PATCH] v1.3.15 feat: improve hysteria2 realm UX, fix port hopping, add v2rayN realm support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add v2rayN Finalmask field for hysteria2 realm subscription output - add dedicated "Close Realm" / "Open Realm" menu entries (E[167]/E[168]) - detect realm state from subscribe/proxies realm-opts instead of reading config file - skip fetch_nodes_value when closing realm; keep it when opening - fix port hopping target parsing (strip leading whitespace from awk output) - keep server/server_port in sing-box json output when realm is enabled, realm as additional field v1.3.15 feat: 优化 Hysteria2 Realm 交互体验,修复端口跳跃,新增 v2rayN Realm 支持 - v2rayN 订阅输出增加 Realm 的 Finalmask 字段 - 新增"关闭 Realm"/"开启 Realm"独立菜单项(E[167]/E[168]) - 通过 subscribe/proxies 的 realm-opts 判断 Realm 状态,不再读取配置文件 - 关闭 Realm 时跳过 fetch_nodes_value,开启时保留 - 修复端口跳跃目标解析(去除 awk 输出的前导空格) - sing-box JSON 输出开启 Realm 时保留 server/server_port,realm 作为附加字段 --- README.md | 13 +++++++------ sing-box.sh | 54 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index e70a67f..ad72bf4 100644 --- a/README.md +++ b/README.md @@ -24,19 +24,20 @@ * * * ## 1.更新信息 +2026.07.01 v1.3.15 Add v2rayN Finalmask field for hysteria2 realm subscription output; v2rayN 订阅输出增加 Hysteria2 Realm 的 Finalmask 字段 2026.05.29 v1.3.14 Added optional custom warp route rule management, available after installation via [sb -d] without affecting the main installation flow; 增加可选的自定义 warp 路由规则管理,不影响主程序安装流程,安装后可通过 [sb -d] 按需管理 -2026.05.18 v1.3.13 Added top-level http_clients configuration; 增加顶层的 http_clients 配置 - -2026.05.14 v1.3.12 1. Add Hysteria2 Realm support for machines without public inbound access, with optional WARP-assisted hole punching for strict NAT environments; 2. Realm configuration export is supported for Clash/Mihomo and sing-box clients; 3. Hysteria2 Realm can be enabled or disabled directly via sb -d; 4. Non-interactive installs support --HY2_REALM and --HY2_WARP parameters; 1. 增加 Hysteria2 Realm 支持,适用于没有公网入口的机器,并可选 WARP 辅助打洞; 2. Realm 已支持导出 Clash/Mihomo 和 sing-box 客户端配置; 3. 修改节点配置时可直接开启或关闭 Hysteria2 Realm; 4. 无交互安装支持 --HY2_REALM 与 --HY2_WARP 参数 - -2026.05.06 v1.3.11 1. Generate v2rayn:// dedicated links for Tuic subscriptions; 2. Generate v2rayn:// dedicated links for AnyTLS subscriptions; 3. Generate v2rayn:// dedicated links for naive http2 and quic modes. Thanks to @DHR60; 1. 为 Tuic 订阅生成 v2rayn:// 专属链接; 2. 为 AnyTLS 订阅生成 v2rayn:// 专属链接; 3. 为 naive http2 和 quic 模式生成 v2rayn:// 专属链接,感谢 @DHR60 -
历史更新 history(点击即可展开或收起)
+>2026.05.18 v1.3.13 Added top-level http_clients configuration; 增加顶层的 http_clients 配置 +> +>2026.05.14 v1.3.12 1. Add Hysteria2 Realm support for machines without public inbound access, with optional WARP-assisted hole punching for strict NAT environments; 2. Realm configuration export is supported for Clash/Mihomo and sing-box clients; 3. Hysteria2 Realm can be enabled or disabled directly via sb -d; 4. Non-interactive installs support --HY2_REALM and --HY2_WARP parameters; 1. 增加 Hysteria2 Realm 支持,适用于没有公网入口的机器,并可选 WARP 辅助打洞; 2. Realm 已支持导出 Clash/Mihomo 和 sing-box 客户端配置; 3. 修改节点配置时可直接开启或关闭 Hysteria2 Realm; 4. 无交互安装支持 --HY2_REALM 与 --HY2_WARP 参数 +> +>2026.05.06 v1.3.11 1. Generate v2rayn:// dedicated links for Tuic subscriptions; 2. Generate v2rayn:// dedicated links for AnyTLS subscriptions; 3. Generate v2rayn:// dedicated links for naive http2 and quic modes. Thanks to @DHR60; 1. 为 Tuic 订阅生成 v2rayn:// 专属链接; 2. 为 AnyTLS 订阅生成 v2rayn:// 专属链接; 3. 为 naive http2 和 quic 模式生成 v2rayn:// 专属链接,感谢 @DHR60 +> >2026.04.25 v1.3.10 Added native protocol, but client support is extremely limited, with Shadowrocket offering the best compatibility. For the sing-box core, you must use the -glibc or -musl version according to the requirements; refer to the official documentation for details: https://sing-box.sagernet.org/configuration/outbound/naive/; 增加 native 协议,支持该协议的客户端极少,Shadowrocket 支持最好。sing-box 内核需要按说明使用-glibc 或者 -musl 版本,详见官方说明 https://sing-box.sagernet.org/zh/configuration/outbound/naive/ > >2026.04.11 v1.3.9 1. remove pre-install UFW blocking logic, fallback to iptables when inactive; 2. avoid unnecessary sing-box restart for CDN / bandwidth / port hopping changes; 3. reduce redundant single-use functions; 1. 移除安装前 UFW 强制校验,inactive 自动回退 iptables; 2. 优选地址 / 带宽 / 端口跳跃修改不再重启 sing-box; 3. 清理单次调用函数,提升结构可读性 diff --git a/sing-box.sh b/sing-box.sh index 01601fb..b818b43 100644 --- a/sing-box.sh +++ b/sing-box.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # 当前脚本版本号 -VERSION='v1.3.14 (2026.06.27)' +VERSION='v1.3.15 (2026.07.01)' # Github 反代加速代理 GITHUB_PROXY=('https://hub.glowp.xyz/' 'https://proxy.vvvv.ee/') @@ -40,8 +40,8 @@ mkdir -p "$TEMP_DIR" E[0]="Language:\n 1. English (default) \n 2. 简体中文" C[0]="${E[0]}" -E[1]="1. Added optional custom warp route rule management, available after installation via [sb -d] without affecting the main installation flow; 2. Added Hysteria2 Realm support for machines without public inbound access, with optional WARP-assisted hole punching" -C[1]="1. 增加可选的自定义 warp 路由规则管理,不影响主程序安装流程,安装后可通过 [sb -d] 按需管理; 2. 增加 Hysteria2 Realm 支持,适用于没有公网入口的机器,并可选 WARP 辅助打洞" +E[1]="1. Added Hysteria2 Realm support for machines without public inbound access, with optional WARP-assisted hole punching; 2. add v2rayN Finalmask field for hysteria2 realm subscription output" +C[1]="1. 增加 Hysteria2 Realm 支持,适用于没有公网入口的机器,并可选 WARP 辅助打洞; 2. v2rayN 订阅输出增加 Realm 的 Finalmask 字段" E[2]="Downloading Sing-box. Please wait a seconds ..." C[2]="下载 Sing-box 中,请稍等 ..." E[3]="Input errors up to 5 times.The script is aborted." @@ -370,6 +370,10 @@ E[165]="Please select or input client fingerprint:\n 1. chrome (default)\n 2. fi C[165]="请选择或输入客户端指纹:\n 1. chrome (默认)\n 2. firefox\n 或直接输入自定义值:" E[166]="Invalid fingerprint format." C[166]="无效的指纹格式" +E[167]="Close Realm" +C[167]="关闭 Realm" +E[168]="Open Realm" +C[168]="开启 Realm" # 自定义字体彩色,read 函数 warning() { echo -e "\033[31m\033[01m$*\033[0m"; } # 红色 @@ -679,13 +683,14 @@ change_config() { MENU_IDX+=(140) && MENU_KEY+=(hy2bw) && MENU_VAL+=("${HY2_UP_NOW}/${HY2_DOWN_NOW}") - local HY2_CONF_NOW=$(ls ${WORK_DIR}/conf/*_${NODE_TAG[1]}_inbounds.json 2>/dev/null | sed -n '1p') - if [ -n "$HY2_CONF_NOW" ] && grep -q '"realm"[[:space:]]*:' "$HY2_CONF_NOW"; then - local HY2_REALM_ACTION="$(text 27)" + if grep -q 'realm-opts' <<< "$HY2_LINE"; then + local HY2_REALM_ACTION="$(text 167)" + MENU_IDX+=(167) else - local HY2_REALM_ACTION="$(text 28)" + local HY2_REALM_ACTION="$(text 168)" + MENU_IDX+=(168) fi - MENU_IDX+=(147) && MENU_KEY+=(hy2realm) && MENU_VAL+=("${HY2_REALM_ACTION}") + MENU_KEY+=(hy2realm) && MENU_VAL+=("${HY2_REALM_ACTION}") check_port_hopping_nat MENU_IDX+=(139) && MENU_KEY+=(hy2hopping) && MENU_VAL+=("${HY2_PORT_HOPPING_RANGE}") @@ -767,11 +772,15 @@ change_config() { return elif [ "$KEY" = "hy2realm" ]; then # 添加 / 删除 Hysteria2 Realm;菜单已明确显示开启/关闭动作,这里不再二次确认 Realm 本身 - fetch_nodes_value - if [ "$IS_HY2_REALM" = 'is_hy2_realm' ]; then + # 判断依据与菜单显示一致:检查 subscribe/proxies 中是否有 realm-opts + local HY2_LINE=$(grep 'type: hysteria2' ${WORK_DIR}/subscribe/proxies) + if grep -q 'realm-opts' <<< "$HY2_LINE"; then + # 已开启 → 直接关闭,不需要二次确认 set_hy2_realm_config disable sync_hy2_warp_route disable else + # 未开启 → 获取配置后开启,询问 WARP 辅助打洞 + fetch_nodes_value IS_HY2_REALM=is_hy2_realm HY2_REALM_ID="${HY2_REALM_ID:-${UUID[12]:-${UUID_CONFIRM}}}" input_hy2_warp @@ -817,7 +826,7 @@ change_config() { PORT_HOPPING_END=$NEW_END HY2_PORT_HOPPING_RANGE="$NEW_RANGE" local HOPPING_TARGET="$PORT_HOPPING_TARGET" - [ -z "$HOPPING_TARGET" ] && HOPPING_TARGET=$(awk -F '[:,]' '/"listen_port"/{print $2; exit}' ${WORK_DIR}/conf/*_${NODE_TAG[1]}_inbounds.json 2>/dev/null) + [ -z "$HOPPING_TARGET" ] && HOPPING_TARGET=$(awk -F '[:,]' '/"listen_port"/{print $2; exit}' ${WORK_DIR}/conf/*_${NODE_TAG[1]}_inbounds.json 2>/dev/null | tr -d ' ') # 静默添加端口跳跃规则,不显示 UFW 检测和成功提示 (add_port_hopping_nat "$PORT_HOPPING_START" "$PORT_HOPPING_END" "$HOPPING_TARGET") >/dev/null 2>&1 IS_HOPPING_SET=true @@ -2251,7 +2260,7 @@ check_port_hopping_nat() { FW_BACKEND=$(check_port_hopping_firewall) unset PORT_HOPPING_START PORT_HOPPING_END HY2_PORT_HOPPING_RANGE - PORT_HOPPING_TARGET=$(awk -F '[:,]' '/"listen_port"/{print $2; exit}' ${WORK_DIR}/conf/*${NODE_TAG[1]}_inbounds.json 2>/dev/null) + PORT_HOPPING_TARGET=$(awk -F '[:,]' '/"listen_port"/{print $2; exit}' ${WORK_DIR}/conf/*${NODE_TAG[1]}_inbounds.json 2>/dev/null | tr -d ' ') if [ "$FW_BACKEND" = 'ufw' ]; then check_port_hopping_ufw_rules @@ -4713,9 +4722,16 @@ vless://${UUID[11]}@${SERVER_IP_1}:${PORT_XTLS_REALITY}?encryption=none${VISION_ if [ -n "$PORT_HYSTERIA2" ]; then [[ -n "$PORT_HOPPING_START" && -n "$PORT_HOPPING_END" ]] && local V2RAYN_PARAMS=",\"Ports\":\"${PORT_HOPPING_START}-${PORT_HOPPING_END}\",\"HopInterval\":\"30s\"" + local REALM_PARAMS="" + [ "$IS_HY2_REALM" = 'is_hy2_realm' ] && REALM_PARAMS=",\"Finalmask\":\"{\\n \\\"udp\\\": [\\n {\\n \\\"type\\\": \\\"realm\\\",\\n \\\"settings\\\": {\\n \\\"url\\\": \\\"realm://public@realm.hy2.io:443/${UUID[12]}\\\",\\n \\\"stunServers\\\": [\\n \\\"stun.nextcloud.com:3478\\\",\\n \\\"stun.sip.us:3478\\\",\\n \\\"turn.cloudflare.com:3478\\\",\\n \\\"global.stun.twilio.com:3478\\\"\\n ]\\n }\\n }\\n ],\\n \\\"quicParams\\\": {\\n \\\"congestion\\\": \\\"bbr\\\"\\n }\\n }\"" + + local HY2_JSON_1="{\"ConfigType\":7,\"ConfigVersion\":4,\"Remarks\":\"${NODE_NAME[12]} ${NODE_TAG[1]}\",\"Address\":\"${SERVER_IP}\",\"Port\":${PORT_HYSTERIA2},\"Password\":\"${UUID[12]}\",\"StreamSecurity\":\"tls\",\"AllowInsecure\":\"false\",\"Sni\":\"${TLS_SERVER}\",\"Cert\":\"${CERT_URL_2}\"" + local HY2_JSON_2=",\"ProtoExtraObj\":{\"UpMbps\":${HY2_UP:-200},\"DownMbps\":${HY2_DOWN:-1000}" + local HY2_JSON_3="}}" + local CLEAN_V2RAYN_PARAMS="${V2RAYN_PARAMS:-}" local V2RAYN_SUBSCRIBE+=" ---------------------------- -v2rayn://hysteria2/$(echo -n "{\"ConfigType\":7,\"ConfigVersion\":4,\"Remarks\":\"${NODE_NAME[12]} ${NODE_TAG[1]}\",\"Address\":\"${SERVER_IP}\",\"Port\":${PORT_HYSTERIA2},\"Password\":\"${UUID[12]}\",\"StreamSecurity\":\"tls\",\"AllowInsecure\":\"false\",\"Sni\":\"${TLS_SERVER}\",\"Cert\":\"${CERT_URL_2}\",\"ProtoExtraObj\":{\"UpMbps\":${HY2_UP},\"DownMbps\":${HY2_DOWN}${V2RAYN_PARAMS}}}" | base64 -w0 | tr '+/' '-_' | tr -d '=')" +v2rayn://hysteria2/$(printf "%s%s%s%s%s\n" "$HY2_JSON_1" "$REALM_PARAMS" "${HY2_JSON_2%$'\n'*}" "${CLEAN_V2RAYN_PARAMS%$'\n'*}" "$HY2_JSON_3" | base64 -w0 | tr '+/' '-_' | tr -d '=')" fi [ -n "$PORT_TUIC" ] && local V2RAYN_SUBSCRIBE+=" @@ -4935,14 +4951,14 @@ naive+quic://${UUID[22]}:${UUID[22]}@${SERVER_IP_1}:${PORT_NAIVE}?congestion_con local NODE_REPLACE+="\"${NODE_NAME[11]} ${NODE_TAG[0]}\"," if [ -n "$PORT_HYSTERIA2" ]; then + local HYSTERIA2_CONFIG=" { \"type\": \"hysteria2\", \"tag\": \"${NODE_NAME[12]} ${NODE_TAG[1]}\", \"server\": \"${SERVER_IP}\", \"server_port\": ${PORT_HYSTERIA2}, \"up_mbps\": ${HY2_UP}, \"down_mbps\": ${HY2_DOWN}, \"password\": \"${UUID[12]}\", \"tls\": { \"enabled\": true, \"server_name\": \"${TLS_SERVER}\", \"certificate_public_key_sha256\": [\"$SELF_SIGNED_FINGERPRINT_BASE64\"], \"alpn\": [ \"h3\" ] }" if [ "$IS_HY2_REALM" = 'is_hy2_realm' ]; then HY2_REALM_ID="${HY2_REALM_ID:-${UUID[12]}}" - local HYSTERIA2_CONFIG=" { \"type\": \"hysteria2\", \"tag\": \"${NODE_NAME[12]} ${NODE_TAG[1]}\", \"up_mbps\": ${HY2_UP}, \"down_mbps\": ${HY2_DOWN}, \"password\": \"${UUID[12]}\", \"tls\": { \"enabled\": true, \"server_name\": \"${TLS_SERVER}\", \"certificate_public_key_sha256\": [\"$SELF_SIGNED_FINGERPRINT_BASE64\"], \"alpn\": [ \"h3\" ] }, \"realm\": { \"server_url\": \"https://realm.hy2.io\", \"token\": \"public\", \"realm_id\": \"${HY2_REALM_ID}\", \"stun_servers\": [ \"turn.cloudflare.com:3478\", \"stun.nextcloud.com:3478\", \"stun.sip.us:3478\", \"global.stun.twilio.com:3478\" ] } }," - else - local HYSTERIA2_CONFIG=" { \"type\": \"hysteria2\", \"tag\": \"${NODE_NAME[12]} ${NODE_TAG[1]}\", \"server\": \"${SERVER_IP}\", \"server_port\": ${PORT_HYSTERIA2}, \"up_mbps\": ${HY2_UP}, \"down_mbps\": ${HY2_DOWN}, \"password\": \"${UUID[12]}\", \"tls\": { \"enabled\": true, \"server_name\": \"${TLS_SERVER}\", \"certificate_public_key_sha256\": [\"$SELF_SIGNED_FINGERPRINT_BASE64\"], \"alpn\": [ \"h3\" ] } }," - if [[ -n "${PORT_HOPPING_START}" && -n "${PORT_HOPPING_END}" ]]; then - HYSTERIA2_CONFIG="${HYSTERIA2_CONFIG/\"server_port\": ${PORT_HYSTERIA2},/\"server_port\": ${PORT_HYSTERIA2}, \"server_ports\": [ \"${PORT_HOPPING_START}:${PORT_HOPPING_END}\" ], \"hop_interval\": \"30s\", \"hop_interval_max\": \"60s\",}" - fi + HYSTERIA2_CONFIG+=", \"realm\": { \"server_url\": \"https://realm.hy2.io\", \"token\": \"public\", \"realm_id\": \"${HY2_REALM_ID}\", \"stun_servers\": [ \"turn.cloudflare.com:3478\", \"stun.nextcloud.com:3478\", \"stun.sip.us:3478\", \"global.stun.twilio.com:3478\" ] }" + fi + HYSTERIA2_CONFIG+=" }," + if [[ -n "${PORT_HOPPING_START}" && -n "${PORT_HOPPING_END}" ]]; then + HYSTERIA2_CONFIG="${HYSTERIA2_CONFIG/\"server_port\": ${PORT_HYSTERIA2},/\"server_port\": ${PORT_HYSTERIA2}, \"server_ports\": [ \"${PORT_HOPPING_START}:${PORT_HOPPING_END}\" ], \"hop_interval\": \"30s\", \"hop_interval_max\": \"60s\",}" fi local OUTBOUND_REPLACE+="${HYSTERIA2_CONFIG}" local NODE_REPLACE+="\"${NODE_NAME[12]} ${NODE_TAG[1]}\","