Files
vpsetup/docs/superpowers/plans/2026-08-23-caddy-xray-hysteria.md

189 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# setup_caddy_xray_hysteria.sh 实施计划(精简版)
> 设计文档:`docs/superpowers/specs/2026-08-23-caddy-xray-hysteria-design.md`
> 模板原文以仓库根部的 `Caddyfile` / `config.json` / `config.yaml` / `hysteria.nft` /
> `nftables.conf` 为准,实现时直接读取转成 heredoc,本计划不再逐字复制。
**Goal:** 单一自包含 bash 脚本,一键部署 Caddy + XrayREALITY/WS/XHTTP+ Hysteria2 +
nftables 端口跳跃,含交互参数收集、凭据自动生成/持久化、配置校验、自检、分享链接输出与卸载。
**Architecture:** 分阶段函数 `preflight → collect_params → system_prepare → install_caddy →
install_xray → generate_xray_secrets → install_hysteria → render_all_configs → setup_nftables →
validate_configs → save_env → enable_services → self_check → print_summary`;模板 quoted heredoc +
`__VAR__` 占位符,bash 参数展开替换(非 sed);`DRY_RUN=1` 渲染全部文件到 `DRY_RUN_DIR`
跳过一切系统变更,是 dev 机可测试的核心机制。
## Global Constraints
- 脚本注释用**中文**;禁止 `sudo`(直接要求 root);`apt-get` + `DEBIAN_FRONTEND=noninteractive`
- 占位符严格 `__VARNAME__` 与变量同名;替换用 bash 参数展开;随机值限 hex 字符集
- 每任务完成必须过:`bash -n``shellcheck``tests/run_tests.sh` → commit
- 供应链:允许 cloudsmith apt 源、Xray/hy2 官方安装脚本;头部注释说明与
setup_warp_zerotrust.sh 的约束差异
- `/etc/nftables.conf` 只**幂等追加** include 行(先 grep 再 append);其余四个配置整体覆盖
- xray 模板第 15 行 `""uuid-uuid` 多引号笔误在 heredoc 中修正;xray heredoc 内**不写
`//` 注释**,产出必须是合法 JSON`python3 -m json.tool` 可验证)
- Caddyfile 伪装反代 `@notpaths` 排除列表必须包含 XHTTP 路径
## 文件结构
- **Create** `setup_caddy_xray_hysteria.sh` — 主脚本(唯一交付物)
- **Create** `tests/run_tests.sh` — DRY_RUN 集成测试
- **Modify** `README.md` / `CLAUDE.md`
- **Move** 5 个手写模板原件 → `docs/templates-original/` 存档
## 全局接口约定(各任务共享,不得改名)
```bash
info / warn / die
gen_hex_bytes N # → 2N 位小写 hex
prompt_var VAR_NAME "提示语" # 仅交互模式;已有值作默认值
render # stdin 模板 → stdout,按 RENDER_VARS 替换 __X__
write_file PATH MODE CONTENT # DRY_RUN 时写到 $DRY_RUN_DIR/<basename>
RENDER_VARS="DOMAIN BASE_DOMAIN EMAIL CF_API_TOKEN CDN_DOMAIN
XRAY_UUID XRAY_WS_UUID XRAY_XHTTP_UUID XRAY_PRIVATE_KEY XRAY_PUBLIC_KEY XRAY_SHORT_ID
XHTTP_PATH XHTTP_PORT XPADDING_HEADER XPADDING_KEY
HY2_PASSWORD HY2_MASQUERADE_URL"
# 环境变量:ACTION(install/uninstall) DRY_RUN DRY_RUN_DIR(默认 ./dry-run-output)
# SKIP_CADDY SKIP_XRAY SKIP_HYSTERIA SKIP_NFTABLES DIST_UPGRADE PURGE KEEP_ENV
# ENV_FILE=/etc/caddy-xray-hy2/setup.env NFTABLES_CONF=/etc/nftables.conf
# INTERACTIVE BASE_DOMAIN XRAY_PUBLIC_KEY(全局,跨函数共享)
# 阶段函数(Task 1 为 no-op 桩,后续逐个替换):
preflight collect_params system_prepare install_caddy install_xray
generate_xray_secrets install_hysteria render_all_configs setup_nftables
validate_configs save_env enable_services self_check print_summary uninstall main
```
## Task 1:脚本骨架与工具函数
**Files:** Create `setup_caddy_xray_hysteria.sh`
- 头部中文注释:用途、架构(Caddy 127.0.0.1:8003 PROXY protocol 收 REALITY 回落;
Xray 443 REALITY + 54442 WS + 8080 XHTTPhy2 8443/UDP + CF DNS-01 泛域名证书;
nftables UDP 20000-30000→8443)、用法/环境变量、供应链说明
- 上述全部工具函数、全局变量、阶段函数桩、main 分发(ACTION=uninstall → uninstall
- `preflight`root 检查(DRY_RUN 跳过)、apt 系发行版检查
- **测试**`bash -n``shellcheck``DRY_RUN=1` 冒烟(桩不报错、无 tty 时跳过交互)
- **Commit**: `feat: add setup_caddy_xray_hysteria.sh skeleton`
## Task 2collect_params + system_prepare + save_env + 测试脚手架
**Files:** Modify 主脚本;Create `tests/run_tests.sh`
- `collect_params``[ -f "$ENV_FILE" ] && source` 作默认值;`prompt_var` 仅当变量为空且有
/dev/tty 时交互;`DOMAIN` 正则 `^([A-Za-z0-9-]+\.)+[A-Za-z]{2,}$`,无 tty 且无值 die
`BASE_DOMAIN="${DOMAIN#*.}"`;默认 `EMAIL="admin@$BASE_DOMAIN"`
UUID×3 用 `/proc/sys/kernel/random/uuid``XRAY_SHORT_ID=$(gen_hex_bytes 4)`
`XHTTP_PATH="/$(gen_hex_bytes 4)"``XHTTP_PORT=8080`
`XPADDING_HEADER="X-$(gen_hex_bytes 2)"``XPADDING_KEY="_$(gen_hex_bytes 2)"`
`HY2_PASSWORD=$(openssl rand -hex 16)``HY2_MASQUERADE_URL` 默认
`https://www.people.com``CDN_DOMAIN` 可选默认空(空则不渲染 CDN 站点块);
`CF_API_TOKEN` 在未设 SKIP_HYSTERIA 时必填
- `system_prepare``apt-get update -qq``DIST_UPGRADE=1``apt-get dist-upgrade -y`
- `save_env`umask 077`mkdir -p /etc/caddy-xray-hy2`printf 全部变量写 ENV_FILE mode 600
- `tests/run_tests.sh`:注入固定测试值(DOMAIN=test.example.com 等)→ DRY_RUN 跑 →
断言 `$DRY_RUN_DIR/setup.env` 存在且含 DOMAIN、BASE_DOMAIN=example.com
- **Commit**: `feat: parameter collection, env persistence, test scaffold`
## Task 3install_caddy + render_caddyfile
**Files:** Modify 主脚本 + tests
- `install_caddy`SKIP_CADDY/DRY_RUN 跳过):cloudsmith gpg key
`curl ... | gpg --batch --yes --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg`
`/etc/apt/sources.list.d/caddy-stable.list``apt-get update -qq && apt-get install -y caddy`
- `render_caddyfile`heredoc 内嵌仓库 `Caddyfile``xxx.yyy.zzz``__DOMAIN__`
email→`__EMAIL__`;新增 `@xhttppaths path __XHTTP_PATH__ __XHTTP_PATH__/*`
**`@notpaths` 必须同时排除 xhttp 路径**`reverse_proxy @xhttppaths 127.0.0.1:__XHTTP_PORT__`
`CDN_DOMAIN` 非空时追加第二站点块(仅 xhttp + /scilad + 伪装反代)
- **断言**:渲染含测试 domain/email、`@xhttppaths path /xh88ab``@notpaths` 行含
`/xh88ab``reverse_proxy @xhttppaths 127.0.0.1:8080`CDN_DOMAIN=cdn.example.com 时含两站点块
- **Commit**: `feat: caddy install + Caddyfile render`
## Task 4install_xray + generate_xray_secrets + render_xray_config
**Files:** Modify 主脚本 + tests
- `install_xray`SKIP_XRAY/DRY_RUN 跳过):官方脚本
`bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install`
- `generate_xray_secrets`UUID 空则 `xray uuid`(回退 /proc uuid)补齐;
`XRAY_PRIVATE_KEY` 空则 `xray x25519` 生成,否则 `xray x25519 -i $KEY` 推公钥;
解析私钥 `grep -i 'private'`、公钥 `grep -iE 'public|password'`,失败 die
DRY_RUN 回退 `XRAY_PUBLIC_KEY=DRYRUN_PUBLIC_KEY`
- `render_xray_config`heredoc 内嵌仓库 `config.json`(修正第 15 行多引号;不写 `//` 注释):
443 REALITYdest "8003"、xver 1、serverNames `__DOMAIN__`、privateKey/shortIds/uuid 替换);
54442 WS127.0.0.1/scilad);8080 XHTTP127.0.0.1path `__XHTTP_PATH__`mode auto
`extra` 块:xPaddingObfsMode/tokenish/queryInHeader/`__XPADDING_HEADER__`/`__XPADDING_KEY__`);
outbounds/dns/routing 保留模板原样(geoip:cn、私有网段、tg-out、域名阻断、bittorrent
- **断言**`python3 -m json.tool` 通过;含 3 个测试 UUID、privateKey、shortId `3f9a2b1c`
serverNames、`"network": "xhttp"``"port": 8080``"xPaddingObfsMode": true`
`"xPaddingHeader": "X-testpad"``"path": "/xh88ab"`
- **Commit**: `feat: xray install, keypair generation, config render`
## Task 5install_hysteria + render_hysteria_config
**Files:** Modify 主脚本 + tests
- `install_hysteria`SKIP_HYSTERIA/DRY_RUN 跳过):`bash <(curl -fsSL https://get.hy2.sh/)`
- `render_hysteria_config`heredoc 内嵌仓库 `config.yaml``listen: :8443`acme dns
cloudflaredomains `["*.__BASE_DOMAIN__"]`、email `__EMAIL__`
`cloudflare_api_token: __CF_API_TOKEN__``dir: /etc/hysteria/acme_certs`
auth password `__HY2_PASSWORD__`masquerade proxy url `__HY2_MASQUERADE_URL__`
rewriteHost true
- 非 DRY_RUN`chown -R hysteria:hysteria /etc/hysteria/`
- **断言**:渲染含 `:8443``*.example.com`、测试 token、密码、masquerade url
- **Commit**: `feat: hysteria2 install + config render`
## Task 6setup_nftables + validate_configs + enable_services
**Files:** Modify 主脚本 + tests
- `setup_nftables`SKIP_NFTABLES 跳过):写 `/etc/nftables/hysteria.nft`
(仓库 `hysteria.nft` 原样:`table inet hysteria_nat`udp dport 20000-30000 redirect
to :8443);`$NFTABLES_CONF` grep 无 include 行才追加(幂等);
非 DRY_RUN`systemctl enable --now nftables`
- `validate_configs`DRY_RUN 跳过):`caddy validate --config /etc/caddy/Caddyfile`
`xray run -test -config /usr/local/etc/xray/config.json`hy2 无离线校验,靠启动后
`systemctl is-active`
- `enable_services`DRY_RUN 跳过):按 SKIP_* `systemctl enable --now`/`restart`
caddy xray hysteria-server → `is-active` 检查,失败 die
- **断言**DRY_RUN 目录 `hysteria.nft``20000-30000``:8443`;渲染的 nftables.conf
含 include 行;include 追加逻辑跑两次不重复
- **Commit**: `feat: nftables port hopping, validation, service enablement`
## Task 7self_check + print_summary + uninstall
**Files:** Modify 主脚本 + tests
- `self_check`DRY_RUN 跳过,失败仅 warn):`curl -skI "https://$DOMAIN"`
`ss -lun | grep :8443``nft list table inet hysteria_nat`
- `print_summary`:参数表 + 分享链接:
- REALITY`vless://$XRAY_UUID@$DOMAIN:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=$DOMAIN&fp=chrome&pbk=$XRAY_PUBLIC_KEY&sid=$XRAY_SHORT_ID&type=tcp#...`
- WS`vless://$XRAY_WS_UUID@$DOMAIN:443?...&type=ws&path=%2Fscilad#...`
- XHTTP`vless://$XRAY_XHTTP_UUID@$DOMAIN:443?...&type=xhttp&path=$XHTTP_PATH&mode=auto#...`
- CDN 变体(CDN_DOMAIN 非空):host/sni 换 CDN_DOMAIN
- Hysteria2`hysteria2://$HY2_PASSWORD@$DOMAIN:8443/?mport=20000-30000&sni=www.$BASE_DOMAIN#...`
- `uninstall``systemctl disable --now` 三服务(容忍不存在);删 Caddyfile/config.json/
config.yamlsed 删 include 行 + 删 hysteria.nft + `nft delete table inet hysteria_nat`
`PURGE=1`apt purge caddy xray、hy2 官方卸载、删 cloudsmith 源/keyring
默认保留 ENV_FILEPURGE=1 且未设 KEEP_ENV 时删除
- **断言**DRY_RUN 摘要含 5 条链接与端口/UUID;`ACTION=uninstall DRY_RUN=1` 不报错
- **Commit**: `feat: self-check, client summary, uninstall`
## Task 8README + CLAUDE.md + 模板归档
**Files:** Modify README.md、CLAUDE.mdMove 5 模板 → `docs/templates-original/`
- README.md 追加中文小节:一键命令、必填/可选环境变量表、DRY_RUN、卸载、架构简述
- CLAUDE.md "What this repo is" 提及第二个脚本
- `git mv` 5 个模板并加存档 README("原始手工模板,已内嵌进脚本 heredoc"
- **测试**:最终 `bash -n` + `shellcheck` + `tests/run_tests.sh` 全绿
- **Commit**: `docs: usage docs, archive original templates`
## 执行方式
内联逐 Task 执行(executing-plans),每 Task 完成跑测试并 commit 后继续。