osquery 主机安全检测实战:EDR 端点监控配置指南

适用场景

osquery 主机安全检测适用于以下场景:一是**EDR 端点监控**,替代部分商业 EDR 实现进程、网络、文件的持续监控;二是**入侵取证**,安全事件发生后用 SQL 快速查询可疑进程、异常连接与登录记录;三是**主机资产清点**,批量盘点服务器上的软件、用户、端口与开机启动项。osquery 以只读方式查询系统状态,资源占用低,适合大规模服务器部署。

前置条件

  • Linux 服务器(Debian/Ubuntu 或 CentOS/RHEL)
  • root 权限(安装与配置需要)
  • 熟悉基础 SQL 语法
  • 可选:Fleet/Zeek 等管理端(本文以单机 osqueryd 为例)

原理说明

osquery 将操作系统各子系统抽象为**虚拟表(virtual tables)**:processes 表对应进程列表,listening_ports 表对应监听端口,file 表对应文件系统,last 表对应登录记录。每个表由内置采集器实时生成数据,用户通过 osqueryi 交互式查询,或用 osqueryd 守护进程按计划执行查询并输出到日志。这种”系统即数据库”的设计,让安全分析可以用统一 SQL 完成,极大降低了端点监控的复杂度。

操作步骤

第一步:安装 osquery

# Debian/Ubuntu
curl -L https://pkg.osquery.io/deb/osquery_5.14.1-1.linux_amd64.deb -o osquery.deb
sudo dpkg -i osquery.deb

# CentOS/RHEL
curl -L https://pkg.osquery.io/rpm/osquery-5.14.1-1.el8.x86_64.rpm -o osquery.rpm
sudo rpm -ivh osquery.rpm

# 验证
osqueryi --version

若下载慢,可先执行 sudo apt install -y osquery(部分发行版仓库已收录)。安装完成后同时提供 osqueryi(交互查询)与 osqueryd(守护进程)两个组件。

操作步骤(续)

第二步:交互式查询基础表

# 进入交互终端
sudo osqueryi

# 查看所有可用表
.tables

# 查询监听端口与对应进程
SELECT p.name, lp.port, lp.address
FROM listening_ports lp
JOIN processes p ON lp.pid = p.pid
WHERE lp.port > 1024;

核心表速查:processes(进程)、listening_ports(监听端口)、users(用户)、crontab(计划任务)、file(文件)、last(登录记录)、os_version(系统版本)。可用 .schema 表名 查看表结构。

第三步:编写监控配置(osqueryd)

创建守护进程配置,定义定时查询计划。编辑 /etc/osquery/osquery.conf:

{
  "schedule": {
    "listening_ports": {
      "query": "SELECT DISTINCT p.name, lp.port, lp.address FROM listening_ports lp JOIN processes p ON lp.pid = p.pid WHERE lp.port > 1024;",
      "interval": 300
    },
    "login_events": {
      "query": "SELECT username, host, time FROM last ORDER BY time DESC LIMIT 50;",
      "interval": 600
    },
    "crontab_changes": {
      "query": "SELECT path, command, month, day, hour, minute FROM crontab;",
      "interval": 300
    },
    "unexpected_root_processes": {
      "query": "SELECT name, path FROM processes WHERE uid = 0 AND name NOT IN ('sshd','systemd','bash','nginx','mysql');",
      "interval": 300
    }
  },
  "logger": {
    "path": "/var/log/osquery/",
    "snapshot": true
  }
}

关键说明:schedule 定义查询任务,interval 为执行间隔(秒);logger.path 指定结果日志目录;snapshot:true 表示每次执行都记录完整结果(而非仅差异)。

第四步:启动守护进程

# 配置校验(语法检查)
sudo osqueryd --config_path=/etc/osquery/osquery.conf --config_check

# 启动并设置开机自启
sudo systemctl enable osqueryd
sudo systemctl start osqueryd

# 查看运行状态
sudo systemctl status osqueryd

# 查看采集日志
sudo tail -f /var/log/osquery/osqueryd.results.log

启动后用 --verbose 参数可查看详细日志排查问题。正常运行时,osqueryd.results.log 会按计划周期性写入各查询结果。

第五步:异常检测与告警

用 shell 脚本对结果日志做告警匹配:

# 每 5 分钟检查异常 root 进程并告警
#!/bin/bash
LOG=/var/log/osquery/osqueryd.results.log
grep "unexpected_root_processes" $LOG | tail -n 5 | while read line; do
  echo "[$(date)] 检测到异常 root 进程: $line" >> /var/log/osquery/alert.log
  # 可替换为 webhook/邮件通知
done

更完善的方案是接入 Fleet(开源 osquery 管理平台)统一管理多台主机,集中配置查询计划与告警规则,实现企业级 EDR 能力。

配置验证

验证 osquery 监控是否正常工作:

  1. osqueryd --config_check 返回无错误,确认配置语法正确
  2. systemctl status osqueryd 显示 active (running)
  3. 等待一个查询周期后查看 /var/log/osquery/osqueryd.results.log,确认各查询结果已写入
  4. 手动执行 sudo osqueryi -c "SELECT * FROM processes WHERE name LIKE '%nc%'" 验证 SQL 查询能力正常

常见问题

Q1:osqueryd 启动失败,提示配置文件错误怎么办?

先用 osqueryd --config_path=/etc/osquery/osquery.conf --config_check 定位语法错误。常见原因:JSON 末尾多逗号、interval 未设置、表名拼写错误。修复后重新执行 systemctl start osqueryd。也可用 osqueryi --json 单条验证查询语句本身是否能执行。

Q2:osquery 与商业 EDR 冲突吗?

不冲突。osquery 是只读查询引擎,不拦截系统调用,与安全软件通常可共存。但注意避免与 EDR 同时监控同一系统资源造成日志重复。若主机已部署商业 EDR 且功能重叠,可将 osquery 定位为补充采集层,只开启 EDR 未覆盖的查询。

Q3:查询大量文件表会占用很高资源吗?

file 表对全盘扫描时开销较大,生产环境应限定路径范围,例如只监控 /etc/tmp/var/www 等敏感目录,并用 --file 参数配合 glob 模式缩小范围。同时合理设置 interval,避免频繁执行高开销查询。

总结

osquery 以 SQL 方式统一了主机安全数据采集,是实现轻量级 EDR 与主机入侵检测的高性价比方案。核心实践路径为安装、交互查询、配置查询计划、启动守护进程、日志告警五步。生产部署时注意:查询计划精简聚焦、日志定期轮转、敏感目录定向监控,并逐步接入 Fleet 实现集中管理,让端点监控真正可落地、可持续。