Co-Authored-By: Claude <noreply@anthropic.com>
19 KiB
VPS 开荒配置脚本集
新购 VPS 的一键初始化脚本集合。每个脚本都是单文件、自包含、无外部依赖的 bash,
wget 下来直接 sudo bash 就跑;参数全部支持环境变量传入(支持 wget|bash 管道),
缺失的凭据自动生成并落盘保存,重跑幂等、不会失效已分发的客户端配置。
| 脚本 | 用途 | 适用场景 |
|---|---|---|
| setup_warp_zerotrust.sh | 给 IPv6-only VPS 加 Cloudflare WARP IPv4 出口(纯 WireGuard,无官方客户端) | 没有 IPv4 的廉价 VPS 需要访问 IPv4 网络 |
| setup_caddy_xray_hysteria.sh | Caddy + Xray(REALITY/WS/XHTTP) + Hysteria2 + nftables 端口跳跃 | 自建代理全家桶:隐蔽直连 + CDN 备用 + UDP 加速 |
共同约定:Debian/Ubuntu;中文注释;ACTION=uninstall 卸载;凭据仅存本机 600 权限文件。
setup_warp_zerotrust.sh
给 IPv6-only 的 VPS 加一个 Cloudflare WARP 的 IPv4 出口 —— 纯 WireGuard 实现, 不装官方 WARP 客户端(不引入任何桌面组件),全部软件只走 apt 官方签名源。
两种模式:
| 模式 | 说明 | 设备管理 |
|---|---|---|
| 免费版(默认) | 匿名注册 consumer WARP,拿到 IPv4 出口 | 无 |
| Zero Trust 团队版 | 注册为组织的团队设备,出口走 Cloudflare 骨干网 | 设备出现在 Zero Trust 仪表盘,受 Gateway L3 策略管控 |
快速开始
# 免费版: 交互提示出现时直接回车
wget -qO- https://git.henhaoji.site/eli/vpsetup/raw/branch/main/setup_warp_zerotrust.sh | bash
# 团队版: 填团队名 + Service Token 凭据即可(见下方配置步骤)
可选环境变量: ALLOWED_IPS(默认 0.0.0.0/0)、MTU(默认 1280)、
DNS64_SERVERS(替换安装期临时 DNS64)、ACTION=delete(注销设备并卸载)。
Zero Trust 仪表盘配置(2026 年最新路径)
⚠️ 网上老教程写的
Settings > WARP Client > Device enrollment permissions是旧版导航,现在找不到很正常。以下是 2026 年现行界面路径 (依据官方文档 Deploy the Cloudflare One Client on headless Linux machines)。
第 0 步:开通 Zero Trust(已有组织可跳过)
- 登录 Cloudflare 仪表盘,左侧进入 Zero Trust
- 首次进入会引导创建组织、设置 team name(团队名,全局唯一)
- 选 Free 计划。注意: 免费计划也要求绑定支付方式(信用卡/PayPal) 做验证,不会收费;Free 计划上限 50 台设备
第 1 步:确认团队名(team name)
- 路径: Zero Trust > Settings,页面上的 Team name 即你的团队名,
下面的 Team domain 是由它生成的注册域名(
<团队名>.cloudflareaccess.com) - 脚本的
CF_TEAM填 name 或完整 domain 都可以,内部自动归一化
第 2 步:创建 Service Token(拿 Client ID / Secret)
- 路径: Zero Trust > Access controls > Service credentials > Service Tokens
- 点 Create Service Token
- 起个名字(比如
vps-warp),选择 Service Token Duration(有效期)- 到期只是不能再注册新设备,已注册设备不受影响;建议选一年或更长
- 点 Generate token,得到:
- Client ID,形如
88bf3b6d86161464f6509f7219099e57.access - Client Secret,64 位十六进制,只显示这一次,务必当场复制
- Client ID,形如
第 3 步:允许用 Service Token 注册设备(关键,漏了会 403)
- 路径: Zero Trust > Team & Resources > Devices,切到 Management 标签页
- 找到 Device enrollment permissions,点 Manage
- 在 Policies 标签页点 Create new policy(会新开一个标签页):
- Action 必须选
Service Auth—— ⚠️ 选成Allow是常见错误: Allow 是交互式身份登录策略,service token 永远拿不到注册 JWT, 脚本会报no enrollment JWT returned (HTTP 302, Location: .../cdn-cgi/access/login/...) - 规则: Include → Selector 选
Service Token→ Value 选你刚建的 token 名 (想省事也可以选Any Access Service Token) - 保存策略
- Action 必须选
- 回到 Device enrollment permissions,把刚创建的策略添加进去,点 Save
第 4 步:在 VPS 上运行
交互式(推荐):
wget -qO- https://git.henhaoji.site/eli/vpsetup/raw/branch/main/setup_warp_zerotrust.sh | bash
# Zero Trust 团队名(回车跳过): myteam
# Service Token Client ID (形如 xxxx.access): 88bf...access
# Service Token Client Secret (输入不显示): ********
或非交互(环境变量齐全时不会有任何提问):
wget -qO /tmp/zt.sh https://git.henhaoji.site/eli/vpsetup/raw/branch/main/setup_warp_zerotrust.sh
CF_TEAM=myteam \
CF_ACCESS_CLIENT_ID=88bf...access \
CF_ACCESS_CLIENT_SECRET=bdd3... \
bash /tmp/zt.sh
凭据不全时自动回退免费版(会有明显提示)。
验证
- 脚本结尾:
IPv4 Exit显示 Cloudflare 的出口 IP,IPv6 Exit仍是 VPS 原生 IPv6,WARP status: warp=on - 仪表盘: Zero Trust > Team & Resources > Devices 列表里出现一台新设备,
身份为
non_identity@<团队名>.cloudflareaccess.com
常见问题
注册报 403 / 429? 403 = 你的 VPS IP 段被 Cloudflare 标记(机房 IP 常见),换 IP 或稍后再试; 429 = 注册限频,等几分钟。脚本会打印服务器原始返回,按 error code 判断。
报 no enrollment JWT returned?
脚本会打印 HTTP 状态码和重定向目标,对照排查:
0. HTTP 404 = 团队域名不存在 → 团队名拼写错误
(建议从 Zero Trust > Settings 页面复制,避免手打)
- 策略 Action 选成了
Allow(最常见)——必须是Service Auth, 特征是 HTTP 302 且 Location 指向/cdn-cgi/access/login/... - 策略建好后没加进 Device enrollment permissions 列表(要点 Save)
- Client ID/Secret 复制不全,或 token 已过期(重建一个即可)
重复运行会重复占设备坑吗?
不会。凭据存在 /etc/wireguard/warp-account.json,重跑时对同一设备 PATCH
换新密钥;仅当模式切换(免费↔团队)时才重新注册。卸载并释放席位:
ACTION=delete bash setup_warp_zerotrust.sh
纯 WireGuard 接入和官方客户端有什么区别?
- 仪表盘的 split tunnel、设备配置文件不会下发——路由以本机
wg0.conf的AllowedIPs为准(默认只接管 IPv4,不碰 IPv6) - Gateway 的 L3(网络层)策略正常生效;L7/HTTP 检查类策略需要官方客户端
- 设备为非身份(non-identity)注册,基于用户身份的策略不适用
内核没有 WireGuard 模块(LXC/老内核)? 脚本自动探测并回退到用户态 wireguard-go(apt 官方源,约 1MB),速度略慢 但功能一致,开机自启同样生效;LXC 容器需先在面板开启 TUN/TAP。
安全说明
- 只通过 apt 官方签名源装包,不添加第三方源,不下载/执行任何远程二进制
- 外联仅 Cloudflare 官方域名;连通性检测用官方
cdn-cgi/trace - 私钥/凭据仅存本机
/etc/wireguard/(600 权限),只有公钥提交给注册接口 - 安装期临时使用公共 DNS64(
DNS64_SERVERS可覆盖),结束后自动还原系统 DNS
参考实现: wgcf · Aether · fscarmen/warp
setup_caddy_xray_hysteria.sh
在 Debian/Ubuntu VPS 上一键部署 Caddy + Xray + Hysteria2 + nftables 端口跳跃:
| 组件 | 监听 | 说明 |
|---|---|---|
| Xray | 443/TCP | VLESS+REALITY(xtls-rprx-vision),非 REALITY 流量回落到 Caddy |
| Xray | 127.0.0.1:54442 | VLESS+WS(路径 /scilad,经 Caddy 反代) |
| Xray | 127.0.0.1:8080 | VLESS+XHTTP(随机路径,mode auto,经 Caddy 反代) |
| Caddy | 127.0.0.1:8003 | 收 REALITY 回落(PROXY protocol),伪装反代 + WS/XHTTP 入口 |
| Hysteria2 | 8443/UDP | 默认 HTTP-01 签 DOMAIN 证书(challenge 仅监听 127.0.0.1:9180,由 Caddy 80 端口反代验证);可选 DNS-01 签 *.主域 通配符 |
| nftables | UDP 20000-30000 | redirect 到 8443(端口跳跃) |
快速开始
wget -qO setup_caddy_xray_hysteria.sh \
https://git.henhaoji.site/eli/vpsetup/raw/branch/main/setup_caddy_xray_hysteria.sh
sudo bash setup_caddy_xray_hysteria.sh # 交互式:只需回答主域名
sudo ACTION=upgrade bash setup_caddy_xray_hysteria.sh # 升级全部组件到最新版(沿用已存参数,不交互)
sudo ACTION=uninstall bash setup_caddy_xray_hysteria.sh # 卸载(PURGE=1 连包一起删)
三个组件的安装方式本身就是幂等升级(Caddy 走 apt 仓库、Xray/hy2 官方脚本重跑即拉 最新版),所以重复运行安装也能升级;
ACTION=upgrade的区别是:未安装过会报错 而不是误装,且完全不交互。
必填:DOMAIN(灰云子域名,Caddy 站点、REALITY serverName、hy2 证书都用它)。
Cloudflare 回源设置指引(2026 年现行界面)
部署前后的域名与回源配置按此操作。核心原则:REALITY 域名必须灰云直连 (REALITY 原理上不能过 CDN),CDN 域名橙云代理(只承载 WS/XHTTP)。
A. 直连域名 DOMAIN(Caddy 站点 + REALITY + hy2,必配)
- DNS → Records:添加 A 记录(IPv4)或 AAAA 记录(IPv6-only VPS), 名称 = 你的子域名,Proxy status 保持灰色云(DNS only)——不要点亮。
- 无其他设置;REALITY 流量由客户端直连 443,Caddy 证书自己向 Let's Encrypt 签。
B. CDN 域名 CDN_DOMAIN(可选,VPS IP 被封后的备用通道)
- DNS → Records:同样指向 VPS IP,但点亮橙色云(Proxied)。
- SSL/TLS → Overview(概述):加密模式选 Full (strict)。 回源证书由 Caddy 用 Let's Encrypt 签(CF 透传 HTTP-01 challenge),满足 strict 校验。 不要用 Flexible(回源走 80 明文且与 hy2 的 HTTP-01 端口语义冲突)。
- Origin Rules:无需配置(全部 Preserve 即可)。CF 回源时 SNI/Host 默认
就是
CDN_DOMAIN:请求先到 Xray 443,REALITY serverNames 不匹配即原样回落 Caddy,Caddy 按 SNI 匹配到 CDN 站点块(WS/XHTTP/伪装反代),全链路不依赖 任何 Host/SNI 改写。注意 Origin Rules 的 Host Header / SNI / DNS record 改写 是 Enterprise 专属(免费版灰色不可选,仅剩 Destination Port 可用)—— 对本架构毫无影响,无需为此升级 plan。 - SSL/TLS → Edge Certificates(边缘证书):
- Encrypted ClientHello (ECH):Free 版默认已开启且界面不显示开关
(官方:"ECH is enabled by default on Free zones"),无需操作。可用
dig +short HTTPS 你的CDN域名验证返回含ech=(本机 systemd-resolved stub 查不出 type65 时换dig @1.1.1.1或 DoH JSON 接口)。 开之后审查者只能看到"你连了 Cloudflare"(外层 SNI 统一为 cloudflare-ech.com),看不到CDN_DOMAIN;客户端 Xray ≥25.7.26 内核, 在节点上启用 ECH(或链接加ech参数)。 - Always Use HTTPS:建议打开。不会与源站 Caddy 的 80→443 跳转形成循环
("too many redirects" 只在源站把 HTTPS 跳回 HTTP 时发生;Caddy 是
http→https 单向跳,方向一致)。打开后访客到边缘的 80 请求由 CF 直接 301,
不再回源 80;ACME challenge 走
/.well-known/路径不受影响。 - Minimum TLS Version:改为 1.2(面板默认 1.0 是兼容上古客户端; 代理客户端全是 TLS 1.2+,收紧无影响)。
- HTTP/3 (QUIC):开关在 Speed → Settings → Protocol Optimization (2026 面板位置,不在 Network 也不在边缘证书页),默认开启即可; 访客↔CF 边缘走 H3,回源仍是 TCP,与本架构无关。
- Advanced Certificate Manager (ACM):付费插件(自定义边缘证书 CA/有效期、 Total TLS、边缘 cipher suites),与本架构无关,无需激活。
- Encrypted ClientHello (ECH):Free 版默认已开启且界面不显示开关
(官方:"ECH is enabled by default on Free zones"),无需操作。可用
- Network → WebSockets:保持开启(默认开),WS 回源需要。 XHTTP 基于普通 HTTP 流式请求,无需额外开关。
C. 常见误区
- 两个域名不能是同一条 DNS 记录切换灰/橙:REALITY 要灰、CDN 要橙,必须两个独立子域名。
- 橙云域名不要再在客户端里配 REALITY——CF 终止 TLS 后源站收到的是普通 HTTPS, REALITY 客户端连不上(会回落成伪装网站,这就是它"看起来正常但代理不通"的原因)。
- VPS 防火墙/安全组只需放行:
443/TCP(Xray)、443/UDP(若想让 CF 边缘 H3 直连,可不开)、8443/UDP(hy2)+20000-30000/UDP(端口跳跃)、80/TCP(HTTP-01 证书验证与跳转)。8003、54442、8080、9180全部只绑 127.0.0.1,无需放行。
hy2 证书两种模式(HY2_CERT_MODE):
http(默认):hy2 内置 ACME(certmagic)走 HTTP-01,challenge 只监听127.0.0.1:9180,由 Caddy 的 80 端口把/.well-known/acme-challenge/反代过去 完成验证。签的是 DOMAIN 非通配证书,自动续期、热生效、无需重启, 不需要任何 DNS API Token,也不新开公网端口(TLS-ALPN 必须独占 443/TCP, 与 Xray 冲突,故不可用)。dns:Cloudflare DNS-01 签*.主域通配符证书,需CF_API_TOKEN(Zone.DNS 编辑权限)。域名不想指向本机 80 端口或想要通配符时用。
可选环境变量(全部留空则自动生成并保存到 /etc/caddy-xray-hy2/setup.env,
重跑自动读取作默认值,不会重新生成导致已分发客户端失效):
| 变量 | 默认 | 用途 |
|---|---|---|
EMAIL |
admin@主域 |
ACME 注册邮箱 |
CDN_DOMAIN |
空 | 橙云域名,独立站点块,仅承载 WS/XHTTP 回源(REALITY 不能过 CDN,二者必须分开) |
HY2_CERT_MODE |
http |
hy2 证书模式:http(默认,经 Caddy 80 验证)或 dns(CF DNS-01 通配符) |
CF_API_TOKEN |
空 | 仅 HY2_CERT_MODE=dns 时必填 |
HY2_ACME_PORT |
9180 |
hy2 HTTP-01 challenge 的本机监听端口 |
XRAY_UUID / XRAY_WS_UUID / XRAY_XHTTP_UUID |
随机 | 三个 inbound 的 UUID |
XRAY_PRIVATE_KEY |
xray x25519 生成 |
REALITY 私钥(公钥自动推导) |
XRAY_SHORT_ID |
8 位 hex | REALITY shortId |
XRAY_VLESS_ENC |
关 | =1 启用 VLESS 后量子加密(见下方「可选增强」) |
XHTTP_PATH / XHTTP_PORT |
/8位hex / 8080 |
XHTTP 路径与本地端口 |
XHTTP_PADDING |
开 | XHTTP extra padding 混淆(随机 header/key),服务端 extra 块与分享链接 extra= 参数(分享标准 4.3.19)带同一份键名。=0 关闭。注意:忽略 extra 的旧客户端会连不上(服务端 400),升级开启后旧链接作废、需重发 |
HY2_PASSWORD |
32 位 hex | Hysteria2 密码 |
HY2_MASQUERADE_URL |
https://engineersblog.net |
hy2 伪装反代目标 |
SKIP_CADDY / SKIP_XRAY / SKIP_HYSTERIA / SKIP_NFTABLES |
— | =1 跳过对应组件 |
DIST_UPGRADE |
— | =1 安装前 apt-get dist-upgrade |
DRY_RUN |
— | =1 干跑:所有配置渲染到 ./dry-run-output/,不做系统变更 |
安装结束自动打印 REALITY / WS / XHTTP /(可选 CDN)/ Hysteria2 的分享链接。
可选增强(默认关闭,按需开启)
VLESS 后量子加密(XRAY_VLESS_ENC=1):防"现在录制流量、未来量子计算机解密"
(harvest-now-decrypt-later)。用 xray vlessenc 生成 ML-KEM-768 后量子密钥对,
写入三个 VLESS inbound 的 decryption,分享链接自动带上客户端 encryption= 参数。
对速度/延迟几乎无感(握手包大约 1-2KB),但要求所有客户端内核 Xray ≥25.8,
不支持的客户端会连不上。密钥持久化在 setup.env,重跑不换。防封锁/限流无帮助,
属保密性强化,客户端生态统一新版时才建议开。
TLS ECH(仅 CDN_DOMAIN 场景,纯客户端配置):走 CF CDN 的 XHTTP/WS 链路上,不开 ECH 时
审查者能看到明文 SNI=CDN_DOMAIN(你的私有域名,被标记就整域报废)。开启后外层
SNI 统一为 CF 公共 ECH 名(cloudflare-ech.com),真实域名加密——审查者只知道你连了
Cloudflare。ECH 在 CF 边缘终止,VPS 无需任何改动(Free 版默认已开,见上方 B 节;
dig +short HTTPS CDN域名 应返回含 ech=)。客户端 Xray ≥25.7.26:分享链接加
&ech=<base64 ECHConfigList>(dig 返回里 ech= 后那串,URL 编码),或 JSON 出站
tlsSettings 里配 echConfigList(静态 base64,或 "域名+https://1.1.1.1/dns-query"
走内置 DoH 动态查询)与 echForceQuery(full/half/none,26.3.27 起默认 full)。
静态配置下 ECH 协商失败会直接报错而非回落明文 SNI,能连通即生效。
CF 轮换 ECH 密钥很勤(静态快照实测很快失效),所以脚本默认在两条 CDN 分享链接
内嵌动态查询形式 ech=CDN域名+udp://8.8.8.8——客户端 Xray 拨号时自查最新
配置并按 TTL 缓存刷新,轮换无感,无需手动更新。查询协议按 scheme 选择:
udp://9.9.9.9(默认):明文 UDP53,Quad9——8.8.8.8 偶发被断,9.9.9.9 实测 不被屏蔽、延迟略高;备选 149.112.112.112(Quad9 备用),或国内 223.5.5.5 / 119.29.29.29(最快最稳,查询记录国内可见——节点域名的 A 查询默认本来也走 国内 DNS,不多暴露什么)。报文理论上可被窃听/投毒,但配合 full 策略,伪造 记录只会导致断连、不会静默降级泄露 SNI,可接受。域名+https://8.8.8.8/dns-query:内置 DoH(h2 + chrome 指纹,最隐蔽),但 8.8.8.8:443 在墙内实测不稳——passwall 的"本机代理"会把路由器自身流量(含 Xray 的 DoH)劫进代理通道,代理一抖查询就失败。DoH 端点必须指到/dns-query(RFC8484 wireformat),/resolve是 JSON 调试接口、Xray 不认。tcp://不支持。 查询失败会硬失败(无明文 SNI 回落),不合适的网络用ECH_CONFIG=off或ECH_CONFIG=<静态 base64>快照(零 DNS 依赖但会过期)。 图形客户端(passwall 等):「ECH 配置」框填CDN域名+udp://9.9.9.9(动态) 或静态 base64;「ECH 查询策略」动态形式选 full(最严,防降级)或 half (查询失败可回落连通),静态 base64 选 none。 直连的 REALITY 域名不需要(SNI 本来就是公开伪装域名);直连 Caddy 的 TLS 链路 用不上(Caddy 的 ECH 2026 年才落地且需自行发布 DNS HTTPS 记录,CDN 链路才是零改动方案)。
hy2 场景化武器(不集成,需要时手动改 /etc/hysteria/config.yaml):
UDP 被选择性限速时试 obfs: salamander(不行再试实验性 gecko);UDP 整体被封的
网络用 mimic(XDP 伪装 TCP,需内核模块 + 客户端同开,与端口跳跃互斥)。
改完 systemctl restart hysteria-server。
安全说明
- 与 setup_warp_zerotrust.sh 不同,本脚本按官方文档引入 cloudsmith apt 源 (Caddy 官方仓库),并执行 Xray / Hysteria2 官方安装脚本;除此之外不下载 任何二进制或远程代码
- 凭据仅存本机
/etc/caddy-xray-hy2/setup.env(600 权限)