cmos486/argos-edge

GitHub: cmos486/argos-edge

自托管边缘网关,整合反向代理、WAF、负载均衡与 SSO,解决家庭实验室多组件集成与安全管控痛点。

Stars: 0 | Forks: 0

# argos-edge [![License: BSL 1.1](https://img.shields.io/badge/License-BSL%201.1-blue.svg)](LICENSE) [![Release](https://img.shields.io/github/v/release/cmos486/argos-edge)](https://github.com/cmos486/argos-edge/releases) [![Docs](https://img.shields.io/badge/docs-cmos486.github.io-blue)](https://cmos486.github.io/argos-edge/) 自托管边缘网关,适用于家庭实验室。反向代理 + WAF + 负载均衡 + Let's Encrypt,统一网页面板。由 Caddy、Coraza 和 CrowdSec 提供支持。 **状态:** v1.0.0 — 首个稳定发布。家庭实验室级别:针对其目标用例的生产就绪版本,单人维护,尽力提供支持。请参阅 [文档门户](https://cmos486.github.io/argos-edge/) 获取安装与运维说明。 ## 为什么 Nginx Proxy Manager 太简单。Zoraxy 缺乏 WAF。BunkerWeb 和 SafeLine 很棒,但不完全符合我的需求。Argos Edge 是一个个人家庭实验室项目,旨在解决我自己的痛点:提供一个集成了代理 + 真实 WAF + ALB 风格规则 + 优秀仪表板的单一面板。 ## 技术栈 - [Caddy 2](https://caddyserver.com/) 作为代理(TLS、Let's Encrypt、HTTP/3) - [Coraza](https://coraza.io/) + OWASP CRS 作为 WAF(阶段 4) - [CrowdSec](https://www.crowdsec.net/) 用于社区威胁情报(阶段 6) - Go 后端,React + TypeScript + Tailwind 前端,SQLite 存储 ## 快速开始 ``` git clone https://github.com/cmos486/argos-edge.git cd argos-edge cp .env.example .env # edit .env: set ARGOS_SESSION_SECRET, ARGOS_MASTER_KEY, ARGOS_INITIAL_ADMIN_PASSWORD docker compose up -d ``` 然后打开 `http://:8080`,使用你在 `.env` 中设置的凭据登录。 ## 面板访问模式 第 9b 阶段引入了两种访问模式,通过 `ARGOS_PANEL_MODE` 选择: | 方面 | `lan`(默认) | `behind_caddy` | |---|---|---| | 如何访问面板 | `http://:8080` | `https://$ARGOS_PANEL_DOMAIN/` | | `:8080` 是否在主机上发布 | 是 | 否(仅内部) | | Cookie 的 `Secure` 标志 | 关闭 | 开启 | | `SameSite` | 严格(两种模式) | 严格 | | HSTS 头部 | 不发送 | `max-age=31536000; includeSubDomains` | | 内容安全策略 | 不发送 | 发送(严格,不允许外部来源) | | 浏览器推送 | 阻止(无 HTTPS) | 可用 | | 首次启动引导 | - | 自动创建主机行 + 指向 `argos:8080` 的 TG | ### LAN 模式 无需操作:`docker compose up -d` 会在 `http://:8080` 启动面板。 ### behind_caddy 模式 1. 在 `.env` 中设置: ARGOS_PANEL_MODE=behind_caddy ARGOS_PANEL_DOMAIN=panel.example.com 2. 使用覆盖文件启动堆栈: docker compose -f docker-compose.yml -f docker-compose.behind-caddy.yml up -d 3. 面板在首次启动时自动注册为主机;Caddy 在约 30 秒内通过 DNS-01 获取证书。访问 `https://panel.example.com/`。 要求 Docker Compose v2.24+(用于覆盖文件中的 `!reset []` YAML 标签)。 **v0.9.0 的重大变更:** `ARGOS_COOKIE_SECURE` 已被移除。Cookie 安全标志现在从 `ARGOS_PANEL_MODE` 派生。 ## CrowdSec(威胁情报) 第 7 阶段将 CrowdSec 作为 docker-compose 服务捆绑。CrowdSec 读取 Caddy 的访问日志,并将决策推送到面板的 UI(`/threats`)以及 Caddy 的 bouncer 以进行强制。在首次 `docker compose up -d` 后的一次性设置: ``` # 1. Issue a bouncer API key for Caddy's HTTP bouncer module docker compose exec argos-crowdsec cscli bouncers add argos-caddy-bouncer # copy the printed key # 2. Register the panel as a CrowdSec "machine" so it can add / delete # decisions from the UI (bouncer keys are read-only) docker compose exec argos-crowdsec cscli machines add argos-panel -a -f /tmp/argos-panel.yaml docker compose exec argos-crowdsec cat /tmp/argos-panel.yaml # copy login + password # 3. Put all three values in .env: # CROWDSEC_BOUNCER_API_KEY= # CROWDSEC_PANEL_MACHINE_USER=argos-panel # CROWDSEC_PANEL_MACHINE_PASSWORD= # 4. Rebuild so caddy picks up the bouncer key + panel reads new env docker compose up -d --build ``` 在第 4 步运行之前,面板会正常启动,并且 `/threats` 会显示一个带有上述命令的设置横幅。Caddy 在无强制的情况下服务流量。 要安装额外的 CrowdSec 集合: ``` docker compose exec argos-crowdsec cscli collections install crowdsecurity/ ``` CrowdSec 的 LAPI 在 docker 网络中监听 `crowdsec:8081`(未发布到主机)。默认 LAPI 端口 8080 会与 argos-panel 冲突,因此我们将 `crowdsec/config.yaml.local` 挂载以覆盖它。 ## OIDC SSO + ForwardAuth Argos 支持通过任何符合 OIDC 标准的提供者 (Authentik、Authelia、Keycloak、Google、Okta、...)登录面板,并且可以保护 argos 代理的任何主机,通过到同一会话的 ForwardAuth 往返。 本地密码 + TOTP 路径在 IdP 不可用时仍完全可用,作为应急回退路线。 ### 架构概览 ``` browser ──▶ Caddy (argos-caddy) ──▶ upstream (huntlo, etc.) │ │ [host.auth_required=1] ▼ forward_auth handler │ GET /api/auth/forward │ cookies forwarded ▼ argos panel │ ├─ cookie valid → 200 + X-Auth-{User,Email,Name,Provider} │ (copied onto upstream request) │ └─ cookie missing → 302 /login?rd= user logs in (password+TOTP or SSO) cookie Domain= → subdomains share it ``` 关键点: 1. **一次仅一个提供者。** `/system` > SSO 保存发行者 URL、 客户端 ID/密钥、作用域、电子邮件/域名允许列表。 `client_secret` 使用 AES-GCM 的 `ARGOS_MASTER_KEY` 加密。 2. **PKCE 是强制性的。** Argos 永远不会发出非 PKCE 流程。 3. **OIDC 用户绕过本地 TOTP** — IdP 是 MFA 的权威来源。 本地用户继续使用 bcrypt + TOTP。 4. **应急回退:** 一个拥有本地用户名+密码及 TOTP 的用户 始终可用。`docker compose exec argos /argos disable-2fa --user admin --yes` 仍可在管理员丢失手机和恢复码时重置 TOTP。 5. **父域 Cookie** 是将面板会话绑定到 ForwardAuth 保护子域的关键。配置一次后,每个 `*.parent-domain` 主机均可设置为 `auth_required=1`。 ### 设置:Authentik 1. 提供者 → 创建 → OAuth2/OpenID 提供者 - 名称:argos - 客户端类型:机密 - 重定向 URI:`https://argos.example.com/api/auth/oidc/callback` - 作用域:openid profile email 2. 应用程序 → 创建 → 绑定到该提供者。 3. 复制客户端 ID + 客户端密钥。 4. argos **/system** → 单点登录: - 发行者 URL:`https://auth.example.com/application/o/argos/` (Authentik 在 `/.well-known/openid-configuration` 处公布发现;仅输入基础 URL)。 - 客户端 ID / 密钥:粘贴。 - 作用域:`openid email profile` - Cookie 父域:`example.com` - 保存。点击 *测试连接* 以确认发现。 ### 设置:Authelia 1. `configuration.yml` → `identity_providers.oidc.clients`: - id: argos secret: "$pbkdf2-sha512$..." redirect_uris: - https://argos.example.com/api/auth/oidc/callback scopes: [openid, email, profile] grant_types: [authorization_code] response_types: [code] authorization_policy: one_factor 2. 重启 Authelia。 3. argos /system → 单点登录:发行者 `https://auth.example.com`, 客户端 ID `argos`,客户端密钥(明文 — Authelia 自行哈希),Cookie 父域 `example.com`。 ### 设置:Keycloak 1. 创建 Realm(或重用现有 Realm)。 2. 客户端 → 创建客户端: - 客户端类型:OpenID Connect - 客户端 ID:argos - 客户端认证:启用 - 有效重定向 URI:`https://argos.example.com/api/auth/oidc/callback` 3. 凭据选项卡 → 复制客户端密钥。 4. argos:发行者 `https://keycloak.example.com/realms/`, 客户端 ID `argos`,客户端密钥,Cookie 父域 `example.com`。 ### 设置:Google OAuth 1. Google Cloud Console → API 与服务 → 凭据 → 创建凭据 → OAuth客户端 ID → Web 应用程序。 2. 授权重定向 URI: `https://argos.example.com/api/auth/oidc/callback` 3. 复制客户端 ID + 密钥。 4. argos:发行者 `https://accounts.google.com`,客户端 ID/密钥, 作用域:`openid email profile`,并且**关键**是将 **allowed_domains** 设置为你的组织域名 —— 否则任何使用 Google 登录的 Google 用户都会自动被创建账户。 ### 每个主机的 `auth_required` 切换 主机 → 表格行 → **Auth** 列 → 点击 🔓 / 🔒 徽章。该标志会持久化,Caddy 在 1 秒内协调,并且后续对该主机的每个请求都会先经过 `/api/auth/forward` 再到达上游。公共主机保持不变。 启用保护时: - 未认证请求 → 302 重定向到面板的 `/login`,并携带 `rd=` 参数指向原始 URL。 - 已认证请求 → 200,并携带 `X-Auth-User`、`X-Auth-Email`、`X-Auth-Name`、`X-Auth-Provider` 头部,这些头部会被复制到上游请求(后端可读取它们以个性化响应)。 ### 已知限制 / 注意事项 - **需要 Cookie 父域**:对于保护子域是必需的。若未设置,会话 Cookie 仅绑定到面板主机,因此任何不同子域上的受保护主机都无法获得 Cookie 并陷入 302 循环。 - **仅限子域**:每个受保护主机必须是所配置父域的子域。面板不支持“多租户”(即单个面板中配置两个独立的父域);Cookie 规范不允许单个 Cookie 覆盖两个同级域。 - **OIDC 用户绕过本地 TOTP**:在启用 OIDC 账户之前,请确认 IdP 已强制执行 MFA。 - **错误的 `ARGOS_MASTER_KEY` 会阻止面板启动**(VAPID 私钥和 OIDC 客户端密钥都无法解密)。 通过临时禁用 OIDC、清除客户端密钥、更新环境变量、重新保存配置来轮换密钥,以使加密重新生效。 - **用户名冲突:** 如果本地存在 `alice`,而新 OIDC 用户的 `preferred_username` 也是 `alice`,argos 会创建 `alice-oidc`。进一步的冲突会导致错误,提示操作员手动重命名。 ### API 接口 - `GET /api/auth/oidc/available` — 公开探测 `{enabled: bool}`。 - `GET /api/auth/oidc/login?rd=` — 302 跳转到 IdP 并启用 PKCE。 - `GET /api/auth/oidc/callback` — 交换并更新会话。 - `GET /api/auth/oidc/status`(需认证) — 脱敏后的配置。 - `PUT /api/auth/oidc/config`(需认证) — 合并并重新验证。 - `POST /api/auth/oidc/test`(需认证) — 仅用于探测发现。 - `GET /api/auth/forward` — Caddy ForwardAuth 端点。 - `GET /api/auth/safe-redirect?rd=` — 防开放重定向的安全 URL。 ## 架构 参见 [ARCHITECTURE.md](./ARCHITECTURE.md)。 ## 路线图 参见 ARCHITECTURE.md 中的分阶段路线图。当前处于阶段 0。 ## 许可证 argos-edge 根据 [商业源码许可证 1.1](LICENSE) 授权。 - **免费用于:** 个人使用、非商业使用、内部业务使用、社区贡献、自托管部署。 - **不允许:** 将 argos-edge 作为托管的商业反向代理、WAF 或应用网关服务提供给第三方。 - **将于 2030-04-20 转为 Apache 2.0 许可证。** 如需商业许可咨询,请打开议题或联系维护者。
标签:Caddy, Caddy 反向代理, Coraza, Coraza WAF, CrowdSec, CrowdSec 社区威胁情报, DNS通配符暴力破解, Edge Computing, EVTX分析, Go, HomeLab, Homelab Gateway, HTTP/3, Let's Encrypt, Load Balancer, React, Ruby工具, Self-hosted Proxy, Self-hosted WAF, SQLite, SSO, SSO 统一认证, Syscalls, Tailwind, TypeScript, WAF, 单面板, 反向代理, 反向代理+WAF+负载均衡, 威胁情报, 安全插件, 家庭实验室, 开发者工具, 开源网关, 日志审计, 生产就绪, 统一控制面板, 自托管, 负载均衡, 边缘网关