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(热力图)的形式展示。
[](https://opensource.org/licenses/Apache-2.0)
[](https://github.com/healert/agent/releases)
[](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工具, 子域名突变, 审计日志, 日志审计, 请求拦截, 运维监控