关于MapR-DB和审计功能的后续篇章
在中文编辑中,我们介绍了使用expandaudit功能对Audit日志id进行解密,但是当使用该功能时,会根据文件是否已处理来判断。由于MFS在重新启动或每天发生文件轮换,Audit日志会不断追加数据,且在轮换未发生的情况下,如果间隔时间内多次运行expandaudit,则会重新读取上次运行时已读取的内容并进行处理。因此,通常会将expandaudit命令作为daily的批处理作业执行。然而,存在以下问题:首先,如果原始的Audit日志大小变大,则处理将变得非常重,其次,由于是批处理,无法实时进行处理。为解决这个问题,MapR 6.0引入了Audit Stream功能,使得可以实时地对Audit日志进行流处理。在下一篇后续文章中,我们将介绍Audit Stream功能,并提供一个使用示例。
关于审计流程
Audit Stream是用于处理Audit日志的功能。
上面的图表是来自MapR官方文档中的示例运行。它可用于实时报告、异常检测以及其他任务的触发等各种用途。
在默认设置下,MapR-ES将保留7天的数据,但当然也可以编辑此期限。
将数据产生到MapR-ES中的是hoststats进程,而消费则仅限于mapr用户。
启动审计流程
那么,让我们立即启动Audit Stream功能。
要启用Audit Stream,请将”mfs.enable.audit.as.stream”参数设置为1。
$ maprcli config save -values '{"mfs.enable.audit.as.stream":"1"}'
$ maprcli config load -json | grep audit.as.stream
"mfs.enable.audit.as.stream":"1",
请访问目标Volume,生成Audit日志。
产生Audit日志后,会自动创建目标流。
流路径为/var/mapr/auditstream/auditlogstream。
$ maprcli stream info -path /var/mapr/auditstream/auditlogstream -json
{
"timestamp":1544532065489,
"timeofday":"2018-12-11 07:41:05.489 GMT-0500 AM",
"status":"OK",
"total":1,
"data":[
{
"path":"/var/mapr/auditstream/auditlogstream",
"physicalsize":2031616,
"logicalsize":1269760,
"numtopics":12,
"defaultpartitions":1,
"ttl":604800,
"compression":"lz4",
"autocreate":true,
"produceperm":"u:mapr",
"consumeperm":"u:mapr",
"topicperm":"u:mapr",
"copyperm":"u:mapr",
"adminperm":"u:mapr",
"ischangelog":false,
"defaulttimestamptype":"CreateTime"
}
]
}
$ maprcli stream topic list -path '/var/mapr/auditstream/auditlogstream' -json
{
"timestamp":1543589952706,
"timeofday":"2018-11-30 09:59:12.706 GMT-0500 AM",
"status":"OK",
"total":12,
"data":[
{
"topic":"ov_auth_ov2",
"partitions":1,
"consumers":0,
"physicalsize":0,
"logicalsize":0,
"maxlag":0
},
{
"topic":"ov_auth_ov0",
"partitions":1,
"consumers":0,
"physicalsize":49152,
"logicalsize":24576,
"maxlag":0
},
{
"topic":"ov_fs_ov1",
"partitions":1,
"consumers":0,
"physicalsize":49152,
"logicalsize":24576,
"maxlag":0
},
{
"topic":"ov_auth_ov1",
"partitions":1,
"consumers":0,
"physicalsize":0,
"logicalsize":0,
"maxlag":0
},
{
"topic":"ov_fs_ov2",
"partitions":1,
"consumers":0,
"physicalsize":65536,
"logicalsize":32768,
"maxlag":0
},
{
"topic":"ov_fs_ov0",
"partitions":1,
"consumers":0,
"physicalsize":1875968,
"logicalsize":1589248,
"maxlag":0
},
{
"topic":"ov_db_ov1",
"partitions":1,
"consumers":0,
"physicalsize":49152,
"logicalsize":24576,
"maxlag":0
},
{
"topic":"ov_cldb_ov0",
"partitions":1,
"consumers":0,
"physicalsize":172032,
"logicalsize":122880,
"maxlag":0
},
{
"topic":"ov_db_ov0",
"partitions":1,
"consumers":0,
"physicalsize":827392,
"logicalsize":688128,
"maxlag":0
},
{
"topic":"ov_cldb_ov1",
"partitions":1,
"consumers":0,
"physicalsize":49152,
"logicalsize":24576,
"maxlag":0
},
},
{
"topic":"ov_cldb_ov2",
"partitions":1,
"consumers":0,
"physicalsize":3055616,
"logicalsize":2498560,
"maxlag":0
},
{
"topic":"ov_db_ov2",
"partitions":1,
"consumers":0,
"physicalsize":49152,
"logicalsize":24576,
"maxlag":0
}
]
}
我已经确认了如上所述的主题已经被创建。
主题名称将按照__的语法进行创建。
包括cldb、auth、fs、db,其中db将发布MapR-DB和MapR-ES的日志。
审计流的消耗
审核流程以ConsumerRecords类的对象形式发布到MapR-ES上。
因此,当进行消费时,需要将记录作为此对象读取。
此外,数据经过ID解密,因此需要在消费者内部根据路径进行解密,就像expandaudit命令一样。
关于解密API的详细信息,请参阅此页面。
现在,即使在MapR的官方文档中,也有关于Consumer示例的实现。我们将使用稍微更改的官方文档实现示例来验证Consumer的行为。
对官方文档的更改如下所示。
-
- Consumeしたレコードは標準出力に出すのではなく、MapR-DBに格納(デバッグ機能として標準出力機能も維持)
-
- クラスタと出力先のMapR-DBのパスをコマンドライン引数から指定可能
- systemdを使ってデーモン化
好的,让我们来实际进行测试。请在集群节点上执行以下操作。
$ git clone https://github.com/tgib23/AuditConsumer
$ cd AuditConsumer
$ javac -cp .:`mapr classpath` AuditConsumer.java -Xlint:deprecation
如果能够成功构建的话,首先手动执行一下试试看。
$ java -cp .:`mapr classpath` AuditConsumer -cluster ov -output_db_path /tmp/testdb -debug 1
让我们随便访问一下审核对象的卷后,确认在标准输出中是否会出现以下类似的日志?
{"timestamp":{"$date":"2018-12-11T14:04:19.148Z"},"operation":"DB_REGIONLOOKUP","uid":5000,"ipAddress":"10.10.75.127","volumeId":1662517,"VolumeName":"force_audit","tableFid":"2304.168.266532","FidPath":"/force_audit/db/46","status":0}
{"timestamp":{"$date":"2018-12-11T14:04:19.318Z"},"operation":"DB_PUT","uid":5000,"ipAddress":"10.10.75.81","volumeId":1662517,"VolumeName":"force_audit","columnFamily":"default","columnQualifier":"total_score","tableFid":"2304.168.266532","FidPath":"/force_audit/db/46","status":0}
{"timestamp":{"$date":"2018-12-11T14:04:19.318Z"},"operation":"DB_PUT","uid":5000,"ipAddress":"10.10.75.81","volumeId":1662517,"VolumeName":"force_audit","columnFamily":"default","columnQualifier":"PROP.power","tableFid":"2304.168.266532","FidPath":"/force_audit/db/46","status":0}
{"timestamp":{"$date":"2018-12-11T14:04:19.318Z"},"operation":"DB_PUT","uid":5000,"ipAddress":"10.10.75.81","volumeId":1662517,"VolumeName":"force_audit","columnFamily":"default","columnQualifier":"PROP.lead","tableFid":"2304.168.266532","FidPath":"/force_audit/db/46","status":0}
{"timestamp":{"$date":"2018-12-11T14:04:19.318Z"},"operation":"DB_PUT","uid":5000,"ipAddress":"10.10.75.81","volumeId":1662517,"VolumeName":"force_audit","columnFamily":"default","columnQualifier":"PROP.intellligence","tableFid":"2304.168.266532","FidPath":"/force_audit/db/46","status":0}
{"timestamp":{"$date":"2018-12-11T14:04:19.318Z"},"operation":"DB_PUT","uid":5000,"ipAddress":"10.10.75.81","volumeId":1662517,"VolumeName":"force_audit","columnFamily":"default","columnQualifier":"USERNAME","tableFid":"2304.168.266532","FidPath":"/force_audit/db/46","status":0}
{"timestamp":{"$date":"2018-12-11T14:04:19.000Z"},"operation":"LOOKUP","uid":5000,"ipAddress":"10.10.75.127","srcFid":"2304.32.266260","FidPath":"/force_audit/db/46","dstFid":"2304.168.266532","FidPath":"/force_audit/db/46","srcName":"46","volumeId":1662517,"VolumeName":"force_audit","status":0}
让我们在/tmp/testdb路径下创建一个表,并将相同的数据存储在该表中。让我们用Drill来进行确认。
$ sqlline -u jdbc:drill:drillbit=ov0 -n mapr -p mapr
0: jdbc:drill:drillbit=ov0> select * from dfs.`/tmp/testdb`;
+-------------------------------+--------------+---------------+------------------+---------+---------------------+-------+---------------+---------------------+---------------------+---------------------+----------+
| _id | VolumeName | ipAddress | operation | status | tableFidPath | uid | columnFamily | columnQualifier | dstFidPath | srcFidPath | srcName |
+-------------------------------+--------------+---------------+------------------+---------+---------------------+-------+---------------+---------------------+---------------------+---------------------+----------+
| 2018-12-11T13:50:30.916Z-821 | force_audit | 10.10.75.81 | DB_TABLEINFO | 0 | /force_audit/db/50 | 5000 | null | null | null | null | null |
| 2018-12-11T13:50:30.920Z-148 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/50 | 5000 | default | PROP.lead | null | null | null |
| 2018-12-11T13:50:30.920Z-288 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/50 | 5000 | default | total_score | null | null | null |
| 2018-12-11T13:50:30.920Z-36 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/50 | 5000 | default | PROP.power | null | null | null |
| 2018-12-11T13:50:30.920Z-664 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/50 | 5000 | default | PROP.intellligence | null | null | null |
| 2018-12-11T13:50:30.920Z-973 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/50 | 5000 | default | USERNAME | null | null | null |
| 2018-12-11T13:50:36.559Z-331 | force_audit | 10.10.75.81 | DB_TABLEINFO | 0 | /force_audit/db/49 | 5000 | null | null | null | null | null |
| 2018-12-11T13:50:36.574Z-699 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/49 | 5000 | default | USERNAME | null | null | null |
| 2018-12-11T13:50:36.574Z-884 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/49 | 5000 | default | total_score | null | null | null |
| 2018-12-11T13:51:23.190Z-432 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/49 | 5000 | default | PROP.lead | null | null | null |
| 2018-12-11T13:51:23.190Z-56 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/49 | 5000 | default | PROP.intellligence | null | null | null |
| 2018-12-11T13:51:23.190Z-572 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/49 | 5000 | default | PROP.power | null | null | null |
| 2018-12-11T13:51:23.190Z-813 | force_audit | 10.10.75.81 | DB_PUT | 0 | /force_audit/db/49 | 5000 | default | total_score | null | null | null |
已经被储存了呀。
顺便说一下,这个程序中指定”_id”键的方式是以时间加上三位随机ID的形式。
虽然很简单,但作为演示来说还是可以的。
让我们接下来将这个程序变成守护进程试试看。
$ sudo mkdir /opt/mapr/audit_consumer
$ sudo cp AuditConsumer* consumer.props /opt/mapr/audit_consumer/
请用指定的类路径(展开mapr类路径的字符串)、集群名称和输出数据库路径来修改AuditConsumer.service中的ExecStart。
$ sudo cp AuditConsumer.service /etc/systemd/system/
$ sudo systemctl enable AuditConsumer
$ sudo systemctl start AuditConsumer
由于这是流处理,建议以某种方式将其守护化。
总结
在后续部分中,我们介绍了AuditStream功能。通过使用该功能,不仅可以实现实时ID的解密,还可以实现实时分析,如检测非法访问等。我们实际上正在模拟访问情况,并计划在未来发布进行非法访问检测的示例等内容。