155 lines
4.1 KiB
Markdown
155 lines
4.1 KiB
Markdown
# tohka 上接入 Pocket ID / TinyAuth / Caddy 的推荐做法
|
||
|
||
这份文档记录当前项目在 `tohka` 上最推荐的后台保护方式:
|
||
|
||
```text
|
||
Browser
|
||
-> Host Caddy
|
||
-> TinyAuth
|
||
-> Pocket ID (OIDC)
|
||
-> admin nginx
|
||
-> backend /api
|
||
```
|
||
|
||
## 1. 目标
|
||
|
||
实现这些效果:
|
||
|
||
- `blog.init.cool` 对外公开,走 frontend SSR
|
||
- `admin.blog.init.cool` 整体受保护
|
||
- admin 页面和它访问的 `/api/*` 同域
|
||
- backend 信任 TinyAuth 注入的登录身份
|
||
- 即使 backend 端口误暴露,也额外要求一个共享密钥头,降低伪造 `Remote-User` 风险
|
||
|
||
## 2. 推荐使用的 compose 方式
|
||
|
||
基础 compose:
|
||
|
||
- `deploy/docker/compose.package.yml`
|
||
|
||
在 tohka 上再叠加这个 override:
|
||
|
||
- `deploy/docker/compose.tohka.override.yml`
|
||
|
||
部署主配置源建议使用:
|
||
|
||
- `deploy/docker/config.yaml`
|
||
|
||
启动方式:
|
||
|
||
```bash
|
||
python deploy/scripts/render_compose_env.py \
|
||
--input deploy/docker/config.yaml \
|
||
--output deploy/docker/.env
|
||
|
||
docker compose \
|
||
-f deploy/docker/compose.package.yml \
|
||
-f deploy/docker/compose.tohka.override.yml \
|
||
--env-file deploy/docker/.env up -d
|
||
```
|
||
|
||
这个 override 会做三件事:
|
||
|
||
1. `frontend / admin / backend` 只绑定到 `127.0.0.1`
|
||
2. 默认打开 `TERMI_ADMIN_TRUST_PROXY_AUTH=true`
|
||
3. 默认关闭 `TERMI_ADMIN_LOCAL_LOGIN_ENABLED`
|
||
|
||
## 3. `config.yaml -> compose_env` 里最关键的变量
|
||
|
||
至少补这些:
|
||
|
||
现在推荐直接从下面这个模板开始:
|
||
|
||
- `deploy/docker/config.yaml.example`
|
||
|
||
然后复制成:
|
||
|
||
- `deploy/docker/config.yaml`
|
||
|
||
至少补这些:
|
||
|
||
```yaml
|
||
compose_env:
|
||
APP_BASE_URL: https://admin.blog.init.cool
|
||
PUBLIC_API_BASE_URL: https://api.blog.init.cool
|
||
ADMIN_API_BASE_URL: https://admin.blog.init.cool
|
||
ADMIN_FRONTEND_BASE_URL: https://blog.init.cool
|
||
|
||
TERMI_ADMIN_TRUST_PROXY_AUTH: true
|
||
TERMI_ADMIN_LOCAL_LOGIN_ENABLED: false
|
||
TERMI_ADMIN_PROXY_SHARED_SECRET: replace-with-a-long-random-secret
|
||
```
|
||
|
||
说明:
|
||
|
||
- `APP_BASE_URL` 建议填后台正式地址,便于后端生成后台相关链接
|
||
- `TERMI_ADMIN_PROXY_SHARED_SECRET` 是 backend 和 Caddy 之间约定的共享密钥
|
||
- backend 现在会在代理 SSO 模式下检查 `X-Termi-Proxy-Secret`
|
||
|
||
## 4. Caddy 侧应该怎么配
|
||
|
||
直接参考:
|
||
|
||
- `deploy/caddy/Caddyfile.tohka.example`
|
||
- `deploy/caddy/Caddyfile.tohka.production.example`
|
||
|
||
关键点是:admin 域名下 `/api/*` 反代到 backend 时要带上:
|
||
|
||
```caddy
|
||
header_up X-Termi-Proxy-Secret {$TERMI_ADMIN_PROXY_SHARED_SECRET}
|
||
```
|
||
|
||
这样 backend 才会接受代理注入的:
|
||
|
||
- `Remote-User`
|
||
- `Remote-Email`
|
||
- `Remote-Groups`
|
||
|
||
## 5. 为什么要加共享密钥头
|
||
|
||
如果只看 `Remote-User` 这类头,而 backend 又被公网直接访问,
|
||
理论上别人可以手工伪造请求头来冒充后台用户。
|
||
|
||
现在的建议闭环是:
|
||
|
||
- backend 端口只监听 `127.0.0.1`
|
||
- admin 域名入口必须经过 TinyAuth / Pocket ID
|
||
- backend 额外校验 `X-Termi-Proxy-Secret`
|
||
|
||
这样会稳很多。
|
||
|
||
## 6. 后台登录页现在的行为
|
||
|
||
当前逻辑:
|
||
|
||
- 如果 `TERMI_ADMIN_LOCAL_LOGIN_ENABLED=true`,仍可用本地账号密码兜底
|
||
- 如果关闭本地登录,admin 登录页会提示“请从受保护入口进入,并重新检查会话”
|
||
- backend 会优先读取代理身份头
|
||
|
||
## 7. 建议的 tohka 落地顺序
|
||
|
||
1. 在 tohka 的大 Caddyfile 里接入 `admin.blog.init.cool`
|
||
2. 给 admin 域名启用 `import tinyauth`
|
||
3. `/api/*` 同域转发到 `localhost:5150`
|
||
4. 加上 `X-Termi-Proxy-Secret`
|
||
5. 用 `compose.tohka.override.yml` 启动容器
|
||
6. 打开 `https://admin.blog.init.cool`
|
||
7. 在后台里确认当前 session 的 `auth_source=proxy`
|
||
|
||
完整部署步骤可再配合:
|
||
|
||
- `deploy/docker/TOHKA_DEPLOY_RUNBOOK.md`
|
||
|
||
## 8. digest / retry / 备份建议一起启用
|
||
|
||
上线时建议连同这些一起启用:
|
||
|
||
- `deploy/systemd/termi-retry-deliveries.timer`
|
||
- `deploy/systemd/termi-weekly-digest.timer`
|
||
- `deploy/systemd/termi-monthly-digest.timer`
|
||
- `deploy/systemd/termi-backup-all.timer`
|
||
- `deploy/systemd/termi-backup-prune.timer`
|
||
- `deploy/systemd/termi-backup-offsite-sync.timer`
|
||
|
||
这样后台保护、通知投递、备份恢复三件事才算闭环。
|