www.apple.com 为伪装地址,前端警告消失
This commit is contained in:
@@ -13,9 +13,13 @@
|
|||||||
# NAT / 端口转发的机器上出口 IP 与入站 IP 可能不同,此时必须手动指定
|
# NAT / 端口转发的机器上出口 IP 与入站 IP 可能不同,此时必须手动指定
|
||||||
# SERVER_IP=1.2.3.4
|
# SERVER_IP=1.2.3.4
|
||||||
|
|
||||||
# Reality 伪装目标(留空则自动选择延迟最低的)
|
# Reality 伪装目标(留空则自动从候选中挑选,见 deploy.sh 的 select_reality_dest)
|
||||||
# REALITY_DEST=www.microsoft.com
|
# 手动指定时务必确认新域名满足两个条件,否则客户端会刷 REALITY 报错:
|
||||||
# REALITY_SNI=www.microsoft.com
|
# 1) TLS 1.3 且证书链 < 8192 字节(用 xray tls ping <域名> 查「with SNI」那段)
|
||||||
|
# 2) 该域名会被客户端路由判成「直连」(命中 geosite:cn)
|
||||||
|
# 已知不可用:dl.google.com(命中 geosite:google)、www.microsoft.com、www.amazon.com
|
||||||
|
# REALITY_DEST=www.apple.com
|
||||||
|
# REALITY_SNI=www.apple.com
|
||||||
|
|
||||||
# 每日 04:00 自动重启 Xray(默认 false)
|
# 每日 04:00 自动重启 Xray(默认 false)
|
||||||
# 崩溃恢复已由 systemd 的 Restart=always 覆盖(秒级响应),
|
# 崩溃恢复已由 systemd 的 Restart=always 覆盖(秒级响应),
|
||||||
|
|||||||
@@ -163,6 +163,36 @@ bash deploy.sh --redetect
|
|||||||
|
|
||||||
> ⚠️ 换完后 SNI 变了,**所有客户端都必须用新的分享链接重新配置**。脚本会在更换时打印醒目提示。
|
> ⚠️ 换完后 SNI 变了,**所有客户端都必须用新的分享链接重新配置**。脚本会在更换时打印醒目提示。
|
||||||
|
|
||||||
|
#### 自定义伪装目标时的两个硬条件
|
||||||
|
|
||||||
|
在 `.env` 里手动指定 `REALITY_DEST` / `REALITY_SNI` 前,必须确认新域名同时满足:
|
||||||
|
|
||||||
|
**1. 技术条件** — TLS 1.3,且证书链总长 < 8192 字节。上限是 `xtls/reality` 里的硬编码值,超出会直接握手失败(见 [XTLS/Xray-core#6356](https://github.com/XTLS/Xray-core/issues/6356),`www.microsoft.com` 的 8273 字节即触发)。在服务器上自查:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xray tls ping www.apple.com # 只看「Pinging with SNI」那一段
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. 客户端路由条件** — 该域名必须会被客户端判成「直连」。
|
||||||
|
|
||||||
|
这条不直观。TUN 模式下客户端偶尔会把「连接本代理服务器」这件事本身也抓进代理(v2rayN 的 sing-box + xray 双核心靠进程嗅探防回环,Windows 上存在竞态)。这种回环连接的去向完全由 SNI 决定:
|
||||||
|
|
||||||
|
| SNI 被判为 | 结果 |
|
||||||
|
|---|---|
|
||||||
|
| 直连 | 连接真的到达本服务器,REALITY 握手成功,**用户无感** |
|
||||||
|
| 走代理 | 进隧道 → 服务器替客户端连了真正的伪装站 → 客户端收到真证书 → 刷屏 `REALITY: received real certificate` |
|
||||||
|
|
||||||
|
实测(v2rayN 默认规则模板,`geosite:google → proxy` 排在 `geosite:cn → direct` 之前):
|
||||||
|
|
||||||
|
| 域名 | 命中规则 | 可用性 |
|
||||||
|
|---|---|---|
|
||||||
|
| `www.apple.com`、`*.apple.com` | `geosite:cn` | ✅ 安全 |
|
||||||
|
| `dl.google.com` | `geosite:google` | ❌ 不安全 |
|
||||||
|
| `www.microsoft.com` | 都不命中 → `final:proxy` | ❌ 不安全 |
|
||||||
|
| `www.amazon.com` | 都不命中 → `final:proxy` | ❌ 不安全 |
|
||||||
|
|
||||||
|
脚本的候选列表因此只保留 Apple 系域名。
|
||||||
|
|
||||||
### 查看状态 / 日志
|
### 查看状态 / 日志
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -5,20 +5,20 @@
|
|||||||
IP : 64.81.25.247
|
IP : 64.81.25.247
|
||||||
端口 : 443
|
端口 : 443
|
||||||
协议 : VLESS
|
协议 : VLESS
|
||||||
UUID : b2f1198d-9475-40af-a2c6-2738a69b4e06
|
UUID : 7c7de15f-d408-4534-b367-f6253e850178
|
||||||
流控 : xtls-rprx-vision
|
流控 : xtls-rprx-vision
|
||||||
传输 : tcp
|
传输 : tcp
|
||||||
安全 : reality
|
安全 : reality
|
||||||
SNI : www.apple.com
|
SNI : www.apple.com
|
||||||
Fingerprint : chrome
|
Fingerprint : chrome
|
||||||
PublicKey : fKRVRMVlmmedi2rFk-cetAT397V-IzRifStKQcMTilM
|
PublicKey : AvX70NC1Tqd1sFBvASY-2oitzS2OpCsZu-H1ucVDUBM
|
||||||
ShortId : fca381b1ac6f4d02
|
ShortId : fa4235504a09feeb
|
||||||
|
|
||||||
==========================================================
|
==========================================================
|
||||||
|
|
||||||
>>> VLESS 分享链接(可直接导入客户端):
|
>>> VLESS 分享链接(可直接导入客户端):
|
||||||
|
|
||||||
vless://b2f1198d-9475-40af-a2c6-2738a69b4e06@64.81.25.247:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=www.apple.com&fp=chrome&pbk=fKRVRMVlmmedi2rFk-cetAT397V-IzRifStKQcMTilM&sid=fca381b1ac6f4d02&type=tcp#vps-reality-lisa-1
|
vless://7c7de15f-d408-4534-b367-f6253e850178@64.81.25.247:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=www.apple.com&fp=chrome&pbk=AvX70NC1Tqd1sFBvASY-2oitzS2OpCsZu-H1ucVDUBM&sid=fa4235504a09feeb&type=tcp#vps-reality-lisa-1
|
||||||
|
|
||||||
==========================================================
|
==========================================================
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
==========================================================
|
||||||
|
Xray VLESS-Reality 部署完成 ✅
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
IP : 140.82.23.27
|
||||||
|
端口 : 443
|
||||||
|
协议 : VLESS
|
||||||
|
UUID : 3cac4c5e-c9ae-488f-9cde-0c65b2d23409
|
||||||
|
流控 : xtls-rprx-vision
|
||||||
|
传输 : tcp
|
||||||
|
安全 : reality
|
||||||
|
SNI : www.apple.com
|
||||||
|
Fingerprint : chrome
|
||||||
|
PublicKey : 5hukUZGoGAs4Fpj2Bc7_1nGQykdaYN1sznG-KsxYUD8
|
||||||
|
ShortId : 4c5999dd1b15ff3c
|
||||||
|
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
>>> VLESS 分享链接(可直接导入客户端):
|
||||||
|
|
||||||
|
vless://3cac4c5e-c9ae-488f-9cde-0c65b2d23409@140.82.23.27:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=www.apple.com&fp=chrome&pbk=5hukUZGoGAs4Fpj2Bc7_1nGQykdaYN1sznG-KsxYUD8&sid=4c5999dd1b15ff3c&type=tcp#vps-reality-3
|
||||||
|
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
⚠️ 请妥善保存以上信息!
|
||||||
|
配置文件: /usr/local/etc/xray/config.json
|
||||||
|
凭据备份: /opt/vps-xray/.env
|
||||||
|
再次查看: bash deploy.sh --show
|
||||||
|
查看日志: journalctl -u xray -f
|
||||||
|
重启服务: systemctl restart xray
|
||||||
|
==========================================================
|
||||||
+73
-10
@@ -234,6 +234,39 @@ generate_keys() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ===== 候选伪装站的技术校验 =====
|
||||||
|
# 只看 xray tls ping 的「Pinging with SNI」那一段:REALITY 实际用的是带 SNI 的
|
||||||
|
# 握手结果,无 SNI 段返回的往往是另一张证书(如 Google 的 invalid2.invalid,
|
||||||
|
# 才 895 字节),照它判会误判。
|
||||||
|
REALITY_DEST_CERT_LEN=""
|
||||||
|
check_reality_dest() {
|
||||||
|
local site="$1" out len
|
||||||
|
REALITY_DEST_CERT_LEN=""
|
||||||
|
|
||||||
|
local raw
|
||||||
|
raw=$(/usr/local/bin/xray tls ping "$site" 2>&1)
|
||||||
|
# 区分「当前 xray 没有 tls ping 子命令」和「这个域名校验不通过」:
|
||||||
|
# 前者不该阻断部署,后者必须判失败。有 "TLS ping" 头即说明子命令存在。
|
||||||
|
if ! echo "$raw" | grep -q "TLS ping"; then
|
||||||
|
warn " ${site}: 当前 xray 不支持 tls ping,跳过技术校验"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
out=$(echo "$raw" | sed -n '/Pinging with SNI/,$p')
|
||||||
|
echo "$out" | grep -q "Handshake succeeded" || return 1
|
||||||
|
echo "$out" | grep -q "TLS Version:.*TLS 1\.3" || return 1
|
||||||
|
|
||||||
|
len=$(echo "$out" | grep -oE "Certificate chain's total length:[[:space:]]*[0-9]+" \
|
||||||
|
| grep -oE '[0-9]+$' | head -1)
|
||||||
|
[ -n "$len" ] || return 1
|
||||||
|
# xtls/reality 对 target 握手报文有 8192 字节硬编码上限,超出直接握手失败
|
||||||
|
# (XTLS/Xray-core#6356:www.microsoft.com 的证书记录 8273 字节即触发)
|
||||||
|
[ "$len" -lt 8192 ] || return 1
|
||||||
|
|
||||||
|
REALITY_DEST_CERT_LEN="$len"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
# ===== 3. 选择 Reality 伪装目标 =====
|
# ===== 3. 选择 Reality 伪装目标 =====
|
||||||
select_reality_dest() {
|
select_reality_dest() {
|
||||||
if [ "$MODE" != "reality" ]; then
|
if [ "$MODE" != "reality" ]; then
|
||||||
@@ -242,7 +275,27 @@ select_reality_dest() {
|
|||||||
|
|
||||||
step "4/8 选择 Reality 伪装目标"
|
step "4/8 选择 Reality 伪装目标"
|
||||||
|
|
||||||
local candidates=("www.microsoft.com" "dl.google.com" "www.apple.com" "www.amazon.com")
|
# 候选伪装站必须同时满足两类条件。
|
||||||
|
#
|
||||||
|
# 【技术条件】TLS 1.3 + 证书链总长 < 8192 字节。由 check_reality_dest 运行时实测。
|
||||||
|
#
|
||||||
|
# 【客户端路由条件】SNI 必须会被客户端判成「直连」——这条不直观,但踩过坑。
|
||||||
|
# TUN 模式下,客户端有时会把「连接本代理服务器」这件事本身也抓进代理
|
||||||
|
# (v2rayN 的 sing-box+xray 双核心架构靠进程嗅探防回环,Windows 上有竞态,
|
||||||
|
# 实测约 2843:1584 的失败率)。这种回环连接的去向完全由 SNI 决定:
|
||||||
|
#
|
||||||
|
# SNI 被判直连 → 连接真的到达本服务器 → REALITY 握手成功 → 用户无感
|
||||||
|
# SNI 被判走代理 → 进隧道 → 服务器替客户端连了真正的伪装站
|
||||||
|
# → 客户端收到真证书 → 刷屏 REALITY: received real certificate
|
||||||
|
#
|
||||||
|
# 实测(v2rayN 默认规则模板,geosite:google → proxy 排在 geosite:cn → direct 之前):
|
||||||
|
# www.apple.com / *.apple.com 命中 geosite:cn 安全
|
||||||
|
# dl.google.com 命中 geosite:google 不安全(本仓库踩过)
|
||||||
|
# www.microsoft.com 两者都不命中 → final:proxy 不安全
|
||||||
|
# www.amazon.com 两者都不命中 → final:proxy 不安全
|
||||||
|
#
|
||||||
|
# 故候选只保留 Apple 系域名。更换前请先确认新域名命中客户端的直连规则。
|
||||||
|
local candidates=("www.apple.com" "swdist.apple.com" "updates.cdn-apple.com" "itunes.apple.com")
|
||||||
REALITY_DEST="${REALITY_DEST:-}"
|
REALITY_DEST="${REALITY_DEST:-}"
|
||||||
REALITY_SNI="${REALITY_SNI:-}"
|
REALITY_SNI="${REALITY_SNI:-}"
|
||||||
|
|
||||||
@@ -259,6 +312,10 @@ select_reality_dest() {
|
|||||||
warn "注意:更换会改变 SNI,届时所有客户端链接都必须同步更新"
|
warn "注意:更换会改变 SNI,届时所有客户端链接都必须同步更新"
|
||||||
else
|
else
|
||||||
log "伪装目标连通性正常 (${ms}ms)"
|
log "伪装目标连通性正常 (${ms}ms)"
|
||||||
|
if ! check_reality_dest "$REALITY_DEST"; then
|
||||||
|
warn "伪装目标 ${REALITY_DEST} 未通过 REALITY 技术校验"
|
||||||
|
warn "(要求 TLS 1.3 且证书链 < 8192 字节),客户端可能握手失败"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
@@ -267,29 +324,35 @@ select_reality_dest() {
|
|||||||
warn "--redetect:将重新挑选伪装目标,原目标为 ${REALITY_DEST}"
|
warn "--redetect:将重新挑选伪装目标,原目标为 ${REALITY_DEST}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local best_dest=""
|
# 按列表顺序优先,只有前面的不可用才往后顺延——不按延迟排序。
|
||||||
local best_ms=9999
|
# 候选现在都是 Apple 系主机,彼此延迟差在噪声级(实测 1~2ms),
|
||||||
|
# 按延迟挑会让每台机器随机选出不同 SNI,徒增客户端管理成本;
|
||||||
|
# 而 SNI 在所有机器上保持一致,运维和排查都省事得多。
|
||||||
|
local best_dest="" best_ms=""
|
||||||
for site in "${candidates[@]}"; do
|
for site in "${candidates[@]}"; do
|
||||||
local ms
|
local ms
|
||||||
# curl 失败时 %{time_connect} 会输出 0.000000,必须要求 ms > 0,
|
# curl 失败时 %{time_connect} 会输出 0.000000,必须要求 ms > 0,
|
||||||
# 否则连不通的站点会被当成「延迟最低」选中
|
# 否则连不通的站点会被当成可用
|
||||||
ms=$(curl -so /dev/null -w '%{time_connect}' --max-time 3 "https://${site}" 2>/dev/null \
|
ms=$(curl -so /dev/null -w '%{time_connect}' --max-time 3 "https://${site}" 2>/dev/null \
|
||||||
| awk '{printf "%d", $1*1000}') || true
|
| awk '{printf "%d", $1*1000}') || true
|
||||||
if [ -z "$ms" ] || ! [[ "$ms" =~ ^[0-9]+$ ]] || [ "$ms" -le 0 ]; then
|
if [ -z "$ms" ] || ! [[ "$ms" =~ ^[0-9]+$ ]] || [ "$ms" -le 0 ]; then
|
||||||
warn " ${site} 不可达,跳过"
|
warn " ${site} 不可达,跳过"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
log " ${site} → ${ms}ms"
|
if ! check_reality_dest "$site"; then
|
||||||
if [ "$ms" -lt "$best_ms" ]; then
|
warn " ${site} (${ms}ms) 未通过技术校验,跳过"
|
||||||
best_ms=$ms
|
continue
|
||||||
best_dest=$site
|
|
||||||
fi
|
fi
|
||||||
|
log " ${site} → ${ms}ms,证书链 ${REALITY_DEST_CERT_LEN:-?} 字节 ✔"
|
||||||
|
best_dest="$site"
|
||||||
|
best_ms="$ms"
|
||||||
|
break
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "$best_dest" ]; then
|
if [ -z "$best_dest" ]; then
|
||||||
error "所有候选伪装目标都无法连接,请检查服务器网络 / DNS"
|
error "没有候选伪装目标能同时满足「可达」与「REALITY 技术要求」"
|
||||||
error "候选列表: ${candidates[*]}"
|
error "候选列表: ${candidates[*]}"
|
||||||
|
error "可在 .env 中手动指定 REALITY_DEST / REALITY_SNI 后重试"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user