# 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 已授權。