Context
本项目需要一套 Ansible 自动化配置,用于在多台服务器上快速部署代理服务(Trojan + Snell)。参考项目 ansible-proxy-chain 使用了 relay/landing 链式架构和单用户配置,但本项目的需求不同:需要在多台服务器上独立部署服务,且 Trojan 需要支持多用户模式。
Snell 是 Surge 开发团队设计的轻量级加密代理协议,仅支持单用户模式。Trojan 则需要在同一端口上支持多个用户同时连接,用户凭证通过外部 YAML 文件管理。
Goals / Non-Goals
Goals:
- 提供一键式多服务器 Ansible 部署流程
- 每台服务器部署完成后具备基础安全能力(SSH 加固、防火墙、入侵检测、自动更新)
- 支持在服务器上部署单用户 Snell 服务
- 支持在服务器上部署多用户 Trojan 服务,用户通过
users.yml 配置
- 自动管理 TLS 证书(Let's Encrypt + certbot)
Non-Goals:
- 不支持 relay/landing 链式代理架构
- 不自动生成客户端配置文件(如 Surge/Clash 配置)
- 不提供 Web 管理面板
- 不支持 Shadowsocks 或其他代理协议
Decisions
使用 trojan-go 作为 Trojan 实现
- Rationale: trojan-go 是 trojan-gfw 的 Go 语言重写版,性能更好,维护更活跃,原生支持多用户配置(通过
users 数组)
- Alternatives considered: trojan-gfw(C++ 版,多用户支持较弱,维护停滞)
多用户配置使用独立 YAML 文件
- Rationale: 将用户凭证从
group_vars 分离到 users.yml,便于单独管理和权限控制(可设置更严格的文件权限),同时保持 Ansible 变量结构的清晰
- 格式:
users.yml 定义 trojan_users 列表,每个用户含 name 和 password
- Alternatives considered: 直接放在
group_vars/all.yml 中(与其他配置混杂,不利于敏感信息隔离)
使用 systemd 管理所有服务
- Rationale: 现代 Linux 发行版的标准 init 系统,支持自动重启、日志收集、权限控制
- Implementation: 每个服务创建独立 service unit,使用专用非 root 用户运行,通过
AmbientCapabilities=CAP_NET_BIND_SERVICE 绑定 443 端口
使用 certbot + Let's Encrypt 管理 TLS 证书
- Rationale: 免费、自动化、广泛支持。通过 deploy-hook 在证书续期后自动复制到服务目录并 reload 服务
- 自动续期: 依赖 certbot 内置的 systemd timer 或 cron
单 playbook 多 host group 部署
- Rationale: 使用单一
site.yml 定义所有 plays,通过 inventory host groups 区分不同角色的服务器
- Structure:
all 组运行基础配置,可选的 snell 组和 trojan 组分别部署对应服务
Risks / Trade-offs
- [Risk] Snell 二进制文件需要从 GitHub Release 下载,国内服务器可能下载失败
- Mitigation: 支持通过变量配置自定义下载 URL / 代理;playbook 失败时提供清晰错误信息
- [Risk] Let's Encrypt 证书申请需要域名已正确解析到服务器 IP
- Mitigation: 在 certbot 任务前增加域名解析检查;提供详细的部署前置条件文档
- [Risk] 多用户 Trojan 配置变更后需要重载服务
- Mitigation: 使用 Ansible handler 监听配置模板变化,自动触发服务 reload
- [Risk]
users.yml 包含敏感凭证,可能意外提交到 Git
- Mitigation: 默认将
users.yml 加入 .gitignore;提供 users.yml.example 模板
- [Trade-off] Trojan 使用 trojan-go 的
users 数组方式管理多用户,而非数据库后端
- 这限制了用户数量和管理灵活性,但保持了部署的简单性和无外部依赖的优势