88 lines
3.7 KiB
Markdown
88 lines
3.7 KiB
Markdown
# Nginx 配置只讀漂移偵測器
|
||
|
||
| 項目 | 內容 |
|
||
|------|------|
|
||
| 日期 | 2026-06-11 |
|
||
| 狀態 | `repo_only_detector_ready` |
|
||
| 工具 | `scripts/security/nginx-config-drift-detector.py` |
|
||
| Snapshot | `docs/security/nginx-config-drift-repo.snapshot.json` |
|
||
| runtime gate | `0` |
|
||
|
||
## 1. 目的
|
||
|
||
本工具把 Nginx 從「靠人記得不要手改」推進到「有可重跑的 source-of-truth 指紋與後續 live 比對格式」。目前只讀 repo 內配置,不 SSH、不 reload、不修改主機。
|
||
|
||
## 2. 已納管 source-of-truth
|
||
|
||
| config id | 主機 | repo source | live path | 等級 |
|
||
|-----------|------|-------------|-----------|------|
|
||
| `host188_all_sites` | `192.168.0.188` | `infra/ansible/roles/nginx/templates/188-all-sites.conf.j2` | `/etc/nginx/sites-enabled/all-sites.conf` | C0 |
|
||
| `host188_internal_tools_https` | `192.168.0.188` | `infra/ansible/roles/nginx/templates/188-internal-tools-https.conf.j2` | 待 owner 確認 | C0 |
|
||
| `host110_ollama_proxy` | `192.168.0.110` | `infra/ansible/roles/nginx/templates/110-ollama-proxy.conf.j2` | `/etc/nginx/sites-enabled/110-ollama-proxy.conf` | C1 |
|
||
|
||
## 3. 可產出的證據
|
||
|
||
工具會輸出:
|
||
|
||
1. repo raw / normalized SHA-256。
|
||
2. `server_name` 清單。
|
||
3. `listen` 清單。
|
||
4. `proxy_pass` upstream 清單。
|
||
5. TLS certificate / key path 清單。
|
||
6. `/admin` route、ACME challenge route、WebSocket route。
|
||
7. live conf 若由 owner 提供,會比較 normalized hash、server name、upstream 與 TLS path 差異。
|
||
|
||
## 4. 指令
|
||
|
||
repo-only snapshot:
|
||
|
||
```bash
|
||
python3 scripts/security/nginx-config-drift-detector.py \
|
||
--root . \
|
||
--generated-at 2026-06-11T12:00:00+08:00 \
|
||
--output docs/security/nginx-config-drift-repo.snapshot.json
|
||
```
|
||
|
||
未來 owner 提供 live conf 匯出檔後,可用比較模式:
|
||
|
||
```bash
|
||
python3 scripts/security/nginx-config-drift-detector.py \
|
||
--root . \
|
||
--live-file host188_all_sites=/path/to/redacted-live-188-all-sites.conf \
|
||
--live-file host110_ollama_proxy=/path/to/redacted-live-110-ollama-proxy.conf
|
||
```
|
||
|
||
## 5. 判讀規則
|
||
|
||
| 狀態 | 意義 | 可做事項 |
|
||
|------|------|----------|
|
||
| `repo_only_no_live_evidence` | 只有 repo source-of-truth 指紋,尚未比較 live | 可作為 owner request packet,不能宣稱 live 無漂移 |
|
||
| `matched` | owner 提供的 live 檔與 repo normalized hash / 語意比對一致 | 可記 evidence,仍不代表 reload 已授權 |
|
||
| `drift_detected` | live 與 repo 出現 hash 或語意差異 | 建立 P0 drift evidence 與 owner decision,不自動覆寫 live |
|
||
| `live_file_missing` | 指定的 live 匯出檔不存在 | 要求補件,不做判斷 |
|
||
|
||
## 6. 邊界
|
||
|
||
1. 本工具不執行 SSH。
|
||
2. 本工具不執行 `nginx -t`。
|
||
3. 本工具不 reload / restart Nginx。
|
||
4. 本工具不讀 TLS private key 內容。
|
||
5. 本工具不收 secret value。
|
||
6. 本工具不開 runtime gate。
|
||
|
||
## 7. 完成度
|
||
|
||
| 工作 | 完成度 | 說明 |
|
||
|------|--------|------|
|
||
| repo source-of-truth 指紋 | `100%` | 已覆蓋三份 Nginx source templates |
|
||
| domain / upstream / TLS / admin / ACME 摘要 | `100%` | 已由 parser 產出 |
|
||
| owner-provided live file 比對格式 | `70%` | 支援手動提供 live conf 檔,不主動取得 live |
|
||
| live Nginx 證據收集 | `0%` | 本階段不 SSH、不讀主機 |
|
||
| Nginx reload / restart | `0%` | 未授權且未執行 |
|
||
|
||
## 8. Preflight 銜接
|
||
|
||
`docs/security/PUBLIC-GATEWAY-PREFLIGHT-INVENTORY.md` 會消費本工具與 DNS / TLS 清冊的 repo-only 結果,固定 Nginx reload / route change 前必備的 owner、live conf、rendered diff、`nginx -t`、route smoke、maintenance window 與 rollback owner 欄位。
|
||
|
||
此銜接仍不代表 live conf 已收、drift 已判定、`nginx -t` 已執行或 reload 已授權。
|