# VPS 开荒配置脚本集 新购 VPS 的一键初始化脚本集合。每个脚本都是**单文件、自包含、无外部依赖**的 bash, `wget` 下来直接 `sudo bash` 就跑;参数全部支持环境变量传入(支持 `wget|bash` 管道), 缺失的凭据自动生成并落盘保存,重跑幂等、不会失效已分发的客户端配置。 | 脚本 | 用途 | 适用场景 | |---|---|---| | [setup_warp_zerotrust.sh](#setup_warp_zerotrustsh) | 给 IPv6-only VPS 加 Cloudflare WARP IPv4 出口(纯 WireGuard,无官方客户端) | 没有 IPv4 的廉价 VPS 需要访问 IPv4 网络 | | [setup_caddy_xray_hysteria.sh](#setup_caddy_xray_hysteriash) | 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 策略管控 | ## 快速开始 ```bash # 免费版: 交互提示出现时直接回车 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]( > https://developers.cloudflare.com/cloudflare-one/tutorials/deploy-client-headless-linux/))。 ### 第 0 步:开通 Zero Trust(已有组织可跳过) 1. 登录 [Cloudflare 仪表盘](https://dash.cloudflare.com/),左侧进入 **Zero Trust** 2. 首次进入会引导创建组织、设置 **team name**(团队名,全局唯一) 3. 选 **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) 1. 路径: **Zero Trust > Access controls > Service credentials > Service Tokens** 2. 点 **Create Service Token** 3. 起个名字(比如 `vps-warp`),选择 **Service Token Duration**(有效期) - 到期只是不能再注册**新**设备,已注册设备不受影响;建议选一年或更长 4. 点 **Generate token**,得到: - **Client ID**,形如 `88bf3b6d86161464f6509f7219099e57.access` - **Client Secret**,64 位十六进制,**只显示这一次**,务必当场复制 ### 第 3 步:允许用 Service Token 注册设备(关键,漏了会 403) 1. 路径: **Zero Trust > Team & Resources > Devices**,切到 **Management** 标签页 2. 找到 **Device enrollment permissions**,点 **Manage** 3. 在 **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`) - 保存策略 4. 回到 **Device enrollment permissions**,把刚创建的策略**添加进去**,点 **Save** ### 第 4 步:在 VPS 上运行 交互式(推荐): ```bash 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 (输入不显示): ******** ``` 或非交互(环境变量齐全时不会有任何提问): ```bash 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 页面复制,避免手打) 1. 策略 **Action 选成了 `Allow`**(最常见)——必须是 `Service Auth`, 特征是 HTTP 302 且 Location 指向 `/cdn-cgi/access/login/...` 2. 策略建好后没加进 **Device enrollment permissions** 列表(要点 Save) 3. 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](https://github.com/ViRb3/wgcf) · [Aether](https://github.com/CluvexStudio/Aether) · [fscarmen/warp](https://gitlab.com/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(端口跳跃) | ## 快速开始 ```bash 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,必配) 1. **DNS → Records**:添加 A 记录(IPv4)或 AAAA 记录(IPv6-only VPS), 名称 = 你的子域名,**Proxy status 保持灰色云(DNS only)**——不要点亮。 2. 无其他设置;REALITY 流量由客户端直连 443,Caddy 证书自己向 Let's Encrypt 签。 ### B. CDN 域名 `CDN_DOMAIN`(可选,VPS IP 被封后的备用通道) 1. **DNS → Records**:同样指向 VPS IP,但**点亮橙色云(Proxied)**。 2. **SSL/TLS → Overview**(概述):加密模式选 **Full (strict)**。 回源证书由 Caddy 用 Let's Encrypt 签(CF 透传 HTTP-01 challenge),满足 strict 校验。 *不要用 Flexible*(回源走 80 明文且与 hy2 的 HTTP-01 端口语义冲突)。 3. **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。 4. **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),与本架构无关,无需激活。 5. **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=`(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 权限)