监控系列第一篇文章,内容大多是 OSSEC 官方文档的翻译,加上一些自己的理解总结 Orz
OSSEC 有两种模式:
Server-Agent模式
AgentLess模式(只能运行完整性检查)
在 Server-Agent 模式下,Agents 和 Server 的通信,可以使用 rsyslog(514端口 TCP、UDP),也可以使用 1514 UDP端口(默认)。
Server 和 Agent 分别安装完成之后,需要先从 Server 添加一个新的 Agent,获取一串 key 添加到 Agent 机器上之后,才能完成 UDP 链接的建立,开始正儿八经的监控。
OSSEC 支持自动化添加 Agent:
在 Server 运行: /var/ossec/bin/ossec-authd -p 1515
在 Agent 运行:/var/ossec/bin/agent-auth -m 192.168.1.12 -p 1515
agent-auth 进程会连接到 Server 的 ossec-authd 进程,获取并且安装 key。
OSSEC 支持通过 Server 远程管理 Agent 的各项配置,只需要设置 /var/ossec/etc/shared/agent.conf。一般需要几个小时来同步配置,但可以手动重启Agent来加快这个进程。
OSSEC 有三大模块:
日志收集 & 分析
完整性检查
rootkit检查
日志处理模块(Log Analysis,又称 LIDS)分为两部分:日志收集(运行在Agent)、日志分析(运行在Server)。
日志收集主要通过如下手段:
进程监控(通过定时运行命令来获取系统当前状态,比如磁盘使用量、CPU占用率等)
文件监控(监控系统的日志文件变动,为被动触发)
添加新的日志收集规则,只需要在 Agent 的 ossec.conf 中添加一条 <localfile>
规则即可
1. `# 文件监控`
2. `<localfile>`
3. `<log_format>apache</log_format>`
4. `<location>/var/www/logs/access_log</location>`
5. `</localfile>`
7. `# 进程监控`
8. `<localfile>`
9. `<log_format>command</log_format>`
10. `<command>df -h</command>`
11. `</localfile>`
Agent 不做任何日志分析/过滤,只是收集日志打包发送给 Server。
日志分析模块接收到日志后,首先会用 decoder 解析出日志的各个字段。然后调用 rules 里的规则对内容进行匹配,输出告警内容。
decoder 实际上也分为两个阶段:第一阶段 pre-decoding 为 ossec 内置,可以将标准的 syslog 日志,解析出基础的 hostname、programname、log 字段[2];第二阶段 decoding 根据解析出的 programname 去解析出详细的字段。官方[3]的栗子:
1. `# 日志原文:`
2. `2013-11-01T10:01:04.600374-04:00 arrakis ossec-exampled[9123]: test connection from 192.168.1.1 via test-protocol1`
4. `# pre-decoding后:`
5. `full event: '2013-11-01T10:01:04.600374-04:00 arrakis ossec-exampled[9123]: test connection from 192.168.1.1 via test-protocol1'`
6. `hostname: 'arrakis'`
7. `program_name: 'ossec-exampled'`
8. `log: 'test connection from 192.168.1.1 via test-protocol1'`
10. `# decoding后:`
11. `decoder: 'ossec-exampled' # 对应上一步骤的program_name`
12. `srcip: '192.168.1.1'`
13. `proto: 'test-protocol1'`
对应的 decoding 规则如下:
1. `<decoder name="ossec-exampled">`
2. `<program_name>ossec-exampled</program_name>`
3. `</decoder>`
5. `<decoder name="ossec-exampled-test-connection">`
6. `<parent>ossec-exampled</parent> # 继承自上一标签`
7. `<prematch offset="after_parent">^test connection </prematch> # 逻辑判断`
8. `<regex offset="after_prematch">^from (\S+) via (\S+)$</regex>`
9. `<order>srcip, protocol</order> # 变量名,对应的值为正则表达式里匹配的内容`
10. `</decoder>`
decoder 利用 parent
、 prematch
等标签实现逻辑判断(类比于if), regex
、 order
实现参数匹配, parent
继承的方式,也可以实现多条件分支判断,用于识别不同类型的日志(比如ssh日志中的登录失败、登录成功等)。这样巧妙的设计值得学习。
rules 一共分为16个等级(0-15),设置为0时只会记录不会告警。同样是通过规则继承实现条件判断,但比decoder更复杂,具体可参考 https://ossec.github.io/docs/syntax/head\_rules.html。
举个栗子,OSSEC 自带的 Apache 服务狗带的告警:
1. `<group name="apache,">`
2. `<rule id="30100" level="0">`
3. `<decoded_as>apache-errorlog</decoded_as> # 对应decoder中的name`
4. `<description>Apache messages grouped.</description>`
5. `</rule>`
7. `<rule id="30103" level="0">`
8. `<if_sid>30100</if_sid> # 继承`
9. `<match>^[notice] </match> # if判断`
10. `<description>Apache notice messages grouped.</description>`
11. `</rule>`
13. `<rule id="30104" level="12">`
14. `<if_sid>30103</if_sid>`
15. `<match>exit signal Segmentation Fault</match>`
16. `<description>Apache segmentation fault.</description>`
17. `<info type="link">http://www.securityfocus.com/infocus/1633</info>`
18. `<group>service_availability,</group>`
19. `</rule>`
20. `</group>`
告警默认通过邮件发送,具体发送的漏洞等级范围可以在 ossec.conf 中调整。
Syscheck(完整性检查):
主要是检查系统中的关键文件的MD5、SHA1变化以及Windows注册表
默认6小时检查一次,可以配置。文件的hash信息会同步到 Server 去存储(/var/ossec/queue/syscheck)
ossec-syscheckd可以做到实时监测,通过inotify 机制来实现
举个栗子,每隔两个小时检查一次 /etc 目录的文件变动:
1. `<syscheck>`
2. `<frequency>7200</frequency> # 检查频率`
3. `<directories check_all="yes">/etc</directories> # 检查的目录`
4. `<ignore>/etc/hosts.deny</ignore> # 忽略的目录,可以理解为白名单,减少重复误报的情况`
5. `</syscheck>`
RootCheck检查手段:
rootkit_files.txt 记录了 rootkit 常用的文件,程序会尝试 stats, fopen and opendir 指定的文件。程序会尝试所有的syscall,因为有些内核级别的的 rootkit 会隐藏文件。尝试的次数越多,漏报会越少。这个库需要不断更新。
rootkit_trojans.txt 记录了木马文件的特征。这个方法无法检测内核级别的 rootkit,也无法发现未知木马。
扫描/dev目录来寻找异常。一些 rootkit 会隐藏在该目录下,实际上这个目录只应该有设备文件。
扫描所有的文件,主要检查权限异常。普通用户不应该有权限修改root的文件。还有suid文件、隐藏的文件和目录。
查找隐藏进程。程序使用 getsid 和 kill 去检查 pid 是否被占用。如果 pid 被占用了,但是 ps 并没有显示,说明有可能被 rootkit了。
查找隐藏端口。程序使用 bind 去检查端口(包括 tcp udp)是否被占用。如果端口被占用了,但是 netstat 并没有显示,说明有可能被 rootkit了。
扫描 promisc 模式的网卡。如果是promiscuous 模式的网卡,但是 ifconfig 没有显示,说明有可能被 rootkit了。
Active Response: 一些规则被匹配到后,会触发命令执行,来实现一些功能[1]。比如:ssh爆破次数大于10次,屏蔽ip
1. `<command>`
2. `<name>host-deny</name>`
3. `<executable>host-deny.sh</executable>`
4. `<expect>srcip</expect>`
5. `<timeout_allowed>yes</timeout_allowed>`
6. `</command>`
7. `<active-response>`
8. `<command>host-deny</command>`
9. `<location>local</location>`
10. `<rules_id>31171</rules_id> # 满足某条规则,就触发屏蔽`
11. `<timeout>600</timeout>`
12. `</active-response>`
注:告警是 Server 端产生的,通过 Server 端运行的 agent_control 进程将相关指令下发给 Agent,最终在 Agent 端执行并生效[4]。
说起来这篇文(fan)章(yi)写了也有段时间了。本来是雄赳赳气昂昂,准备看完文档就看源码的,结果文档写的很好,国内外也有很多人分享过各个方面的理解,也就丢了看源码的心思(😩其实是不想看C)。
整个的设计模式非常有参考价值,通过层层叠叠的配置文件,降低了添加新规则的门槛,也让整体看起来更有条理。
[1]开源HIDS-OSSEC使用实例2:使用联动功能阻断cc攻击 http://www.freebuf.com/articles/system/69394.html [2]OSSEC日志泛化及告警规则配置 http://www.freebuf.com/articles/network/36484.html 在 [3]OSSEC官方文档 http://ossec-docs.readthedocs.io/en/latest/manual [4]About active responses in OSSEC http://sgros.blogspot.com/2012/08/about-active-responses-in-ossec.html