再探 audit 审计机制
在文章如何审计 Linux 系统的操作行为中, 我们详细介绍了审计系统行为的几种方式, 以及对应的优缺点. 但是在 audit
方面介绍还不够深入, 缺乏实践使用的一些准则. 本文则对 audit
机制以及相关工具做更多的延申介绍, 主要包含以下几点:
auditd 工作机制
如何实现
备注: 部分内容参考如何审计 Linux 系统的操作行为.
auditd
主要由内核和用户空间两部分组成. 内核空间主要由 kauditd
组件支持, 目前主要的 Linux
发行版都会内置支持. 以 Linux
的 audit
用户空间工具为例说明, 主要流程如下所示:
备注: 更多见 audit 事件, 字段字典, Linux 系统调用. 用户空间侧一般仅关注 1300 ~ 1399 的类型事件;
audit 整体上为分离的架构, auditctl 可以控制 kauditd 生成记录的策略, kauditd 生成的记录事件会发送到 auditd 守护程序, audisp 可以消费 auditd 的记录到其它地方. 其主要的几个组件包含如下:
组件 | 说明 |
---|---|
auditctl | 配置 kauditd 事件的规则, 可以及时生效, 用户空间通常使用 auditctl 调整规则; |
auditd | audit 相关配置的加载, 日志落盘等都通过 auditd 守护程序实现, 同时也和 kauditd 交互; |
audisp | 与 auditd 通信, 将收到的记录信息发送到其它地方, 比如 syslog 中; |
augenrules ausearch autrace aureport |
audit 提供的辅助分析工具; |
过滤规则
同 snoopy
规则类似, 不希望审计可能包含的敏感信息命令时, 在使用的时候我们可以忽略一些条目:
### ignore common tools
-a never,exit -F arch=b64 -F exe=/usr/bin/redis-cli
-a never,exit -F arch=b64 -F exe=/usr/bin/mysql
-a never,exit -F arch=b64 -F exe=/usr/bin/mongo
### record system invoke
-a always,exit -F arch=b64 -S execve
-a always,exit -F arch=b32 -S execve
-a always,exit -F arch=b64 -S truncate,ftruncate,creat -F exit=-EACCES -F key=access
-a always,exit -F arch=b64 -S truncate,ftruncate,creat -F exit=-EPERM -F key=access
上述的
-EACCES, -EPERM
是仅在访问错误或权限错误的时候才记录.
系统默认的 auditd 输出信息相对晦涩, 需要二次解析处理:
type=SYSCALL msg=audit(1669631724.918:33310): arch=c000003e syscall=59 success=yes exit=0 a0=11abec0 a1=1288450 a2=12345f0 a3=7ffd90cca5a0 items=2 ppid=19123 pid=19399 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts2 ses=62194 comm="ip" exe="/usr/sbin/ip" key=(null)
type=EXECVE msg=audit(1669631724.918:33310): argc=2 a0="ip" a1="addr"
auditd 机制的延申
由于 auditd
的功能足够丰富, 市面上出现了很多基于 auditd
机制的工具, 相比 Linux
的 audit
套件, 这些工具架构更简单:
这些工具等同实现了 auditd
和 audisp
两个组件的功能, 同时还增加了事件的解析功能, 补足了 audit
输出信息晦涩的不足. 另外 output
支持的也更多, 可以直接落盘或者发送到 es
, kafka
等组件.
这些工具中, auditbeat 为 elastic
公司产品 beats
中的一员, 周边生态丰富; hids 和 wazuh 属于同类产品, 更侧重于安全分析和事件响应, 相比较 wazuh
更为活跃; go-audit 出现较早, 功能比较集中, 但活跃度不高.
下面则主要介绍 auditbeat
, wazuh
和 Elkeid
这三类工具.
auditbeat 工作机制
功能说明
auditbeat(比如 7.17 版本)
对审计做了不少扩展, 有的功能 audit
虽然支持, 但是解析更耗资源, 相比定期检查等方式更轻量方便. 目前主要支持三大类的审计功能:
模块 | 功能 | 说明 |
---|---|---|
auditd | 兼容 Linux Audit | 与 kauditd 交互, 消费收到的事件消息,比 audit 日志更易阅读; |
File Integrity | 文件完整性检查 | 定期(10s)遍历指定目录下的文件(/bin, /user 等), 保存文件哈希到 boltdb 中; 对比上报哈希值不同的文件信息; |
System | dataset: host login package process socket user |
分别用来获取: 主机信息(ip, kernel, mac 等); 登录信息; yum/deb 安装信息; 进程启停信息(同文件完整性, 定期(10s)检查); tcp/udp 网络信息(数据可能很多); 用户创建删除信息; |
上述的功能中, 有 3 点需要注意:
1. 定期执行意味着短时间运行的进程或文件可能监控不到;
2. 开启 socket 监控, 可能产生很多日志, 尤其在短连接很多的场景中;
3. auditbeat 提供了内存队列, 磁盘限额存储事件等特性, 防止事件太多造成不可控的影响;
备注: 和内核可能产生 kernel 死锁.
auditbeat
对日志信息做了额外的解析, 比起 audisp
更方便阅读:
过滤规则
可以参考 snoopy
规则, 做以下过滤:
processors:
- add_host_metadata: ~
- drop_event:
when:
or:
- contains:
process.title: "iptables -S"
- contains:
process.title: "telegraf --test"
- contains:
process.title: "redis-cli"
- regexp:
process.title: "mysql.*-p"
- equals:
user.name: "telegraf"
- equals:
process.executable: "/usr/sbin/crond"
- equals:
process.name: "consul-kv"
- equals:
process.name: "sadc"
wazuh 工作机制
功能说明
wazuh
工具整体上功能更全, 也更偏重于安全分析和事件响应, 架构方面主要包含 agent
和 manager
组件:
数据可以存储到官方指定的 opensearch(兼容 es), 其在此基础上实现了很多看板和数据分析. 不过也可以存储到 es, 但需要单独安装 kibana 插件;
在上面架构中, agent
直接和 cluster
通信, 将搜集的信息发给 cluster 节点, cluster 节点落盘到日志文件, 最后通过 filebeat 消费到 es 集群中.
以下为 agent 主要的一些主要功能, 很多功能受 manager
端开关控制:
功能 | 说明 |
---|---|
支持平台 | 支持 linux, windows, mac, unix |
自动升级 | 有自动升级的机制; |
数据搜集 | linux - audit 机制, 自定义内核模块以及系统信息; windows - auditing 规则和系统信息. auditing 功能不够多, 主要集中于数据的修改以及用户, 进程等; |
系统调用 | 监控指定的系统调用, 仅支持 linux - 可能产生很多数据; |
入侵检测 | 扫描主机发现可能的恶意软件, rootkit 和可疑行为, 同时检测隐藏的文件和进程; |
日志分析 | 会获取系统日志或程序日志并发送到 server 端存储以供分析; |
文件完整性检查 | 同 auditbeat, 定期检查保存哈希到 sqlite 中, 上报哈希变更的信息; 进程检查也类似; |
漏洞扫描 | 定期获取本机软件详单和 server 端的 CVE 数据库交互,进而得到漏洞信息; |
事件响应 | 可以对指定的事件作出动作响应, 比如修改 iptables, 删除用户, 执行指定命令等; |
安全(云/容器) | 结合各云厂商的安全 api, 来分析云主机的安全情况; |
过滤规则
wauzh
通过搜集 audit.log
日志进而分析系统命令的执行, 参考 wazuh-audit, 不过 wazuh
主要以 audit
关键字进行区分, 如下所示:
# cat /var/ossec/etc/lists/audit-keys
audit-wazuh-w:write
audit-wazuh-r:read
audit-wazuh-a:attribute
audit-wazuh-x:execute
audit-wazuh-c:command
所以在创建 audit
过滤规则的时候需要通过 -k
选项添加对应的过滤标识, 如下所示:
### ignore common tools
-a never,exit -F arch=b64 -F exe=/usr/bin/redis-cli
-a never,exit -F arch=b64 -F exe=/usr/bin/mysql
-a never,exit -F arch=b64 -F exe=/usr/bin/mongo
-a always,exit -F arch=b64 -S execve -k audit-wazuh-x
-a always,exit -F arch=b32 -S execve -k audit-wazuh-x
-a always,exit -F arch=b64 -S truncate,ftruncate,creat -F exit=-EACCES -F key=access -k audit-wazuh-r
-a always,exit -F arch=b64 -S truncate,ftruncate,creat -F exit=-EPERM -F key=access -k audit-wazuh-r
备注:
auditbeat
和wazuh
在审计方面是互斥的,wazuh
需要auditd
服务, 消费日志audit.log
,auditbeat
则需要关闭auditd
服务, 自己来接收消息.
Elkeid 工作机制
Elkeid 是字节出的一款入侵检测系统, 功能有点类似 wazuh
, 不过它的机制有很大的不同, 如下所示:
目前主要开源了 agent
, driver
和 RASP
几个组件, 通过源码编译时也出现了一些异常,比如缺少一些依赖说明, rasp
组件依赖太多等问题. 不过从这几个组件也能看出 Elkeid
的工作机制有很大的不同.
组件 | 功能说明 |
---|---|
agent | 插件及自定义插件管理; 系统信息, 日志数据的搜集; 和 server 端通信, 进行服务发现; |
driver | 主要用于搜集 kernel 数据, 包括: hids_driver.lo 内核模块; 跟踪 io, bind, execve 系统调用, 通过 ptrace 实现; rootkit 检测; |
rasp | 主要为进程运行时分析, 包括: jvm - 通过 ASM 修改类的字节码, 跟踪堆栈和参数调用; golang - 从 gopclntab 块中解析符号表, 再加入 hook api, 进而跟踪堆栈和参数调用; php - 增加 hook 函数和 opcodes, 跟踪堆栈和参数调用; |
driver
组件中, 主要通过 ptrace
和内核模块实现了内核空间的数据搜集, 这种方式对发行版的侵入很大, 通用性不够, 内核模块和内核版本也强绑定, 见 ko_list, 所以这种方式不适合我们线上使用.
其它工具
packetbeat 工作机制
功能说明
packetbeat 同样是 beats 的组件之一, 主要通过 pcap 抓包机制实时分析网络包, 不过比起 auditbeat 的 socket 功能, packetbeat 的功能更丰富, 解析报文支持的协议也更多, 包括:
ICMP, DHCP, DNS, HTTP
AMQP, Cassandra, MySQL, PostgreSQL, Redis, MongoDB, Memcached
NFS, TLS, Thrift
备注: 同
auditbeat
,packetbeat
也提供了内存队列, 磁盘限额存储事件等特性, 防止事件太多造成不可控的影响.
过滤规则
过滤规则同样可以使用 drop_event 语法, 如下所示:
processors:
- add_host_metadata: ~
- drop_event:
when:
or:
- network:
source.ip: private
- network:
destination.ip: '192.168.1.0/24'
filebeat 工作机制
功能说明
filebeat 同样是 beats 的组件之一, 主要用来搜集文件内容. 目前通过模块化的方式支持并解析了所有常见的系统和软件日志, 包含:
syslog, audit, secure, haproxy, iis, tomcat, nginx, kafka, zeek
mysql, postgresql, mssql, oracle, mongodb, redis, elasticsearch ...
开启模块并设置字段建立索引模板后, 各模块的 mapping
映射信息会自动同步到 es.
过滤规则
由于 filebeat 的目的很单一, 主要为搜集日志, 如果仅考虑系统运维层面, 可以考虑使用以下配置:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/telegraf/telegraf*.log
fields:
logmon: telegraf
- type: log
enable: true
paths:
- /var/log/filebeat/filebeat*
fields:
logmon: filebeat
- type: log
enable: true
paths:
- /data/scripts/logs/*.log
fields:
logmon: scripts
filebeat.config.modules:
reload.enabled: true
reload.period: 15s
path: /etc/filebeat/modules.d/*.yml
并开启以下模块:
mysql, redis, system
各工具对比
上述工具各有优缺点, 不过应用到线上需要慎重考虑. 对各工具的优劣对比如下:
特点 | snoopy | auditbeat | wazuh | packetbeat | filebeat | Elkeid |
---|---|---|---|---|---|---|
应用领域 | 命令审计 | 命令审计 | 安全分析 | 网络分析 | 日志收集 | 安全分析 |
是否全平台 | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
部署简单 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
方便升级维护 | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
是否活跃 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
影响应用成都 | 中高 | 轻微 | 轻微 | 中高 | 轻微 | 中高 |
影响内核程度(可能死锁, 崩溃等) | 轻微 | 中等 | 中等 | 轻微 | 轻微 | 中高 |
过滤规则 | 事后 | 事后 | 事后 | 事后 | ❓ | 事前事后 |
是否适合线上 | ✅ | ✅ | ❗ | ❌ | ✅ | ❌ |
过滤规则中, 事后表示无论设置什么规则, 都是先由工具接收所有事件后再应用规则. 这意味着如果系统调用的事件很多, 无论是否应用规则, 内核 kauditd 的压力都可能增大.
是否适合线上, wazuh
为感叹号, 因为他的审计依赖 audit
套件, 并消费 audit.log
日志. 另外不少事件响应功能也不是线上所需要的.
容量预估
以测试环境的一台 centos 7
主机为例说明, 该主机相对空闲, 仅运行两台 MySQL
和 telegraf
监控程序, 单日的数据量大致如下:
auditbeat 测试
编号 | 功能 | 数据量 |
---|---|---|
1 | 开启 execve, 开启 file_integrity, login, process, user, socket | 2.5 GB |
2 | 开启 execve, 开启 file_integrity, login, process, user | 200 MB |
3 | 同 2, 开启过滤规则 | 40 MB |
filebeat 测试
编号 | 功能 | 数据量 |
---|---|---|
1 | 仅监控运维层面的日志信息 | 8 MB |
wauzh 测试
编号 | 功能 | 数据量 |
---|---|---|
1 | 默认配置, 不设置 audit 规则 | 25 MB |
2 | 设置 auditctl 规则 | 接近 auditbeat 的规则 2, 3 |
packetbeat 测试
未做测试, 主要受配置和系统上运行服务的影响. 网络请求越多, 单日数据量越大. 但上限受内存队列和磁盘限额的调整.
总结: 从上述的数据量来看, auditbeat
的规则 2, 3, filebeat
和 wauzh
的数据量相对合适, 比如 1 千台主机产生的数据量(单日 40G ~ 200G 左右).
细看 auditbeat
根据上述的对比, auditebat
更适合实际的使用情况, 如果需要应用到线上, 我们需要对 auditbeat
有更多的了解.
系统调用的进与出
对每个 Linux
的系统调用而言, 比如以简单的 open
调用, 对应到内核中为 sys_open
函数:
asmlinkage long sys_open(const char __user *filename,
int flags, umode_t mode);
如果需要跟踪 open
调用, 可以在 sys_open
函数执行前后两个点来获取上下文信息, 不过为了尽量避免影响函数的执行, 通常都会选择执行完后, 即在 sys_open
函数 exit
的时候开始记录信息.
对应到 auditctl
规则, 可以表示如下:
-a never,exit # 系统调用 exit 的时候永不记录
-a always,exit # 总在系统调用 exit 的时候记录
audit 事件
由于可以跟踪很多系统调用, 这些系统函数及其参数信息就可以组成很多可以审计的事件(用户空间 1300 ~ 1399
), 比如常见的下面事件:
AUDIT_PATH
AUDIT_CWD
AUDIT_EXECVE
AUDIT_PROCTITLE
事件配合进程和线程的上下文信息即可获取到我们需要的审计信息.
规则测试
auditbeat 规则
# 仅测试环境
-a always,exit -F arch=b64 -S open -S sendfile -S truncate -S ftruncate -S chdir -S fchdir -S rename -S mkdir -S rmdir -S creat -S unlink -S readlink -S openat -S mkdirat -S unlinkat -S renameat -S readlinkat -F key=note
-a always,exit -F arch=b64 -S mount,umount2 -F auid!=-1 -F key=mount
-a always,exit -F arch=b32 -S mount,umount,umount2 -F auid!=-1 -F key=mount
-w /etc/sysconfig/iptables -p wa -k iptables
-w /etc/sysctl.conf -p wa -k sysctl
-w /etc/sysctl.d -p wa -k sysctl
-w /sbin/auditctl -p x -k audittools
-w /sbin/auditd -p x -k audittools
-w /usr/sbin/auditd -p x -k audittools
-w /usr/sbin/augenrules -p x -k audittools
-w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/gshadow -p rwxa -k identity
-w /etc/shadow -p rwxa -k identity
-w /etc/sudoers -p wa -k actions
-w /etc/sudoers.d -p wa -k actions
-w /usr/bin/passwd -p x -k passwd_modification
-w /usr/sbin/groupadd -p x -k group_modification
-w /usr/sbin/groupmod -p x -k group_modification
-w /usr/sbin/addgroup -p x -k group_modification
-w /usr/sbin/useradd -p x -k user_modification
-w /usr/sbin/userdel -p x -k user_modification
-w /usr/sbin/usermod -p x -k user_modification
-w /usr/sbin/adduser -p x -k user_modification
-w /etc/ssh/sshd_config -p rwxa -k sshd
-w /etc/ssh/sshd_config.d -p rwxa -k sshd
# 常见命令打标签, 方便监控
-w /usr/sbin/iptables -p x -k note_cmd
-w /usr/bin/zip -p x -k note_cmd
-w /usr/bin/gzip -p x -k note_cmd
-w /usr/bin/bzip2 -p x -k note_cmd
-w /usr/bin/lz4 -p x -k note_cmd
-w /usr/bin/zstd -p x -k note_cmd
-w /usr/bin/tar -p x -k note_cmd
-w /usr/bin/cp -p x -k note_cmd
-w /usr/bin/mv -p x -k note_cmd
-w /usr/bin/wget -p x -k note_cmd
-w /usr/bin/curl -p x -k note_cmd
-w /usr/bin/scp -p x -k note_cmd
-w /usr/bin/rsync -p x -k note_cmd
-w /usr/bin/ftp -p x -k note_cmd
-w /usr/bin/sftp -p x -k note_cmd
-w /usr/bin/hexdump -p x -k note_cmd
-w /usr/bin/xxd -p x -k note_cmd
-w /usr/bin/ln -p x -k note_cmd
-a always,exit -F arch=b64 -S truncate,ftruncate,creat -F exit=-EACCES -F key=access
-a always,exit -F arch=b64 -S truncate,ftruncate,creat -F exit=-EPERM -F key=access
-a always,exit -F arch=b64 -S bind -S execve -S connect
-a always,exit -F arch=b32 -S bind -S execve -S connect
connect 仅测试环境.
文件完整性规则
- module: file_integrity
paths:
- /bin
- /usr/bin
- /sbin
- /usr/sbin
- /etc
max_file_size: 3000 MiB
系统规则
- module: system
datasets:
- login
- process
- user
state.period: 8h
process.hash.max_file_size: 1000 MiB
user.detect_password_changes: true
login.wtmp_file_pattern: /var/log/wtmp*
login.btmp_file_pattern: /var/log/btmp*
标签及自定义规则
tags: ["xxxxx"] # 标识信息
fields:
logmon: auditbeat # 自定义字段, 方便 logstash 等工具判断处理
audit 事件忽略
为避免产生过多的日志, 整体上按以下规则忽略事件:
没有 uid 的行为;
忽略 telegraf/zabbix 等监控行为相关的事件;
忽略 crond 相关的事件;
忽略 mysql, redis-cli 等相关的正常事件;
对应 auditbeat
的规则语法如下示例:
- drop_event:
when:
or:
- equals: # old-uid is not set(-1)
auditd.summary.actor.primary: "unset"
- contains:
process.title: "iptables -S"
- contains:
process.args: "-tnlp"
- equals:
process.name: "redis-cli"
- equals:
process.executable: "mysql"
- equals:
process.executable: "mongo"
- equals:
user.saved.name: "telegraf"
- equals:
user.name: "telegraf"
报警策略
规则报警可以集中在 audit key
信息, 对应 auditbeat
规则的 -k
属性.
总结
在上述的介绍中, 可以看到不通工具都有很强的功能定位行, 而且越偏底层, 带给内核的风险就越大, 所以具体实践中很难将这些功能都集成到一个工具中, 但是借助这些工具又能加强我们的基础能力. 所以如果从功能和风险因素角度来看:
功能 | 风险 |
---|---|
记录执行的命令; 系统文件完整性检查; 进程启停检查; 系统和脚本日志搜集; 所有信息结合 CMDB,可搜索, 可视化, 可告警; |
是否对内核, 应用产生影响; 是否加重系统压力; 出现问题是否方便部署升级; 是否会产生安全问题; <是否产生日志过多, 加重存储负担>; |
部署多个组件可以将风险都分担开, 不至于一个组件出问题对系统产生很大的影响. 可以参考下图:
+-----------------+
| Host A |
| +-----------+ |
| | telegraf | | +--------------------+ +-----------------+
| +-----------+ | | victoriaMetrics |----------------------------> | metric monitor |
| | filebeat |--+-------> +--------------------+ +---------------+ +-----------------+
| +-----------+ | | logstash / kafak |------> | elasticsearch |---> | audit monitor |
| | auditbeat | | +--------------------+ +---------------+ | log monitor |
| +-----------+ | +-----------------+
| |
+-----------------+
事实上
telegraf
也支持elasticsearch
, 只不过对监控的指标数据而言,victoriametrics
的压缩比更高, 且 alert 组件的功能也更完善. logstash 和 kafka 可以视具体情况而定. 如果需要加工信息, 比如去除一些多余字段, 增加一些 CMDB, 使用人等字段可以考虑使用 kafka, 由消费程序统一处理.
由 telegraf + filebeat + auditbeat
组合来覆盖系统层所有的监控, 可以很好的满足我们在审计方面的需求. 如果是采用云产品或其它商业产品, 相信在功能方面也是相对分层的, 毕竟几个组件功能都很庞大, 与底层的交互也较深, 也更有利于生产环境的操作维护.