OSSIM中分布式消息队列应用
1. 消息队列处理
企业日志数量正在以指数级形式高速增长,日志数据的具有海量、多样、异构等特点,基于传统的单一节点混合式安装的OSSIM平台(指OSSIM 4.4及以下系统),无法满足海量日志分析要求。在OSSIM 4.4以后的系统中增加了中间件RabbitMQ,可通过RabbitMQ将系统中各组件解除耦合,避免了系统中运行模块的影响(例如MySQL的写操作等),这样设计可实现分布式日志分析平台的要求。
在网络出现故障前或故障过程中,各种设备和服务器会发送大量日志到日志服务器,在原先的设计中,这样的日志会直接写入数据库或者/var/log的某个文件中,在故障状态下的高并发情形下,会对数据库服务器造成巨大的压力,这是在进行日志查询操作时,变得相应延迟加剧,很容易就超过了系统的最大负载。
如图1-42中所示为早期日志收集的方案,在图中PHP脚本从数据库中读取数据的典型流程,此图包括打开数据库连接、运行任意SQL和语句、读取SQL语句找到的结果、关闭数据库连接,最后在HTML页面上将所或内容显示给用户。
上述实例中,每个步骤都存在瓶颈,数据库可能未调整为最佳运行状态,SQL语句使用的数据表可能未被优化,其中还有很多需要管理员注意的地方。如果没有缓存,用户在每次请求PHP脚本时都会碰到问题,每次都会导致性能降低。如果使用缓存来存储SQL语句的结果,这种性能的损耗将不复存在。
如何解决这种问题呢,在OSSIM中采用异步操作的方式,其核心思想就是消息队列(在OSSIM系统中,消息(Message)是由通信的双方所需要传递的日志消息),通过消息队列,将短时间高并发产生的日志消息,存储在消息队列中,从而削平高峰期的并发事务,这样可以有效抵御大量涌入的日志,对单机数据库系统的冲击,也就相对改善数据库系统性能。
以OSSIM中的SIEM事件存储来说明问题,设备将日志发送到Sensor,经过归一化处理之后发往OSSIM Server,关联引擎在对其继续加工,会同时将数个任务收集事件写到数据库,因此数据库写入量很大,当同时查询时并发操作将严重占用有限的I/O通道。
由于关联引擎的业务逻辑的处理比较复杂,往往MySQL数据库的写操作量更大,所以在OSSIM4.0之前系统中没有采用消息队列时,大负荷时往往系统响应迟缓。
但OSSIM 4.4 之后采用消息队列的思想,重构了系统之后,加入了消息队列服务器,结构如图1-43所示。
消息队列服务器中有一个进程单独对消息队列进行处理,首先判断消息队列中是否有待处理的消息,如果有的话,那么将其取出,并进行相应地处理。消息队列处理流程如图1-44所示,就这样通过消息队列将高并发用户请求进行异步操作,然后逐一对消息队列中进行出队同步操作,也避免了并发控制的难题。
消息队列只是解决并发问题的其中一种方式,在OSSIM中往往需要结合多种不同的技术方式来共同解决,比如负载均衡、反向代理等方案。这里,虽然以异常日志为例,但是"麻雀虽小五脏俱全",日志写入文件的高并发操作也同样适用于数据库的高并发,所以研究该案例具有一定指导意义。
2 RabbitMQ
RabbitMQ是实现AMQP(高级消息队列协议)消息中间件的一种,它是消息中间件的开发标准,与平台无关,现用于OSSIM分布式系统中存储转发消息,其工作原理如图1-45所示。
为什么要使用RabbitMQ?在高并发情况下RabbitMQ在处理发送和接收请求时响应非常快速,而且对其性能调优后,系统响应速度还会有所提高。RabbitMQ使用Erlang编写的AMQP 服务器,而AMQP基于客户端/代理模式。
在大数据日志分析应用中,我们常将OSSIM做成集群模式,因为这样可以使用RabbitMQ的集群功能。另外,RabbitMQ中集群中有两种节点,内存节点与磁盘节。对于每个Rabbitmq 节点,根据日志种类建立相应的队列,并且根据日志种类的名称建立exchange的key值,后面再介绍。RabbitMQ通讯端口为5672。
OSSIM中我们通过以下命令查看。
#netstat –na |grep 55672 tcp 0 0 127.0.0.1:52667 127.0.0.1:5672 ESTABLISHED
RabbitMQ环境变量的配置文件位于/etc/rabbitmq/rabbitmq-env.conf,使用时需要查询Rabbitmq状态命令,方法如下:
#rabbitmq-server alienvault \\这里的alienvault代表Ossim Server的主机名称
此时,能显示rabbitmq的端口、节点名称和主目录(/var/lib/rabbitmq)。
永远不要用kill命令直接停止RabbitMQ服务器,而应该采用rabbitmqctl命令(这样可以将数据同步保存到磁盘,然后关闭服务):
#rabbitmqctl stop
3 选择Key/Value存储
早期OSSIM版本中依然是采用Mysql+memcache的架构存储数据,由于存在性能和一致性问题,在OSSIM4.4后续版本中引入Redis作为队列处理服务器,有读者会问为什么选用Key/Value存储?从SIEM收集业务角度出发,无论日志还是安全事件都属于非结构化数据,在日志关联分析时,非结构化的数据量会大大超过结构化数据,这些数据之间存在关联,如果将这些数据直接存入数据库,那么对数据库访问频率将增加,由于单个表行数的猛增,对表的访问行数成比例增加,在多个表之间的数据调用将会产生大量的计算,足以将任何一个数据分析系统压垮。
在分析Ossim系统各集成开源工具中发现系统没有进行持久化,如果RabbitMQ服务器重启会导致消息丢失,所以采用Redis Server来解决这些问题,Redis是一个Key/Value的NoSQL数据库,Redis作为缓存服务器,数据存储在内存,所以速度比MySQL要快得多,尤其在OSSIM的Web UI中很多的排行榜应用、取出TOP 10的操作、包括各种仪表盘、计算器应用、SIEM控制台的Uniq操作、获取某段时间所有数据的列表、取最新的TOP N操作,包括在分布式日志收集系统中消息队列的处理,这些都要用到Redis服务。
更多有关OSSIM内容,请参考《开源安全运维平台-OSSIM最佳实践》一书。注:以上为样章内容,最终效果以书中文字为准。