healert-io/agent

GitHub: healert-io/agent

一款 Kubernetes 审计日志摩擦检测代理,用于识别平台操作绕过行为并通过 Backstage 插件以摩擦分数和热力图形式可视化展示。

Stars: 0 | Forks: 0

# Healert Agent **适用于 Healert Friction Intelligence Platform 的 Kubernetes audit log 摩擦检测 agent。** 持续追踪 Kubernetes audit log,根据可配置的规则检测平台绕过事件, 并将摩擦事件发送至自托管的 Healert 后端。通过 `@backstage-community/plugin-healert` 在 Backstage 中以 各服务的 Friction Scores(摩擦分数)和 Heatmaps(热力图)的形式展示。 [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Version](https://img.shields.io/badge/version-0.1.1-green.svg)](https://github.com/healert/agent/releases) [![Go](https://img.shields.io/badge/Go-1.22+-blue.svg)](https://golang.org) ## 概述 ``` Kubernetes Audit Log (/var/log/k3s-audit.log) | NDJSON events, tailed from EOF — one line at a time v Healert Go Agent <- this repo isInternalSystemActor() filter controllers, detect human operators matchRules() evaluate all rules (AND logic per rule) send() POST /events with API key auth | v Healert Backend github.com/healert/backend FastAPI + SQLite Exponential decay scoring | v Backstage Plugin @backstage-community/plugin-healert FrictionScoreCard + FrictionHeatmap per catalog entity ``` 该 agent 是一个**没有外部依赖的单一 Go 二进制文件**。 它可以作为**本地进程**(开发环境)或 **Kubernetes DaemonSet**(生产环境)运行。 ## 仓库结构 ``` healert-agent/ | +-- main.go Go agent — 1,498 lines, zero external dependencies | 9 sections: | 1. Configuration env var loading and validation | 2. Rule Types Rule, RuleMatch, RulesConfig structs | 3. Rules Loader YAML parser, validator, config block | 4. Audit Types AuditEvent, FrictionEvent structs | 5. Detection isInternalSystemActor, matchRule, | matchRules, normaliseWorkloadName | 6. Description renderDescription, sanitiseLogValue | 7. Backend Client send(), healthCheck(), 10s timeout | 8. Log Tailer tailLog(), processLine(), bufio.Reader | 9. Entry Point main(), banner, health check | +-- rules.yaml Detection rules — 520 lines | config block: global ignore_namespaces | 5 active rules + 10+ optional rules | Rule types: TYPE 1 workload, TYPE 2 shared resource, | TYPE 3 cluster, TYPE 4 network, TYPE 5 storage | +-- healert.sh Management script — 2,788 lines, 17 commands | start [backend|agent|kubernetes] | stop [backend|agent|kubernetes] | update kubernetes | configure [--audit-log|--rules|--namespace] | configure scoring [--threshold|--half-life|--retention] | validate, restart, reset, status, logs, test, version, help | +-- Dockerfile Multi-stage distroless build — 255 lines | Stage 1: golang:1.22-alpine (builder) | Stage 2: gcr.io/distroless/static:nonroot (final) | Result: ~25MB, no shell, uid=65532 | Features: OCI labels, multi-arch, private registry support | +-- daemonset.yaml Kubernetes DaemonSet — 388 lines | Resources: Namespace, ServiceAccount, NetworkPolicy, DaemonSet | Security: nonroot uid=65532, readOnlyRootFilesystem, drop ALL | Features: K8S_NAMESPACE Downward API, system-node-critical priority | 30s termination grace period, rolling update strategy | | +-- example.audit-policy.yaml (Tells the Kubernetes API server which events to write to the audit log and at what detail level.) | | +-- go.mod Go module (zero external dependencies) | +-- .env.example Configuration template | +-- LICENSE Apache-2.0, Copyright 2026 Healert OU ``` ## 前置条件 | 要求 | 版本 | 说明 | |---|---|---| | Go | 1.22+ | 编译 agent 二进制文件 | | Python 3 | 3.8+ | 后端 runtime(由 healert.sh 管理) | | pip | 任意 | Python 包管理器 | | curl | 任意 | 健康检查和 API 调用 | | Kubernetes | 任意 | k3s, kubeadm, EKS, GKE, AKS | | Audit logging | 已启用 | 请参阅“Audit Log 设置”部分 | ## 快速开始 ``` # 1. 克隆并编译 git clone https://github.com/healert/agent.git cd agent go build -o healert-agent main.go # 2. 配置目录 ./healert.sh init # 3. 检查依赖 ./healert.sh deps # 4. 生成 API key 并配置双方 ./healert.sh setup # 5. 设置审计日志路径 (k3s) ./healert.sh configure --audit-log /var/log/k3s-audit.log Note: if the audit log file is not found sudo touch /var/log/k3s-audit.log sudo chmod 644 /var/log/k3s-audit.log # 6. 验证规则 ./healert.sh validate # 7. 启动后端和 agent ./healert.sh start # 8. 验证 pipeline ./healert.sh test ``` ## Audit Log 设置 ### k3s ``` # 创建审计策略 sudo mkdir -p /etc/k3s sudo cp example.audit-policy.yaml /etc/k3s/audit-policy.yaml # 启用审计日志 sudo mkdir -p /etc/systemd/system/k3s.service.d sudo tee /etc/systemd/system/k3s.service.d/audit.conf << CONF [Service] ExecStart= ExecStart=/usr/local/bin/k3s server \ --kube-apiserver-arg=audit-log-path=/var/log/k3s-audit.log \ --kube-apiserver-arg=audit-policy-file=/etc/k3s/audit-policy.yaml \ --kube-apiserver-arg=audit-log-maxage=7 \ --kube-apiserver-arg=audit-log-maxbackup=3 \ --kube-apiserver-arg=audit-log-maxsize=100 CONF sudo systemctl daemon-reload sudo systemctl restart k3s sleep 15 # 设置权限 sudo groupadd healert 2>/dev/null || true sudo usermod -aG healert $USER sudo chown root:healert /var/log/k3s-audit.log sudo chmod 640 /var/log/k3s-audit.log ``` ### kubeadm ``` # 在 spec.containers.command 下的 kube-apiserver.yaml 中添加: # - --audit-log-path=/var/log/kubernetes/audit/audit.log # - --audit-policy-file=/etc/kubernetes/audit-policy.yaml ``` ## 命令参考 ### 本地模式 | 命令 | 描述 | |---|---| | `./healert.sh init` | 配置后端和 agent 目录 | | `./healert.sh deps` | 检查并安装所有依赖 | | `./healert.sh setup` | 生成 API key,并配置两端 | | `./healert.sh setup rotate` | 轮换现有的 API key | | `./healert.sh configure` | 以交互方式更新 agent 设置 | | `./healert.sh configure --audit-log PATH` | 设置 audit log 路径 | | `./healert.sh configure --rules PATH` | 设置 rules.yaml 路径 | | `./healert.sh configure --namespace NS` | 设置 Backstage entity namespace | | `./healert.sh configure scoring` | 以交互方式更新评分参数 | | `./healert.sh configure scoring --threshold N` | score=100 对应的分数(默认:50) | | `./healert.sh configure scoring --half-life N` | 衰减半衰期,以天为单位(默认:7) | | `./healert.sh configure scoring --retention N` | 事件时间窗口,以天为单位(默认:30) | | `./healert.sh configure scoring --reset` | 恢复默认的评分参数 | | `./healert.sh start` | 启动后端和 agent | | `./healert.sh start backend` | 仅启动后端 | | `./healert.sh start agent` | 仅启动 agent | | `./healert.sh stop` | 停止后端和 agent | | `./healert.sh stop backend` | 仅停止后端 | | `./healert.sh stop agent` | 仅停止 agent | | `./healert.sh restart` | 验证规则,并停止和启动两者 | | `./healert.sh validate` | 验证 rules.yaml | | `./healert.sh reset` | 删除并重新创建数据库 | | `./healert.sh reset --confirm` | 重置而不提示确认 | | `./healert.sh status` | 显示健康状态和运行状态 | | `./healert.sh logs` | 实时追踪所有进程的日志 | | `./healert.sh test` | 发送测试事件,验证完整 pipeline | | `./healert.sh version` | 显示版本、版权、许可证 | | `./healert.sh help` | 显示所有命令及其描述 | ### Kubernetes DaemonSet | 命令 | 描述 | |---|---| | `./healert.sh start kubernetes` | 将 agent 部署为 Kubernetes DaemonSet | | `./healert.sh stop kubernetes` | 移除 DaemonSet 和 healert-system namespace | | `./healert.sh update kubernetes` | 应用最新配置并进行滚动重启 | ## 配置 ### Agent | 变量 | 默认值 | 描述 | |---|---|---| | `HEALERT_BACKEND_URL` | `http://localhost:8000` | 后端 URL | | `HEALERT_HOST` | `127.0.0.1` | 后端绑定 host —— 在 DaemonSet 模式下设置为 `0.0.0.0` | | `AUDIT_LOG_PATH` | `/var/log/k3s-audit.log` | Audit log 路径 | | `ENTITY_NAMESPACE` | `default` | 集群范围资源的默认 namespace | | `RULES_PATH` | 必填 | 检测规则文件路径 | | `HEALERT_API_KEY` | 必填 | 用于后端认证的 Bearer token | | `K8S_NAMESPACE` | 自动 | Agent namespace —— 自动排除在检测之外 | ### 评分 | 变量 | 默认值 | 描述 | |---|---|---| | `SCORE_CRITICAL_THRESHOLD` | `50` | score=100 对应的加权分数 | | `SCORE_DECAY_HALF_LIFE` | `7` | 事件权重半衰期,以天为单位 | | `SCORE_RETENTION_DAYS` | `30` | 事件时间窗口,以天为单位 | **调优指南:** ``` ./healert.sh configure scoring --threshold 20 --half-life 3 # strict ./healert.sh configure scoring --threshold 50 --half-life 7 # default ./healert.sh configure scoring --threshold 100 --half-life 14 # lenient ``` ## 检测规则 规则定义在 `rules.yaml` 中。Agent 在启动时加载它们,并针对每个 audit log 事件评估每条规则(每条规则采用 AND 逻辑)。 ### 全局 Namespace 排除 将系统 namespace 添加到配置块中,以将它们从所有规则中排除: ``` config: ignore_namespaces: - kube-system - kube-public - kube-node-lease - cert-manager - istio-system - argocd # Add your system namespaces here ``` Agent 会自动将其自身的 namespace (K8S_NAMESPACE) 从所有检测中排除。 ### 生效规则 (v0.1.0) | 规则 | 严重性 | 类型 | 检测内容 | |---|---|---|---| | `kubectl-exec` | 高 | TYPE 1 Workload | 对 pod 的交互式 shell 访问 | | `pipeline-skip` | 高 | TYPE 1 Workload | deployment 上的策略绕过注解 | | `config-drift` | 高 | TYPE 1 Workload | 对 workload 资源的直接写入操作 | | `port-forward` | 中 | TYPE 1 Workload | 到 pod 的直接 port-forward | | `emergency-access` | 中 | TYPE 2 Shared | 直接的 secret 访问 | ### 自动 Namespace Entity 解析 (v0.1.0) Agent 直接使用 Kubernetes 事件的 namespace 作为 Backstage catalog 的 namespace: ``` pod in "default" -> component:default/payments-api (auto) pod in "staging" -> component:staging/payments-api (auto) pod in "production" -> component:production/payments-api (auto) ``` 无需任何配置。适用于任意数量的 namespace。 ### 评分公式 ``` Score = min(100, round(weighted_total / threshold x 100)) weighted_total = sum(points x 0.5^(age_days / half_life)) ``` | 严重性 | 分数 | |---|---| | high | 10 | | medium | 6 | | low | 3 | ## Kubernetes 生产环境部署 ### 第一步 —— 构建并导入镜像 ``` docker build -t ghcr.io/healert-io/agent:0.1.1 . docker push ghcr.io/healert-io/agent:0.1.1 # 对于 k3s (本地 registry): docker save ghcr.io/healert-io/agent:0.1.1 | sudo k3s ctr images import - ``` ### 第二步 —— 配置 daemonset.yaml ``` # 设置你的后端主机 IP (不是 127.0.0.1 — pods 无法访问 loopback) - name: HEALERT_BACKEND_URL value: "http://192.168.x.x:8000" # 更新 image tag image: ghcr.io/healert-io/agent:0.1.1 ``` ### 第三步 —— 部署 ``` export KUBECONFIG=/etc/rancher/k3s/k3s.yaml ./healert.sh start kubernetes ``` ### 第四步 —— 验证 ``` kubectl get pods -n healert-system -o wide kubectl logs -n healert-system -l app=healert-agent --tail=20 ``` 预期结果: ``` Healert Agent v0.1.0 Rules: 5 loaded Ignored namespaces (8): - kube-system ... - healert-system <- auto-added from K8S_NAMESPACE Backend OK -- version=0.1.1 auth=enabled Tailing "/var/log/k3s-audit.log" from end-of-file ``` ### 无停机更新 ``` # 在修改 daemonset.yaml 或轮换 API key 之后: ./healert.sh update kubernetes ``` ## 安全性 | 属性 | 实现 | |---|---| | API key 存储 | `.env` 文件并设置 `chmod 600` —— 从不提交到 git | | API key 注入 | 环境变量 —— 从不出现在 `ps aux` 输出中 | | 后端绑定 | 默认为 `127.0.0.1` —— 不对外暴露到网络 | | Kubernetes Secret | API key 作为 K8s Secret 存储 —— 而非普通的 env var | | Agent 用户 | 以非 root 用户 uid=65532 (distroless) 运行 | | 文件系统 | `readOnlyRootFilesystem: true` | | Capabilities | `drop: ALL` —— 零 Linux capabilities | | 网络 | NetworkPolicy:仅允许出站到 backend:8000 和 DNS | | Audit log | 只读 hostPath 挂载 | | Shell 执行 | agent 二进制文件中零次 exec.Command() 调用 | | 路径验证 | 仅限绝对路径,禁止 `..` 遍历 | | 输入清理 | `sanitiseLogValue()` 防止日志注入 | | HTTP 超时 | 所有出站请求均为 10 秒 | | 脚本强化 | `set -euo pipefail`, `umask 077` | | 优雅关闭 | SIGTERM/SIGINT 处理程序 —— 在滚动更新时干净退出 | | Namespace 隔离 | Agent 自动排除其自身的 namespace | | Priority class | `system-node-critical` —— 在资源压力下绝不被驱逐 | ## Audit Log 路径 | 发行版 | 路径 | |---|---| | k3s | `/var/log/k3s-audit.log` | | kubeadm | `/var/log/kubernetes/audit/audit.log` | | Vanilla Kubernetes | `/var/log/audit/audit.log` | ## 相关仓库 | 仓库 | 描述 | |---|---| | [healert-io/backend](https://github.com/healert-io/backend) | FastAPI + SQLite 后端 | | [backstage/community-plugins](https://github.com/backstage/community-plugins) | Backstage 插件 (`@backstage-community/plugin-healert`) | ## 许可证 Apache License 2.0 -- 版权所有 2026 Healert OÜ 有关完整的许可证文本,请参阅 [LICENSE](./LICENSE)。
标签:Backstage, Go, Ruby工具, 子域名突变, 审计日志, 日志审计, 请求拦截, 运维监控