feat(adr-076): Task 2.2 + 2.3 — 規則擴充 + kubectl 注入防護
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled

Task 2.2: alert_rules.yaml 新增 3 類規則 (priority 125-127)
  - gitea_down: Gitea CI/CD 下線 → NO_ACTION (priority 125, critical)
  - ssl_cert_expiring: SSL 憑證到期 → NO_ACTION (priority 126, medium)
  - external_site_down: MoWoooWork/Dev/Blackbox probe → NO_ACTION (priority 127, medium)
  規則總數: 21 → 24

Task 2.3: alert_rule_engine.py kubectl 注入防護
  - _RULE_ENGINE_DESTRUCTIVE_RE: 阻擋 delete pvc/namespace/statefulset/deployment,
    drain/cordon, --replicas=0, rm -rf, DROP TABLE, $() 反引號
  - validate_kubectl_command(): 公開 API,SSH 指令/空字串直接通過
  - match_rule() 整合: 變數替換後驗證,阻擋時清空 + log warning
  - test_alert_rule_engine_validation.py: 34 tests (100% 通過)

測試: 776 passed, 26 skipped, 0 failed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-14 15:10:10 +08:00
parent be2ec4d761
commit cc42aa0bdb
3 changed files with 298 additions and 1 deletions

View File

@@ -43,6 +43,51 @@ _generating: set[str] = set()
# Redis 分散式鎖 TTL (秒),覆蓋 Ollama + Gemini 最長生成時間
_RULE_GEN_LOCK_TTL = 120
# ── kubectl 注入防護 (Task 2.3, ADR-076, 2026-04-14) ─────────
# 對齊 auto_approve._DESTRUCTIVE_PATTERNS + decision_manager._ALLOWED_KUBECTL_PATTERN
# 目標: 規則 YAML 中的 kubectl_command 在變數替換後若含下列破壞性模式 → 清空並告警
_RULE_ENGINE_DESTRUCTIVE_RE = re.compile(
r"(kubectl\s+delete\s+(pvc|namespace|statefulset|deployment)" # 破壞性 K8s 刪除
r"|kubectl\s+(drain|cordon)" # 節點驅逐/封鎖
r"|--replicas=\s*0\b" # 縮容至零
r"|rm\s+-[rf]{1,2}\s" # rm -rf
r"|\bdrop\s+(table|database)\b" # SQL 破壞性 DDL
r"|\$\([^)]{0,200}\)" # shell 命令替換 $(...)
r"|`[^`]{0,200}`" # 反引號替換
r")",
re.IGNORECASE,
)
# ── kubectl 注入防護 公開 API ───────────────────────────────
def validate_kubectl_command(command: str) -> bool:
"""
kubectl 注入安全驗證Task 2.3, ADR-076
Returns:
True — 指令安全,可執行
False — 含破壞性模式,呼叫方應清空指令並記錄 warning
通過條件(直接 True:
- 空字串 — 無動作規則
- "ssh ..." 開頭 — SSH 層指令,不走 kubectl 路徑
阻擋條件(返回 False:
- kubectl delete pvc/namespace/statefulset/deployment — 破壞性刪除
- kubectl drain / cordon — 節點驅逐(業務衝擊)
- --replicas=0 — 縮容至零(服務停止)
- rm -rf — 主機層破壞
- DROP TABLE/DATABASE — SQL 破壞性 DDL
- $(...) 或反引號 — Shell 命令注入
"""
if not command:
return True
if command.strip().startswith("ssh "):
return True
return not bool(_RULE_ENGINE_DESTRUCTIVE_RE.search(command))
# ── 變數提取 ────────────────────────────────────────────────
@@ -211,12 +256,23 @@ def match_rule(alert_context: dict) -> dict[str, Any] | None:
for o in resp.get("optimization", [])
]
# Task 2.3: kubectl 注入防護 — 變數替換後驗證,阻擋破壞性模式
kubectl_command = _fill(resp.get("kubectl_command", ""), vars)
if not validate_kubectl_command(kubectl_command):
logger.warning(
"rule_kubectl_command_blocked",
rule_id=matched_rule["id"],
reason="destructive_pattern_detected",
command_snippet=kubectl_command[:80],
)
kubectl_command = ""
return {
"rule_id": matched_rule["id"],
"action_title": _fill(resp["action_title"], vars),
"description": _fill(resp["description"], vars),
"suggested_action": resp["suggested_action"],
"kubectl_command": _fill(resp["kubectl_command"], vars),
"kubectl_command": kubectl_command,
"target_resource": vars["target"],
"namespace": vars["namespace"],
"risk_level": risk,