fuomag9/caddy-proxy-manager
GitHub: fuomag9/caddy-proxy-manager
Caddy 代理管理器提供现代化的 Web UI 与完整 API,简化 Caddy 反向代理、证书与 WAF 的配置与运维。
Stars: 61 | Forks: 7
# Caddy 代理管理器
用于管理 [Caddy 服务器](https://caddyserver.com/) 反向代理和证书的 Web 界面。
[](https://mit-license.org)
[](https://nextjs.org/)
[](https://www.docker.com/)
[Report Bug](https://github.com/fuomag9/caddy-proxy-manager/issues) • [Request Feature](https://github.com/fuomag9/caddy-proxy-manager/issues)
## 概述
该项目为 Caddy 服务器提供 Web UI,无需手动编辑 JSON 配置或 Caddyfile。它通过 shadcn/ui 界面处理反向代理、访问列表和证书管理。采用 Next.js 16、React 19、shadcn/ui、Tailwind CSS、Drizzle ORM 和 TypeScript 构建。分析数据(流量事件、WAF 事件)存储在 ClickHouse 中以实现快速聚合查询,并通过 TTL 自动保留 90 天。
## 安装
```
git clone https://github.com/fuomag9/caddy-proxy-manager.git
cd caddy-proxy-manager
cp .env.example .env
# 使用您的凭据编辑 .env
docker compose up -d
```
访问地址 `http://localhost:3000/login`
数据持久化存储在 Docker 卷中(caddy-manager-data、caddy-data、caddy-config、caddy-logs)。
## 功能特性
- **代理主机** - 支持自定义头部、多上游、负载均衡(8 种策略)、主动/被动健康检查、重试以及启用/禁用开关的反向代理
- **L4 代理主机** - 基于 TCP/UDP 流的代理,支持 TLS SNI 匹配、代理协议(v1/v2)、负载均衡、健康检查以及每主机地理屏蔽。通过 sidecar 自动管理 Docker Compose 端口
- **位置规则** - 基于路径的路由,可将不同路径转发到不同的上游(例如 `/api/*` 指向一个后端,`/ws/*` 指向另一个)
- **重定向与重写** - 每主机的重定向规则(301/302/307/308)和路径前缀重写
- **转发认证门户** - 内置身份提供者,无需外部 IdP 即可保护代理主机。支持凭证登录和 OAuth 登录门户、用户组及成员管理、按主机或用户/组的访问控制
- **WAF** - 基于 Coraza 的 Web 应用防火墙,支持可选的 OWASP 核心规则集(SQL 注入、XSS、文件包含、命令执行等)。可按主机启用/禁用、全局或按主机规则抑制、自定义 SecLang 指令,以及按严重性和阻断/检测分类的可搜索事件日志
- **分析** - 实时流量图表、协议分布、国家地图、顶级用户代理和可配置时间范围内的被阻断请求日志
- **地理屏蔽** - 按国家、大洲、ASN、CIDR 范围或精确 IP 地址对每主机进行屏蔽或放行。放行规则优先于屏蔽规则。支持失败关闭模式、自定义响应码/正文和可信代理支持
- **访问列表** - 多账户 HTTP 基本认证(bcrypt 哈希),可按代理主机分配
- **证书** - 通过 Caddy ACME 为每个代理主机自动提供 HTTPS(支持 Let's Encrypt / ZeroSSL),支持手动导入 SSL/TLS 证书并监控过期,内置 CA 用于签发和撤销内部客户端证书(mTLS)
- **mTLS** - 每主机的双向 TLS 认证。使用内置 CA 签发、追踪和撤销客户端证书。撤销后所有证书失效即拒绝连接
- **mTLS RBAC** - 为 mTLS 客户端证书定义角色,分配证书到角色,并创建基于路径的访问规则(例如 `/admin/*` 需要 `ops` 角色)
- **用户角色** - 三级权限系统(查看者、用户、管理员),控制仪表板访问、API 权限和功能可见性
- **用户管理** - 管理页面支持编辑角色、状态、资料;禁用或删除账户;搜索和筛选
- **用户组** - 将用户组织成组以用于转发认证访问控制。可将组分配给代理主机以一次性授权所有成员
- **Authentik 集成** - 每主机的转发认证 SSO,支持配置头部转发和保护路径
- **DNS 控制** - 每主机的自定义 DNS 解析器,支持上游 DNS 固定(IPv4/IPv6/两者)
- **REST API** - 提供 `/api/v1/` 下的完整 REST API,支持 Bearer 令牌认证,涵盖所有资源。交互式 OpenAPI 3.1.0 文档位于 `/api-docs`
- **API 令牌** - 创建和管理具有可选过期时间的 API 令牌,用于程序化访问
- **实例同步** - 主/从配置同步,主实例在每次变更时将代理主机、证书、访问列表和设置推送到从实例
- **OAuth / SSO** - 支持任何 OIDC 兼容提供者(Authentik、Keycloak、Auth0 等)。可从个人资料页面关联账户
- **设置** - ACME 邮箱、Cloudflare DNS-01、上游 DNS 固定默认值、Authentik 出站、Prometheus 指标、日志格式
- **审计日志** - 支持搜索的配置变更历史记录,带用户归属和分页
- **搜索与分页** - 所有数据表支持服务端搜索和分页
- **深色模式** - 完整支持深色/浅色主题,并自动检测系统偏好
- **移动端 UI** - 针对 iPhone 及其他窄屏设备优化的全响应式界面
## 配置
### 环境变量
| 变量 | 描述 | 默认值 | 是否必需 |
|------|------|--------|----------|
| `SESSION_SECRET` | 会话加密密钥(至少 32 字符) | 无 | **是** |
| `ADMIN_USERNAME` | 管理员登录用户名 | `admin` | **是** |
| `ADMIN_PASSWORD` | 管理员密码(详见下方要求) | `admin`(仅开发模式) | **是** |
| `BASE_URL` | 用户访问仪表板的公共 URL
**OAuth 必需** - 必须与重定向 URI 匹配 | `http://localhost:3000` | **是**(若使用 OAuth) | | `CADDY_API_URL` | Caddy 管理 API 端点 | `http://caddy:2019`(生产)
`http://localhost:2019`(开发) | 否 | | `DATABASE_URL` | SQLite 数据库 URL | `file:/app/data/caddy-proxy-manager.db` | 否 | | `CERTS_DIRECTORY` | 证书存储目录 | `./data/certs` | 否 | | `LOGIN_MAX_ATTEMPTS` | 触发速率限制前的最大登录尝试次数 | `5` | 否 | | `LOGIN_WINDOW_MS` | 速率限制窗口(毫秒) | `300000`(5 分钟) | 否 | | `LOGIN_BLOCK_MS` | 速率限制阻断时长(毫秒) | `900000`(15 分钟) | 否 | | `OAUTH_ENABLED` | 启用 OAuth2/OIDC 认证 | `false` | 否 | | `OAUTH_PROVIDER_NAME` | OAuth 提供者显示名称 | `OAuth2` | 否 | | `OAUTH_CLIENT_ID` | OAuth2 客户端 ID | 无 | 否 | | `OAUTH_CLIENT_SECRET` | OAuth2 客户端密钥 | 无 | 否 | | `OAUTH_ISSUER` | OAuth2 OIDC 发行者 URL | 无 | 否 | | `OAUTH_AUTHORIZATION_URL` | 可选的 OAuth 授权端点覆盖 | 从 `OAUTH_ISSUER` 自动发现 | 否 | | `OAUTH_TOKEN_URL` | 可选的 OAuth 令牌端点覆盖 | 从 `OAUTH_ISSUER` 自动发现 | 否 | | `OAUTH_USERINFO_URL` | 可选的 OAuth 用户信息端点覆盖 | 从 `OAUTH_ISSUER` 自动发现 | 否 | | `OAUTH_ALLOW_AUTO_LINKING` | 允许自动关联 OAuth 身份到现有用户 | `false` | 否 | | `AUTH_TRUST_HOST` | 信任 Host 头部以构建 URL(仅适用于重写 Host 的反向代理) | `false` | 否 | | `AUTH_RATE_LIMIT_ENABLED` | 启用 Better Auth 速率限制 | `true` | 否 | | `AUTH_RATE_LIMIT_WINDOW` | 速率限制窗口(秒) | `60` | 否 | | `AUTH_RATE_LIMIT_MAX` | 每个窗口最大请求数 | `5` | 否 | | `INSTANCE_MODE` | 实例角色:`standalone`、`master` 或 `slave` | `standalone` | 否 | | `INSTANCE_SYNC_TOKEN` | 从实例用于认证同步请求的 Bearer 令牌 | 无 | 否(若 `slave` 则必需) | | `INSTANCE_SLAVES` | 主实例推送配置的 JSON 数组(从实例) | 无 | 否 | | `INSTANCE_SYNC_INTERVAL` | 周期性同步间隔(秒,`0` 禁用) | `0` | 否 | | `INSTANCE_SYNC_ALLOW_HTTP` | 允许通过 HTTP 同步(仅用于内部 Docker 网络) | `false` | 否 | | `CLICKHOUSE_URL` | ClickHouse HTTP 端点(分析用) | `http://clickhouse:8123` | 否 | | `CLICKHOUSE_USER` | ClickHouse 用户名 | `cpm` | 否 | | `CLICKHOUSE_PASSWORD` | ClickHouse 密码(`openssl rand -base64 32` 生成) | 无 | **是** | | `CLICKHOUSE_DB` | ClickHouse 数据库名 | `analytics` | 否 | **生产环境要求:** - `SESSION_SECRET`:32 字符以上(`openssl rand -base64 32`) - `ADMIN_PASSWORD`:至少 12 位,包含大小写字母、数字和特殊字符 开发模式(`NODE_ENV=development`)允许使用默认的 `admin`/`admin` 凭据。 ## 安全 - 生产环境强制使用强密码(至少 12 位,含大小写字母、数字和特殊字符) - 会话密钥要求 32 字符以上 - 登录速率限制:每 60 秒最多 5 次尝试 - 所有配置变更均有审计追踪 - 支持 OAuth2/OIDC 单点登录 **生产环境部署:** ``` export SESSION_SECRET=$(openssl rand -base64 32) export ADMIN_USERNAME="admin" export ADMIN_PASSWORD="YourStr0ng-P@ssw0rd123!" docker compose up -d ``` **限制:** - 证书私钥以明文形式存储在 SQLite 中 - 内存级速率限制(不适用于多实例部署) ## 用户角色 CPM 提供三种权限递增的角色: | 能力 | 查看者 | 用户 | 管理员 | |------|--------|------|--------| | 登录仪表板 | 是 | 是 | 是 | | 查看个人资料 | 是 | 是 | 是 | | 访问转发认证保护的应用(已授权) | 是 | 是 | 是 | | 管理代理主机、证书、访问列表 | 否 | 否 | 是 | | 管理用户、组和设置 | 否 | 否 | 是 | | 查看分析、审核日志和 API 文档 | 否 | 否 | 是 | | 创建和管理 API 令牌 | 否 | 否 | 是 | | 访问 REST API(`/api/v1/`) | 否 | 否 | 是 | 新用户默认分配为 **用户** 角色。初始管理员账户通过 `ADMIN_USERNAME` / `ADMIN_PASSWORD` 环境变量创建。 ## 证书管理 Caddy 会自动为所有代理主机获取 Let's Encrypt 证书。 **Cloudflare DNS-01(可选)** - 在设置中配置 Cloudflare API 令牌(`Zone.DNS:Edit` 权限) **自定义证书(可选)** - 可通过证书页面导入自有证书。私钥以明文形式存储在 SQLite 中。 ## 地理屏蔽 地理屏蔽按代理主机配置。需要 MaxMind GeoLite2 数据库(参见 [GeoIP 设置](#geoip-setup))。 ### 规则类型 | 类型 | 示例 | 描述 | |------|------|------| | 国家 | `DE` | ISO 3166-1 alpha-2 国家代码 | | 大洲 | `EU` | `AF`、`AN`、`AS`、`EU`、`NA`、`OC`、`SA` | | ASN | `24940` | 自治系统编号 | | CIDR | `91.98.150.0/24` | CIDR 表示的 IP 范围 | | IP | `91.98.150.103` | 精确 IP 地址 | 规则可分为 **block** 或 **allow**。放行规则优先于屏蔽规则——可以屏蔽整个大洲,然后允许特定 IP 或 ASN 通过。 ### GeoIP 设置 地理屏蔽需要 MaxMind GeoLite2 国家数据库和/或 ASN 数据库。使用内置的 `geoipupdate` 服务: 1. 在 [maxmind.com](https://www.maxmind.com/) 注册免费账户 2. 生成包含 `GeoLite2-Country` 和 `GeoLite2-ASN` 权限的许可证密钥 3. 添加到 `.env`: ``` GEOIPUPDATE_ACCOUNT_ID=your-account-id GEOIPUPDATE_LICENSE_KEY=your-license-key ``` 4. 启动服务: ``` docker compose --profile geoipupdate up -d ``` 数据库存储在 `geoip-data` Docker 卷中,并在 Web 和 Caddy 容器间共享。 ## WAF(Web 应用防火墙) WAF 由 [Coraza](https://coraza.io/) 提供支持,并集成 OWASP 核心规则集。 在 **WAF → 设置** 中全局启用,然后可按主机覆盖。两种模式: - **Block** — 匹配规则的请求将被拒绝并返回 403 - **Detect** — 请求仅记录但不阻止 **OWASP CRS** 默认启用,覆盖 SQL 注入、XSS、文件包含、命令执行等。 **规则抑制** — 可从事件详情抽屉或“被抑制规则”标签页全局或按主机抑制噪声规则。 **自定义指令** — 接受任何 ModSecurity SecLang 语法,例如: ``` SecRule REQUEST_URI "@beginsWith /api/" "id:9001,phase:1,ctl:ruleEngine=Off,nolog" ``` ## 实例同步 运行主实例,在每次变更时将配置推送到一个或多个从实例。 ``` # Master INSTANCE_MODE=master INSTANCE_SLAVES='[{"name":"replica","url":"https://replica.example.com","token":"<32-char-token>"}]' # Slave INSTANCE_MODE=slave INSTANCE_SYNC_TOKEN=<32-char-token> ``` 同步数据包括:代理主机、证书、访问列表和设置。**用户账户不会被同步**。 生产环境中使用 HTTPS 从实例 URL。仅在内部 Docker 网络中设置 `INSTANCE_SYNC_ALLOW_HTTP=true`。 参见 [环境变量参考](https://github.com/fuomag9/caddy-proxy-manager/wiki/Environment-Variables-Reference) 了解所有 `INSTANCE_*` 选项。 ## 上游 DNS 固定 可在全局(**设置 → 上游 DNS 固定**)启用,并为每主机覆盖(**代理主机 → 上游 DNS 固定**)。 启用后,主机名上游在配置保存/加载时解析为具体 IP 并写入 Caddy。支持以下地址族: - `both`(首选,先解析 AAAA 再解析 A,优先 IPv6) - `ipv6` - `ipv4` ### 重要 HTTPS 限制 如果某个反向代理处理器包含多个不同的 HTTPS 上游主机名,则对该 HTTPS 上游跳过固定以避免 TLS SNI 不匹配。此时仍保留主机名拨号。 HTTP 上游在同一处理器中仍可进行固定。 ## OAuth 认证 支持任何 OIDC 兼容提供者(Authentik、Keycloak、Auth0 等)。提供者可通过环境变量或 **设置 → OAuth 提供者** UI 配置。 ### 选项 A:通过 UI 配置(推荐) 1. 以管理员身份登录并进入 **设置 → OAuth 提供者** 2. 点击 **添加提供者** 并填写详细信息 3. 复制显示的 **回调 URL** 并添加到 OAuth 提供器的允许重定向 URI ### 选项 B:通过环境变量配置 ``` # 设置您的公共 URL(OAuth 正常运行所必需) BASE_URL=https://caddy-manager.example.com OAUTH_ENABLED=true OAUTH_PROVIDER_NAME="Authentik" # Display name OAUTH_CLIENT_ID=your-client-id OAUTH_CLIENT_SECRET=your-client-secret OAUTH_ISSUER=https://auth.example.com/application/o/app/ ``` **重定向 URI 配置:** 回调 URL 格式为: ``` {BASE_URL}/api/auth/oauth2/callback/{provider-id} ``` 对于环境配置的提供器,提供器 ID 从 `OAUTH_PROVIDER_NAME` 派生(小写,替换非字母数字为 `-`)。确切的回调 URL 在 **设置 → OAuth 提供者** 同步后显示。 示例: - `https://caddy-manager.example.com/api/auth/oauth2/callback/authentik-QXV0aG`(生产) - `http://localhost:3000/api/auth/oauth2/callback/authentik-QXV0aG`(开发) `BASE_URL` 环境变量必须与用户访问仪表板的地址完全匹配。 OAuth 登录显示在登录页面,与凭证并列。用户可从个人资料页面关联 OAuth 身份。 ## 转发认证门户 CPM 包含内置的转发认证身份提供者,无需外部 IdP(Authentik、Authelia 等)。 ### 工作原理 1. 在代理主机上启用 **转发认证** 并选择允许访问的用户或组 2. 未认证访客会被重定向到 CPM 登录门户 3. 登录后,CPM 颁发会话 Cookie 并重定向回受保护应用 4. Caddy 的 `forward_auth` 指令验证后续请求的每个请求 ### 用户组 在 **用户组 页面创建组以组织用户。授予组对代理主机的访问权限后,该组的所有当前及未来成员将自动获得访问权限。 ### 每主机访问控制 每个启用转发认证的主机都有独立的访问列表,指定允许的用户和/或组。访问权限独立于用户角色——即使管理员也必须被明确授权。 ## 路线图 - [ ] 额外的 DNS 提供商(Route53、Namecheap 等) [Open an issue](https://github.com/fuomag9/caddy-proxy-manager/issues) 提交功能请求。 ## 贡献 欢迎贡献: 1. 叉出仓库 2. 创建功能分支(`git checkout -b feature/name`) 3. 提交变更(`git commit -m 'Add feature'`) 4. 推送到分支(`git push origin feature/name`) 5. 创建拉取请求 - 遵循现有代码风格(TypeScript、Prettier 格式化) - 为新功能添加测试(如适用) - 更新用户文档以反映面向用户的变更 - 保持提交专注并撰写清晰的提交信息 ## 支持 - **问题:** [GitHub Issues](https://github.com/fuomag9/caddy-proxy-manager/issues) 用于错误和功能请求 - **讨论:** [GitHub Discussions](https://github.com/fuomag9/caddy-proxy-manager/discussions) 用于提问和分享想法 ## 许可证 本项目根据 MIT 许可证授权——参见 [LICENSE](LICENSE) 文件。 ## 感谢 - **[Caddy 服务器](https://caddyserver.com/)** — 支持本项目的优秀 Web 服务器 - **[Nginx 代理管理器](https://github.com/NginxProxyManager/nginx-proxy-manager)** — 原始项目 - **[Next.js](https://nextjs.org/)** — 生产环境的 React 框架 - **[shadcn/ui](https://ui.shadcn.com/)** — 基于 Radix UI 和 Tailwind CSS 构建的精美设计组件 - **[Drizzle ORM](https://orm.drizzle.team/)** — 轻量级 SQL 迁移和类型安全查询
## 概述
该项目为 Caddy 服务器提供 Web UI,无需手动编辑 JSON 配置或 Caddyfile。它通过 shadcn/ui 界面处理反向代理、访问列表和证书管理。采用 Next.js 16、React 19、shadcn/ui、Tailwind CSS、Drizzle ORM 和 TypeScript 构建。分析数据(流量事件、WAF 事件)存储在 ClickHouse 中以实现快速聚合查询,并通过 TTL 自动保留 90 天。
## 安装
```
git clone https://github.com/fuomag9/caddy-proxy-manager.git
cd caddy-proxy-manager
cp .env.example .env
# 使用您的凭据编辑 .env
docker compose up -d
```
访问地址 `http://localhost:3000/login`
数据持久化存储在 Docker 卷中(caddy-manager-data、caddy-data、caddy-config、caddy-logs)。
## 功能特性
- **代理主机** - 支持自定义头部、多上游、负载均衡(8 种策略)、主动/被动健康检查、重试以及启用/禁用开关的反向代理
- **L4 代理主机** - 基于 TCP/UDP 流的代理,支持 TLS SNI 匹配、代理协议(v1/v2)、负载均衡、健康检查以及每主机地理屏蔽。通过 sidecar 自动管理 Docker Compose 端口
- **位置规则** - 基于路径的路由,可将不同路径转发到不同的上游(例如 `/api/*` 指向一个后端,`/ws/*` 指向另一个)
- **重定向与重写** - 每主机的重定向规则(301/302/307/308)和路径前缀重写
- **转发认证门户** - 内置身份提供者,无需外部 IdP 即可保护代理主机。支持凭证登录和 OAuth 登录门户、用户组及成员管理、按主机或用户/组的访问控制
- **WAF** - 基于 Coraza 的 Web 应用防火墙,支持可选的 OWASP 核心规则集(SQL 注入、XSS、文件包含、命令执行等)。可按主机启用/禁用、全局或按主机规则抑制、自定义 SecLang 指令,以及按严重性和阻断/检测分类的可搜索事件日志
- **分析** - 实时流量图表、协议分布、国家地图、顶级用户代理和可配置时间范围内的被阻断请求日志
- **地理屏蔽** - 按国家、大洲、ASN、CIDR 范围或精确 IP 地址对每主机进行屏蔽或放行。放行规则优先于屏蔽规则。支持失败关闭模式、自定义响应码/正文和可信代理支持
- **访问列表** - 多账户 HTTP 基本认证(bcrypt 哈希),可按代理主机分配
- **证书** - 通过 Caddy ACME 为每个代理主机自动提供 HTTPS(支持 Let's Encrypt / ZeroSSL),支持手动导入 SSL/TLS 证书并监控过期,内置 CA 用于签发和撤销内部客户端证书(mTLS)
- **mTLS** - 每主机的双向 TLS 认证。使用内置 CA 签发、追踪和撤销客户端证书。撤销后所有证书失效即拒绝连接
- **mTLS RBAC** - 为 mTLS 客户端证书定义角色,分配证书到角色,并创建基于路径的访问规则(例如 `/admin/*` 需要 `ops` 角色)
- **用户角色** - 三级权限系统(查看者、用户、管理员),控制仪表板访问、API 权限和功能可见性
- **用户管理** - 管理页面支持编辑角色、状态、资料;禁用或删除账户;搜索和筛选
- **用户组** - 将用户组织成组以用于转发认证访问控制。可将组分配给代理主机以一次性授权所有成员
- **Authentik 集成** - 每主机的转发认证 SSO,支持配置头部转发和保护路径
- **DNS 控制** - 每主机的自定义 DNS 解析器,支持上游 DNS 固定(IPv4/IPv6/两者)
- **REST API** - 提供 `/api/v1/` 下的完整 REST API,支持 Bearer 令牌认证,涵盖所有资源。交互式 OpenAPI 3.1.0 文档位于 `/api-docs`
- **API 令牌** - 创建和管理具有可选过期时间的 API 令牌,用于程序化访问
- **实例同步** - 主/从配置同步,主实例在每次变更时将代理主机、证书、访问列表和设置推送到从实例
- **OAuth / SSO** - 支持任何 OIDC 兼容提供者(Authentik、Keycloak、Auth0 等)。可从个人资料页面关联账户
- **设置** - ACME 邮箱、Cloudflare DNS-01、上游 DNS 固定默认值、Authentik 出站、Prometheus 指标、日志格式
- **审计日志** - 支持搜索的配置变更历史记录,带用户归属和分页
- **搜索与分页** - 所有数据表支持服务端搜索和分页
- **深色模式** - 完整支持深色/浅色主题,并自动检测系统偏好
- **移动端 UI** - 针对 iPhone 及其他窄屏设备优化的全响应式界面
## 配置
### 环境变量
| 变量 | 描述 | 默认值 | 是否必需 |
|------|------|--------|----------|
| `SESSION_SECRET` | 会话加密密钥(至少 32 字符) | 无 | **是** |
| `ADMIN_USERNAME` | 管理员登录用户名 | `admin` | **是** |
| `ADMIN_PASSWORD` | 管理员密码(详见下方要求) | `admin`(仅开发模式) | **是** |
| `BASE_URL` | 用户访问仪表板的公共 URL**OAuth 必需** - 必须与重定向 URI 匹配 | `http://localhost:3000` | **是**(若使用 OAuth) | | `CADDY_API_URL` | Caddy 管理 API 端点 | `http://caddy:2019`(生产)
`http://localhost:2019`(开发) | 否 | | `DATABASE_URL` | SQLite 数据库 URL | `file:/app/data/caddy-proxy-manager.db` | 否 | | `CERTS_DIRECTORY` | 证书存储目录 | `./data/certs` | 否 | | `LOGIN_MAX_ATTEMPTS` | 触发速率限制前的最大登录尝试次数 | `5` | 否 | | `LOGIN_WINDOW_MS` | 速率限制窗口(毫秒) | `300000`(5 分钟) | 否 | | `LOGIN_BLOCK_MS` | 速率限制阻断时长(毫秒) | `900000`(15 分钟) | 否 | | `OAUTH_ENABLED` | 启用 OAuth2/OIDC 认证 | `false` | 否 | | `OAUTH_PROVIDER_NAME` | OAuth 提供者显示名称 | `OAuth2` | 否 | | `OAUTH_CLIENT_ID` | OAuth2 客户端 ID | 无 | 否 | | `OAUTH_CLIENT_SECRET` | OAuth2 客户端密钥 | 无 | 否 | | `OAUTH_ISSUER` | OAuth2 OIDC 发行者 URL | 无 | 否 | | `OAUTH_AUTHORIZATION_URL` | 可选的 OAuth 授权端点覆盖 | 从 `OAUTH_ISSUER` 自动发现 | 否 | | `OAUTH_TOKEN_URL` | 可选的 OAuth 令牌端点覆盖 | 从 `OAUTH_ISSUER` 自动发现 | 否 | | `OAUTH_USERINFO_URL` | 可选的 OAuth 用户信息端点覆盖 | 从 `OAUTH_ISSUER` 自动发现 | 否 | | `OAUTH_ALLOW_AUTO_LINKING` | 允许自动关联 OAuth 身份到现有用户 | `false` | 否 | | `AUTH_TRUST_HOST` | 信任 Host 头部以构建 URL(仅适用于重写 Host 的反向代理) | `false` | 否 | | `AUTH_RATE_LIMIT_ENABLED` | 启用 Better Auth 速率限制 | `true` | 否 | | `AUTH_RATE_LIMIT_WINDOW` | 速率限制窗口(秒) | `60` | 否 | | `AUTH_RATE_LIMIT_MAX` | 每个窗口最大请求数 | `5` | 否 | | `INSTANCE_MODE` | 实例角色:`standalone`、`master` 或 `slave` | `standalone` | 否 | | `INSTANCE_SYNC_TOKEN` | 从实例用于认证同步请求的 Bearer 令牌 | 无 | 否(若 `slave` 则必需) | | `INSTANCE_SLAVES` | 主实例推送配置的 JSON 数组(从实例) | 无 | 否 | | `INSTANCE_SYNC_INTERVAL` | 周期性同步间隔(秒,`0` 禁用) | `0` | 否 | | `INSTANCE_SYNC_ALLOW_HTTP` | 允许通过 HTTP 同步(仅用于内部 Docker 网络) | `false` | 否 | | `CLICKHOUSE_URL` | ClickHouse HTTP 端点(分析用) | `http://clickhouse:8123` | 否 | | `CLICKHOUSE_USER` | ClickHouse 用户名 | `cpm` | 否 | | `CLICKHOUSE_PASSWORD` | ClickHouse 密码(`openssl rand -base64 32` 生成) | 无 | **是** | | `CLICKHOUSE_DB` | ClickHouse 数据库名 | `analytics` | 否 | **生产环境要求:** - `SESSION_SECRET`:32 字符以上(`openssl rand -base64 32`) - `ADMIN_PASSWORD`:至少 12 位,包含大小写字母、数字和特殊字符 开发模式(`NODE_ENV=development`)允许使用默认的 `admin`/`admin` 凭据。 ## 安全 - 生产环境强制使用强密码(至少 12 位,含大小写字母、数字和特殊字符) - 会话密钥要求 32 字符以上 - 登录速率限制:每 60 秒最多 5 次尝试 - 所有配置变更均有审计追踪 - 支持 OAuth2/OIDC 单点登录 **生产环境部署:** ``` export SESSION_SECRET=$(openssl rand -base64 32) export ADMIN_USERNAME="admin" export ADMIN_PASSWORD="YourStr0ng-P@ssw0rd123!" docker compose up -d ``` **限制:** - 证书私钥以明文形式存储在 SQLite 中 - 内存级速率限制(不适用于多实例部署) ## 用户角色 CPM 提供三种权限递增的角色: | 能力 | 查看者 | 用户 | 管理员 | |------|--------|------|--------| | 登录仪表板 | 是 | 是 | 是 | | 查看个人资料 | 是 | 是 | 是 | | 访问转发认证保护的应用(已授权) | 是 | 是 | 是 | | 管理代理主机、证书、访问列表 | 否 | 否 | 是 | | 管理用户、组和设置 | 否 | 否 | 是 | | 查看分析、审核日志和 API 文档 | 否 | 否 | 是 | | 创建和管理 API 令牌 | 否 | 否 | 是 | | 访问 REST API(`/api/v1/`) | 否 | 否 | 是 | 新用户默认分配为 **用户** 角色。初始管理员账户通过 `ADMIN_USERNAME` / `ADMIN_PASSWORD` 环境变量创建。 ## 证书管理 Caddy 会自动为所有代理主机获取 Let's Encrypt 证书。 **Cloudflare DNS-01(可选)** - 在设置中配置 Cloudflare API 令牌(`Zone.DNS:Edit` 权限) **自定义证书(可选)** - 可通过证书页面导入自有证书。私钥以明文形式存储在 SQLite 中。 ## 地理屏蔽 地理屏蔽按代理主机配置。需要 MaxMind GeoLite2 数据库(参见 [GeoIP 设置](#geoip-setup))。 ### 规则类型 | 类型 | 示例 | 描述 | |------|------|------| | 国家 | `DE` | ISO 3166-1 alpha-2 国家代码 | | 大洲 | `EU` | `AF`、`AN`、`AS`、`EU`、`NA`、`OC`、`SA` | | ASN | `24940` | 自治系统编号 | | CIDR | `91.98.150.0/24` | CIDR 表示的 IP 范围 | | IP | `91.98.150.103` | 精确 IP 地址 | 规则可分为 **block** 或 **allow**。放行规则优先于屏蔽规则——可以屏蔽整个大洲,然后允许特定 IP 或 ASN 通过。 ### GeoIP 设置 地理屏蔽需要 MaxMind GeoLite2 国家数据库和/或 ASN 数据库。使用内置的 `geoipupdate` 服务: 1. 在 [maxmind.com](https://www.maxmind.com/) 注册免费账户 2. 生成包含 `GeoLite2-Country` 和 `GeoLite2-ASN` 权限的许可证密钥 3. 添加到 `.env`: ``` GEOIPUPDATE_ACCOUNT_ID=your-account-id GEOIPUPDATE_LICENSE_KEY=your-license-key ``` 4. 启动服务: ``` docker compose --profile geoipupdate up -d ``` 数据库存储在 `geoip-data` Docker 卷中,并在 Web 和 Caddy 容器间共享。 ## WAF(Web 应用防火墙) WAF 由 [Coraza](https://coraza.io/) 提供支持,并集成 OWASP 核心规则集。 在 **WAF → 设置** 中全局启用,然后可按主机覆盖。两种模式: - **Block** — 匹配规则的请求将被拒绝并返回 403 - **Detect** — 请求仅记录但不阻止 **OWASP CRS** 默认启用,覆盖 SQL 注入、XSS、文件包含、命令执行等。 **规则抑制** — 可从事件详情抽屉或“被抑制规则”标签页全局或按主机抑制噪声规则。 **自定义指令** — 接受任何 ModSecurity SecLang 语法,例如: ``` SecRule REQUEST_URI "@beginsWith /api/" "id:9001,phase:1,ctl:ruleEngine=Off,nolog" ``` ## 实例同步 运行主实例,在每次变更时将配置推送到一个或多个从实例。 ``` # Master INSTANCE_MODE=master INSTANCE_SLAVES='[{"name":"replica","url":"https://replica.example.com","token":"<32-char-token>"}]' # Slave INSTANCE_MODE=slave INSTANCE_SYNC_TOKEN=<32-char-token> ``` 同步数据包括:代理主机、证书、访问列表和设置。**用户账户不会被同步**。 生产环境中使用 HTTPS 从实例 URL。仅在内部 Docker 网络中设置 `INSTANCE_SYNC_ALLOW_HTTP=true`。 参见 [环境变量参考](https://github.com/fuomag9/caddy-proxy-manager/wiki/Environment-Variables-Reference) 了解所有 `INSTANCE_*` 选项。 ## 上游 DNS 固定 可在全局(**设置 → 上游 DNS 固定**)启用,并为每主机覆盖(**代理主机 → 上游 DNS 固定**)。 启用后,主机名上游在配置保存/加载时解析为具体 IP 并写入 Caddy。支持以下地址族: - `both`(首选,先解析 AAAA 再解析 A,优先 IPv6) - `ipv6` - `ipv4` ### 重要 HTTPS 限制 如果某个反向代理处理器包含多个不同的 HTTPS 上游主机名,则对该 HTTPS 上游跳过固定以避免 TLS SNI 不匹配。此时仍保留主机名拨号。 HTTP 上游在同一处理器中仍可进行固定。 ## OAuth 认证 支持任何 OIDC 兼容提供者(Authentik、Keycloak、Auth0 等)。提供者可通过环境变量或 **设置 → OAuth 提供者** UI 配置。 ### 选项 A:通过 UI 配置(推荐) 1. 以管理员身份登录并进入 **设置 → OAuth 提供者** 2. 点击 **添加提供者** 并填写详细信息 3. 复制显示的 **回调 URL** 并添加到 OAuth 提供器的允许重定向 URI ### 选项 B:通过环境变量配置 ``` # 设置您的公共 URL(OAuth 正常运行所必需) BASE_URL=https://caddy-manager.example.com OAUTH_ENABLED=true OAUTH_PROVIDER_NAME="Authentik" # Display name OAUTH_CLIENT_ID=your-client-id OAUTH_CLIENT_SECRET=your-client-secret OAUTH_ISSUER=https://auth.example.com/application/o/app/ ``` **重定向 URI 配置:** 回调 URL 格式为: ``` {BASE_URL}/api/auth/oauth2/callback/{provider-id} ``` 对于环境配置的提供器,提供器 ID 从 `OAUTH_PROVIDER_NAME` 派生(小写,替换非字母数字为 `-`)。确切的回调 URL 在 **设置 → OAuth 提供者** 同步后显示。 示例: - `https://caddy-manager.example.com/api/auth/oauth2/callback/authentik-QXV0aG`(生产) - `http://localhost:3000/api/auth/oauth2/callback/authentik-QXV0aG`(开发) `BASE_URL` 环境变量必须与用户访问仪表板的地址完全匹配。 OAuth 登录显示在登录页面,与凭证并列。用户可从个人资料页面关联 OAuth 身份。 ## 转发认证门户 CPM 包含内置的转发认证身份提供者,无需外部 IdP(Authentik、Authelia 等)。 ### 工作原理 1. 在代理主机上启用 **转发认证** 并选择允许访问的用户或组 2. 未认证访客会被重定向到 CPM 登录门户 3. 登录后,CPM 颁发会话 Cookie 并重定向回受保护应用 4. Caddy 的 `forward_auth` 指令验证后续请求的每个请求 ### 用户组 在 **用户组 页面创建组以组织用户。授予组对代理主机的访问权限后,该组的所有当前及未来成员将自动获得访问权限。 ### 每主机访问控制 每个启用转发认证的主机都有独立的访问列表,指定允许的用户和/或组。访问权限独立于用户角色——即使管理员也必须被明确授权。 ## 路线图 - [ ] 额外的 DNS 提供商(Route53、Namecheap 等) [Open an issue](https://github.com/fuomag9/caddy-proxy-manager/issues) 提交功能请求。 ## 贡献 欢迎贡献: 1. 叉出仓库 2. 创建功能分支(`git checkout -b feature/name`) 3. 提交变更(`git commit -m 'Add feature'`) 4. 推送到分支(`git push origin feature/name`) 5. 创建拉取请求 - 遵循现有代码风格(TypeScript、Prettier 格式化) - 为新功能添加测试(如适用) - 更新用户文档以反映面向用户的变更 - 保持提交专注并撰写清晰的提交信息 ## 支持 - **问题:** [GitHub Issues](https://github.com/fuomag9/caddy-proxy-manager/issues) 用于错误和功能请求 - **讨论:** [GitHub Discussions](https://github.com/fuomag9/caddy-proxy-manager/discussions) 用于提问和分享想法 ## 许可证 本项目根据 MIT 许可证授权——参见 [LICENSE](LICENSE) 文件。 ## 感谢 - **[Caddy 服务器](https://caddyserver.com/)** — 支持本项目的优秀 Web 服务器 - **[Nginx 代理管理器](https://github.com/NginxProxyManager/nginx-proxy-manager)** — 原始项目 - **[Next.js](https://nextjs.org/)** — 生产环境的 React 框架 - **[shadcn/ui](https://ui.shadcn.com/)** — 基于 Radix UI 和 Tailwind CSS 构建的精美设计组件 - **[Drizzle ORM](https://orm.drizzle.team/)** — 轻量级 SQL 迁移和类型安全查询
[⬆ 返回顶部](#caddy-proxy-manager)
标签:Caddy, ClickHouse, Docker, Drizzle ORM, HTTPS, mTLS, React, REST API, SEO, shadcn/ui, Streamlit, Syscalls, Tailwind CSS, TCP/UDP 代理, TypeScript, WAF, Web 管理界面, 健康检查, 双因素认证, 反向代理, 地理位置屏蔽, 安全插件, 安全防御评估, 审计日志, 流代理, 网络测绘, 自动化攻击, 访问控制, 证书管理, 请求拦截, 负载均衡, 路径重写, 重定向