用 Prometheus 把 Linux 安全审计变成持续监控

2026-05-18 18 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:7 分钟

安全审计这件事,最折磨人的不是标准有多严,而是检查本身是"一次性"的。SSH 上去逐台看 SELinux 状态、防火墙规则、过期账户、密码策略——几十台机器做完,人已经麻了。更致命的是:今天查完合规,明天有人改了一行配置,你根本不知道。

security-collector-exporter 的思路很简单:把这些散落在各处的安全配置项变成 Prometheus 指标,审计从"人肉巡检"变成"持续可观测"。

审计项怎么变成指标

Linux 安全审计覆盖的东西很杂,但大致可以归为几类:

类别 典型检查项 指标化思路
访问控制 SELinux 模式、AppArmor 状态 1/0 表示 enforcing/permissive/disabled
网络边界 iptables/nftables 是否加载、默认策略 规则数量 + 默认策略枚举
身份认证 SSH PermitRootLogin、PasswordAuthentication 布尔指标,1 = 不合规
账户管理 过期账户数、空密码账户数 直接暴露计数
密码策略 最小长度、最大天数 数值指标

关键设计决策:不合规的项用 1 表示,合规用 0。这样在 Prometheus 里一条 sum(security_ssh_permit_root_login == 1) 就能立刻知道有多少台机器开了 root 登录,告警规则也直观。

部署与采集配置

Exporter 本身是个轻量 Go 二进制,跑在被监控节点上,定期读取本地配置文件和系统状态,暴露 /metrics 端点。下面是一个最小化部署方案。

先在目标机器上启动 exporter(以 systemd 方式为例):

# 下载二进制(假设版本 v0.3.0)
curl -L -o /usr/local/bin/security-collector-exporter \
  https://github.com/ownObservability/security-collector-exporter/releases/download/v0.3.0/security-collector-exporter-linux-amd64

chmod +x /usr/local/bin/security-collector-exporter

# 写 systemd unit
cat > /etc/systemd/system/security-collector-exporter.service << 'EOF'
[Unit]
Description=Security Collector Exporter for Prometheus
After=network.target

[Service]
ExecStart=/usr/local/bin/security-collector-exporter \
  --web.listen-address=0.0.0.0:9987 \
  --config.path=/etc/security-collector/config.yaml
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now security-collector-exporter

Exporter 的采集配置文件 /etc/security-collector/config.yaml,可以指定要检查哪些模块:

modules:
  ssh:
    enabled: true
    config_path: /etc/ssh/sshd_config
  selinux:
    enabled: true
  firewall:
    enabled: true
    backend: nftables  # 或 iptables
  accounts:
    enabled: true
    check_expired: true
    check_empty_password: true
  password_policy:
    enabled: true
    login_defs_path: /etc/login.defs

然后在 Prometheus 的 prometheus.yml 里加上采集目标:

scrape_configs:
  - job_name: 'security-collector'
    scrape_interval: 60s   # 安全配置不需要秒级采集
    static_configs:
      - targets:
          - '10.0.1.11:9987'
          - '10.0.1.12:9987'
          - '10.0.1.13:9987'
        labels:
          cluster: 'prod'

如果节点多,配合 node_exporter 的服务发现方式(Consul、Kubernetes SD 等)统一管理就行,端口和 job 名区分开即可。

指标出来后怎么用

Exporter 暴露的指标大致长这样(curl localhost:9987/metrics 截取):

security_selinux_mode{mode="enforcing"} 1
security_selinux_mode{mode="permissive"} 0
security_selinux_mode{mode="disabled"} 0

security_ssh_permit_root_login 1
security_ssh_password_auth 0

security_account_expired_total 3
security_account_empty_password_total 0

security_password_min_length 8
security_password_max_days 90

几个立竿见影的用法:

1. 不合规计数面板

# 有多少台机器 SSH 允许 root 登录
sum(security_ssh_permit_root_login == 1)

# 有多少台机器 SELinux 不是 enforcing
sum(security_selinux_mode{mode="enforcing"} == 0)

2. 告警规则——配置漂移立刻发现

groups:
  - name: security_compliance
    rules:
      - alert: SSHPermitRootLoginEnabled
        expr: security_ssh_permit_root_login == 1
        for: 5m
        labels:
          severity: warning
          team: infra
        annotations:
          summary: "SSH 允许 root 登录"
          description: "{{ $labels.instance }}  sshd_config 开启了 PermitRootLogin"

      - alert: SELinuxNotEnforcing
        expr: security_selinux_mode{mode="enforcing"} == 0
        for: 10m
        labels:
          severity: critical
        annotations:
          summary: "SELinux 未处于 enforcing 模式"
          description: "{{ $labels.instance }} 当前 SELinux 状态不是 enforcing"

      - alert: ExpiredAccountsExist
        expr: security_account_expired_total > 0
        for: 1h
        labels:
          severity: warning
        annotations:
          summary: "存在过期账户"
          description: "{{ $labels.instance }}  {{ $value }} 个过期账户"

3. 审计报告一键生成

不再需要逐台 SSH,一条 PromQL 就能出全集群报告:

# 每台机器的合规得分(合规项数 / 总检查项数)
# 假设 exporter 还暴露了 security_compliance_total 和 security_compliance_passed
security_compliance_passed / security_compliance_total

在 Grafana 里做成表格面板,按 instance 排序,低于 0.8 的标红——审计报告的雏形就有了。

上手前的几个考虑

  • 采集频率别太高。安全配置变更频率远低于业务指标,60s 甚至 5min 都够用,没必要给 Prometheus 和目标机器加压。
  • 指标设计要稳定。一旦 label 结构定下来就尽量别改,Prometheus 的历史数据对 label 变化是不友好的。新增检查项加新指标,不要在旧指标上塞新 label。
  • 和 node_exporter 共存没问题。端口分开(node_exporter 默认 9100,这个用 9987),job 名分开,互不干扰。
  • 敏感信息别进指标。不要把密码哈希、账户名等丢进 metric label,Prometheus 数据谁都能查。只暴露"是否合规"和"数量",具体账户名留在告警 annotation 或单独的审计日志里。
  • 配置漂移才是核心价值。一次性审计用 Ansible 也能做,这个 exporter 的真正意义是:改了配置 5 分钟内告警就到,不用等下一次人工巡检。

从一台机器开始试——部署 exporter、加 scrape 配置、写两条告警规则,跑一天看数据。合规这件事,持续看见比偶尔检查有用得多。


相关推荐