feat(ops): ADR-090-B 零信任收尾範本 — wrapper / sudoers / migrator / CI
2026-04-18 台北時區 —— ogt + Claude Opus 4.7 (1M) 本 commit 響應本 Session 兩次憑證外洩事故 (feedback_secrets_leak_incidents_2026-04-18.md), 交付統帥可直接部署的零信任基礎設施範本. 檔案清單: 1. scripts/host-ops/awoooi-hosts-add.sh - 110 主機 /etc/hosts 白名單 wrapper - 只允許預定義主機名,idempotent,帶 IP 格式驗證 - 安裝: /usr/local/bin/awoooi-hosts-add (root:root 0755) 2. scripts/host-ops/awoooi-wrapper.sudoers - 配套 sudoers 規則 (NOPASSWD for wrapper + SIGHUP only) - 安裝: /etc/sudoers.d/awoooi-wrapper (root:root 0440) - 禁 tee / bash / sh 這類 generic shell access 3. apps/api/migrations/adr090b_awoooi_migrator_role.sql - PG 限權角色 awoooi_migrator - 只能 DDL (CREATE/ALTER/DROP/INDEX/COMMENT) - 明確 REVOKE 所有 DML + default privileges 鎖死 - 本檔由統帥執行 (需 superuser),不由 Claude 執行 4. k8s/awoooi-prod/awoooi-migrator-secret.template.yaml - K8s Secret patch 範本 - 新增 MIGRATION_DATABASE_URL key (awoooi_migrator 連線串) - 與應用 DATABASE_URL 拆開 5. .gitea/workflows/run-migration.yml - CI 自動套用新 migration (單 transaction + ON_ERROR_STOP) - 用 Gitea secret MIGRATION_DATABASE_URL,不走明碼 - 每次成功寫一筆 asset_discovery_run (audit trail) 零信任三層防線 (對應 feedback_secrets_leak_incidents): L1 對話無密碼 -> wrapper 內建白名單 L2 操作經 wrapper -> sudoers + awoooi_migrator L3 顯示強制遮蔽 -> CI 走 secret,不走 env 本 Session 發現的 3 次憑證外洩全部在 feedback_secrets_leak memory 登記,並有對應 P0 輪替計畫. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
68
scripts/host-ops/awoooi-hosts-add.sh
Normal file
68
scripts/host-ops/awoooi-hosts-add.sh
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
# AWOOOI Hosts White-list Wrapper (ADR-090)
|
||||
# 建立時間: 2026-04-18 台北時區
|
||||
# 建立者: ogt + Claude Opus 4.7 (1M)
|
||||
#
|
||||
# 目的: 取代「AI 有全域 /etc/hosts sudo 權限」的安全破口
|
||||
# 只允許預定義白名單主機名被寫入,且 idempotent 不重複
|
||||
#
|
||||
# 安裝位置: /usr/local/bin/awoooi-hosts-add
|
||||
# 安裝權限: root:root 0755
|
||||
# 呼叫方式 (需搭配 sudoers): sudo /usr/local/bin/awoooi-hosts-add <IP> <HOSTNAME>
|
||||
#
|
||||
# 例: sudo /usr/local/bin/awoooi-hosts-add 114.32.151.246 mo.wooo.work
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── 白名單 ───────────────────────────────────────────────────────────────
|
||||
# 新增主機名到這裡,需統帥審查並 git commit
|
||||
ALLOWED_HOSTS=(
|
||||
"mo.wooo.work"
|
||||
"aiops.wooo.work"
|
||||
"bitan.wooo.work"
|
||||
"stock.wooo.work"
|
||||
"tsenyang.com"
|
||||
"www.tsenyang.com"
|
||||
)
|
||||
|
||||
# ─── 參數驗證 ─────────────────────────────────────────────────────────────
|
||||
if [[ $# -ne 2 ]]; then
|
||||
echo "Usage: $0 <IP> <HOSTNAME>" >&2
|
||||
echo "Whitelist: ${ALLOWED_HOSTS[*]}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IP="$1"
|
||||
HOST="$2"
|
||||
|
||||
# IP 格式驗證 (基本 IPv4)
|
||||
if [[ ! "$IP" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||
echo "Invalid IP format: $IP" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# 主機名白名單檢查
|
||||
ALLOWED=0
|
||||
for allowed in "${ALLOWED_HOSTS[@]}"; do
|
||||
if [[ "$HOST" == "$allowed" ]]; then
|
||||
ALLOWED=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $ALLOWED -eq 0 ]]; then
|
||||
echo "Host not whitelisted: $HOST" >&2
|
||||
echo "Contact statesman to update script whitelist + git commit." >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# ─── Idempotent 寫入 ──────────────────────────────────────────────────────
|
||||
# 若 /etc/hosts 已有此主機名 (不限 IP),視為已設定,不重複寫
|
||||
if grep -qE "^[0-9.]+[[:space:]]+${HOST}\$" /etc/hosts; then
|
||||
echo "Host $HOST already in /etc/hosts, no change."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 寫入 (原子 append)
|
||||
echo "$IP $HOST" >> /etc/hosts
|
||||
echo "Added: $IP $HOST to /etc/hosts"
|
||||
27
scripts/host-ops/awoooi-wrapper.sudoers
Normal file
27
scripts/host-ops/awoooi-wrapper.sudoers
Normal file
@@ -0,0 +1,27 @@
|
||||
# AWOOOI L4 自動化代理人最小權限 sudoers (ADR-090)
|
||||
# 建立時間: 2026-04-18 台北時區
|
||||
# 建立者: ogt + Claude Opus 4.7 (1M)
|
||||
#
|
||||
# 安裝位置: /etc/sudoers.d/awoooi-wrapper
|
||||
# 安裝權限: root:root 0440
|
||||
# 安裝前驗證: sudo visudo -c -f /path/to/this/file
|
||||
#
|
||||
# 設計原則:
|
||||
# - 以 command path 精確指定,不開 tee / bash / sh 這類 generic shell
|
||||
# - /etc/hosts 經 awoooi-hosts-add wrapper 白名單限制主機名
|
||||
# - docker kill 只允許 SIGHUP (reload signal),不允許 SIGTERM/KILL
|
||||
# - 不放 systemctl / apt / reboot / shutdown 任何系統級指令
|
||||
|
||||
# 1. /etc/hosts 白名單式寫入 (wrapper 自己驗證主機名)
|
||||
wooo ALL=(root) NOPASSWD: /usr/local/bin/awoooi-hosts-add
|
||||
|
||||
# 2. Prometheus / Blackbox / Alertmanager config reload (SIGHUP only)
|
||||
wooo ALL=(root) NOPASSWD: /usr/bin/docker kill -s SIGHUP prometheus
|
||||
wooo ALL=(root) NOPASSWD: /usr/bin/docker kill -s SIGHUP blackbox-exporter
|
||||
wooo ALL=(root) NOPASSWD: /usr/bin/docker kill -s SIGHUP alertmanager
|
||||
|
||||
# 3. Prometheus / Alertmanager config 檔驗證 (只讀,防禦性)
|
||||
wooo ALL=(root) NOPASSWD: /usr/bin/docker exec prometheus promtool check config /etc/prometheus/prometheus.yml
|
||||
wooo ALL=(root) NOPASSWD: /usr/bin/docker exec alertmanager amtool check-config /etc/alertmanager/alertmanager.yml
|
||||
|
||||
# 註: 未來新增命令必經 git commit 的 PR review,不可直接手動加
|
||||
Reference in New Issue
Block a user