feat(security): 建立 Nginx 只讀漂移偵測器 [skip ci]
This commit is contained in:
@@ -1,3 +1,34 @@
|
||||
## 2026-06-11|IwoooS Nginx 只讀漂移偵測器 repo-only 第一波
|
||||
|
||||
**背景**:接續高價值配置控管清冊,P0 下一步是先把 Nginx 這個最容易被手動改動的公開入口配置做成可重跑的只讀漂移偵測框架。使用者已要求 Nginx 必須有資安機制控管;本階段仍不 SSH、不讀 live、不 reload、不修改主機。
|
||||
|
||||
**完成內容:**
|
||||
- 新增 `scripts/security/nginx-config-drift-detector.py`,只讀解析 repo 內 Nginx source-of-truth,輸出 raw / normalized SHA-256、`server_name`、`listen`、`proxy_pass`、TLS certificate path、admin route、ACME route 與 WebSocket route。
|
||||
- 新增 `docs/security/NGINX-CONFIG-DRIFT-DETECTOR.md`,記錄 detector 用法、判讀規則、owner-provided live file compare 模式與禁止事項。
|
||||
- 新增 `docs/security/nginx-config-drift-repo.snapshot.json`,固定 repo-only snapshot;目前覆蓋 `host188_all_sites`、`host188_internal_tools_https`、`host110_ollama_proxy` 三份 source template。
|
||||
- 更新 `docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md`:repo-only Nginx detector 完成度 `100%`,owner-provided live file compare 格式 `70%`,live evidence collection 仍 `0%`。
|
||||
|
||||
**本地驗證:**
|
||||
- `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` 通過。
|
||||
- `python3 -m json.tool docs/security/nginx-config-drift-repo.snapshot.json` 通過。
|
||||
- `python3 -m py_compile scripts/security/nginx-config-drift-detector.py` 通過。
|
||||
- detector compare smoke 通過:使用 `host110_ollama_proxy=infra/ansible/roles/nginx/templates/110-ollama-proxy.conf.j2` 作為 owner-provided live file,回傳 `live_input_count=1`、`drift_detected_count=0`。
|
||||
- repo-only snapshot 摘要:`source_config_count=3`、`live_input_count=0`、`drift_detected_count=0`、`live_evidence_collected=false`。
|
||||
- `python3 scripts/security/security-mirror-progress-guard.py --root .` 通過。
|
||||
- `python3 scripts/security/source-control-owner-response-guard.py --root .` 通過。
|
||||
- `node scripts/ci/check-gitea-step-env-secrets.js` 通過。
|
||||
- `python3 scripts/ops/doc-secrets-sanity-check.py docs .gitea` 通過,`scanned_files=640`。
|
||||
- `git diff --check` 通過。
|
||||
- P0 高風險字串掃描通過:關閉 SSH host key 驗證的逐字參數、舊 Gitea token、Grafana 密碼常值、舊 MinIO credential、舊 MinIO token、Prometheus inline bearer token 均未命中。
|
||||
|
||||
**完成度與邊界:**
|
||||
- Nginx repo source-of-truth 指紋:`100%`。
|
||||
- domain / upstream / TLS / admin / ACME / WebSocket 摘要:`100%`。
|
||||
- owner-provided live file compare 格式:`70%`,已支援手動提供 live conf 檔,不主動取得 live。
|
||||
- live Nginx evidence collection:`0%`;本階段未 SSH、未 Ansible check-mode、未讀 live hash。
|
||||
- Nginx `nginx -t`、reload、restart、DNS 修改、TLS renew、主機寫入、runtime gate:全部未執行。
|
||||
- IwoooS 整體仍維持 `64%`;active runtime gate 仍為 `0`;owner response received / accepted 仍為 `0 / false`。
|
||||
|
||||
## 2026-06-11|IwoooS 高價值配置控管清冊與 P0 source-control 止血
|
||||
|
||||
**背景**:使用者要求所有重要配置都要納入資安控管,特別指出 Nginx 常被手動變更,必須建立資安機制。同時需完整盤點哪些配置要先納管、哪些既有規範不符合現在要求、哪些需要新增或調整。
|
||||
|
||||
@@ -126,14 +126,16 @@ Nginx 是目前必須最先資安控管的配置,原因是它同時控制公
|
||||
| 重要配置範圍盤點 | `100%` | 已建立 C0-C3 分級與總清單 |
|
||||
| Nginx 控管機制定義 | `100%` | 已定義 source-of-truth、live path、gate、drift 原則 |
|
||||
| source-control P0 止血 | `100%` | 已清掉本波掃到的 token 範例、Grafana 密碼常值與 SSH host key 關閉 |
|
||||
| live Nginx drift detector | `0%` | 尚未 SSH / Ansible check-mode / live hash;需 owner 與維護窗口規則 |
|
||||
| repo-only Nginx drift detector | `100%` | 已新增 `scripts/security/nginx-config-drift-detector.py` 與 repo source-of-truth snapshot |
|
||||
| owner-provided live Nginx file compare | `70%` | 工具可吃 owner 匯出的 live conf 檔比較;本階段不主動 SSH 取得 |
|
||||
| live Nginx evidence collection | `0%` | 尚未 SSH / Ansible check-mode / live hash;需 owner 與維護窗口規則 |
|
||||
| live Nginx reload / restart | `0%` | 未授權,未執行 |
|
||||
| DNS / TLS live validation | `0%` | 本階段未跑 live probe;若下一階段改前端或 route,需 desktop / mobile / route smoke |
|
||||
| cross-product owner response | `0%` | 尚未收到 VibeWork、agent-bounty-protocol、StockPlatform 等 owner acceptance |
|
||||
|
||||
## 7. 下一階段優先順序
|
||||
|
||||
1. P0:建立 Nginx 只讀 drift detector 草案,輸出 repo-rendered hash、live hash、affected domain / upstream / TLS / admin route,不自動覆寫。
|
||||
1. P0:由 owner 提供脫敏 live Nginx conf 匯出檔,重跑 compare mode;不自動覆寫、不 reload。
|
||||
2. P0:補 DNS / TLS / certbot domain inventory,先只讀,不 renew、不 reload。
|
||||
3. P0:把 workflow / runner / secret name owner response 與高價值配置 C0 gate 串成同一個 IwoooS 狀態。
|
||||
4. P1:盤點 110 / 188 Docker Compose 與 systemd live config,標記 Harbor、Sentry、Langfuse、Gitea、agent-bounty-protocol 影響面。
|
||||
|
||||
81
docs/security/NGINX-CONFIG-DRIFT-DETECTOR.md
Normal file
81
docs/security/NGINX-CONFIG-DRIFT-DETECTOR.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# 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%` | 未授權且未執行 |
|
||||
1106
docs/security/nginx-config-drift-repo.snapshot.json
Normal file
1106
docs/security/nginx-config-drift-repo.snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user