背景信息
在 日志服务与SIEM(如Splunk)集成方案实战 中,作者已经就阿里云日志服务及审计相关日志的现状做了介绍,并实现了“使用SLS消费组构建程序,从SLS进行实时消费,然后通过Splunk API(HEC)来发送日志给Splunk。”
本文主要介绍如何让阿里云日志服务(SLS)通过Splunk Add-on与您的Splunk服务实现日志对接, 以便确保阿里云上的所有法规、审计、与其他相关日志能够导入到您的安全运维中心(SOC)中。
整体介绍
阿里云日志服务Splunk Add-on从阿里云日志服务(SLS)采集日志并投递到Splunk。主要的特性如下:
- 通过Splunk data input创建SLS消费组,并从阿里云日志服务进行实时日志消费。
- 将采集到的日志通过Splunk私有协议(private protocol)或者HTTP Event Collector(HEC)投递到Splunk indexer。
概念介绍
SLS相关概念
- 日志库(Logstore):日志服务中日志数据的采集、存储和查询单元。每个日志库隶属于一个项目,且每个项目可以创建多个日志库。您可以根据实际需求为某一个项目生成多个日志库,其中常见的做法是为一个应用中的每类日志创建一个独立的日志库。
- 分区(Shard):Logstore读写日志必定保存在某一个分区(Shard)上。每个日志库(Logstore)分若干个分区,每个分区由MD5左闭右开区间组成,每个区间范围不会相互覆盖,并且所有的区间的范围是MD5整个取值范围。
- 服务入口(Endpoint):日志服务入口是访问一个项目(Project)及其内部日志数据的 URL。它和 Project 所在的阿里云区域(Region)及 Project 名称相关。包括公网服务入口、经典/VPC网络服务入口、全球加速服务入口。
- 访问密钥(AccessKey):阿里云访问密钥是阿里云为用户使用 API(非控制台)来访问其云资源设计的安全口令。您可以用它来签名 API 请求内容以通过服务端的安全验证。
- 消费组(Consumer Group):一个消费组由多个消费者构成,同一个消费组下面的消费者共同消费一个logstore中的数据,消费者之间不会重复消费数据。
- 消费者(Consumer):消费组的构成单元,实际承担消费任务,同一个消费组下面的消费者名称必须不同。
Splunk相关概念
- Add-on:运行在Splunk上提供特定功能的组件。
- Heavy forwarder:Splunk的转发器。
- Indexer:Splunk的索引器。
- HEC:Splunk的Http事件接收器(Splunk Http Event Collector), 一个 HTTP(s)接口,用于接收日志。
更多Splunk概念详见:Splunk基础
机制介绍
- 一个data input创建一个消费者进行日志消费。
- 一个消费组由多个消费者构成,同一个消费组下面的消费者共同消费一个Logstore中的数据,消费者之间不会重复消费数据。
-
一个Logstore下面会有多个Shard。
- 每个Shard只会分配到一个消费者。
- 一个消费者可以同时拥有多个Shard。
- 所创建的消费者名字是由消费组名、host名、进程名、event协议类型组合而成,保证同一消费组内的消费者不重名。
操作步骤
准备工作
- 获取日志服务的AccessKey。
您可以通过阿里云RAM获取日志服务Project的AccessKey,详情请参见访问密钥和访问密钥配置。
您可以通过权限助手配置RAM权限,详情请参见配置权限助手。常用的RAM配置如下:
说明 为您的日志服务Project名称,为您的日志服务Logstore名称,请根据实际情况替换,名字替换支持通配符*。
{
"Version": "1",
"Statement": [
{
"Action": [
"log:ListShards",
"log:GetCursorOrData",
"log:GetConsumerGroupCheckPoint",
"log:UpdateConsumerGroup",
"log:ConsumerGroupHeartBeat",
"log:ConsumerGroupUpdateCheckPoint",
"log:ListConsumerGroup",
"log:CreateConsumerGroup"
],
"Resource": [
"acs:log:*:*:project/<Project name>/logstore/<Logstore name>",
"acs:log:*:*:project/<Project name>/logstore/<Logstore name>/*"
],
"Effect": "Allow"
}
]
}
- Splunk版本及运行环境检查
请确保使用最新的Add-on版本。
操作系统:Linux、Mac OS、Windows。
Splunk版本:Splunk heavy forwarder 8.0+;Splunk indexer 7.0+。
- 配置Splunk HTTP Event Collector,详情请参见Configure HTTP Event Collector on Splunk Enterprise。
如果需要使用HEC来发送event,请确保HEC配置成功。如果选择Splunk私有协议,则可以跳过该步骤。
需要注意的是:目前创建 Event Collector token时,不支持开启indexer acknowledgment功能。
安装Add-on
这里提供两种通过Splunk web UI安装Splunk Add-on的方式:
- 管理应用->浏览更多应用->搜索“Splunk Add-on for Alibaba Cloud Log Service”->点击“安装”->点击“重启 Splunk服务”。
- 管理应用->从文件安装应用->上传.tgz文件,可以从https://splunkbase.splunk.com/apps下载->选择“升级应用程序选中它将覆盖已存在的应用程序”->点击“上载”按钮->点击“重启 Splunk服务”。
配置Add-on
通过Splunk Web UI 选择应用,进入"Splunk Add-on for Alibaba Cloud Log Service"界面。
全局账号配置
在“配置-Account”界面, 设置SLS AccessKey。需要注意的是这里配置的用户名、密码分别对应SLS的AccessKey ID、AccessKey Secret。
日志级别配置
在"配置-Logging" 页,可以设置Add-on的运行日志级别。
添加data input
在“输入”界面,点击"Create New Input"可以创建新的data input。具体的配置参数如下:
- 阿里云日志服务基本参数:包括消费组及相关的连接信息。
- Splunk参数:event协议和一些附加参数。
参数 | 必选项 & 格式 | 描述 | 取值举例 |
---|---|---|---|
名字 | Yes, String | 全局唯一的Data input名 | |
间隔 | Yes, Integer | Splunk data input退出后的重启时间。单位:s。 | 默认值: 10(s) |
索引 | Yes, String | Splunk索引 | |
SLS AccessKey | Yes, String | 阿里云访问密钥由AccessKeyId、AccessKeySecret组成。需要注意的是这里配置的用户名、密码分别对应SLS的AccessKey ID、AccessKey Secret。 | 全局账号配置中配置的"Account name"。 |
SLS endpoint | Yes, String | 阿里云日志服务入口。关于HTTPS的更多信息,详见“规格及安全--HTTPS”部分。 | cn-huhehaote.log.aliyuncs.com 或 https://cn-huhehaote.log.aliyuncs.com |
SLS project | Yes, String | 日志服务Project。 | - |
SLS logstore | Yes, String | 日志服务Logstore。 | - |
SLS consumer group | Yes, String | 日志服务消费组。扩容时,多个data input需要配置相同的消费组名称。更多信息详见“机制”部分。 | - |
SLS cursor start time | Yes, String | 消费起始时间。该参数只有消费组首次创建时有效。非首次创建日志都是从上次的保存点开始消费。注意:这里的时间是日志到达时间。 | 取值:“begin”、“end”、“ISO格式的时间(例如2018-12-26 0:0:0+8:00)”。 |
SLS heartbeat interval | Yes, Integer | SLS消费者与Sever间的心跳间隔。单位:s。 | 默认值: 60(s) |
SLS data fetch interval | Yes, Integer | 日志拉取间隔,如果日志频率较低,建议不要设的太小。单位:s。 | 默认值: 1(s) |
Topic filter | No, String | Topic过滤字符串,以;间隔区分多个过滤的Topic。如果日志的topic被命中,则该日志会被忽略掉,从而不能投递到Splunk。 | “TopicA;TopicB”意味着topic为“TopicA”or “TopicB”的日志将被忽略。 |
Unfolded fields | No, Json | Json格式的topic到字段列表的映射关系。{"topicA": ["field_nameA1", "field_nameA2", ...], "topicB": ["field_nameB1", "field_nameB2", ...], ...} | {"actiontrail_audit_event": ["event"] } 意味着对于topic为 "actiontrail_audit_event"的日志, 该日志的 "event"字段将从字符串展开成Json格式。 |
Event source | No, String | Splunk event数据源 | - |
Event source type | No, String | Splunk event数据源类型 | - |
Event retry times | No, Integer | 0表示无限重传。 | 默认值: 0次 |
Event protocol | Yes | Splunk event发送协议。如果选择私有协议,后续参数可以忽略。 | HTTP for HEC;HTTPS for HEC;Private protocol |
HEC host | Yes,只有Event protocol选择HEC时有效,String。 | HEC host。 | - |
HEC port | Yes,只有Event protocol选择HEC时有效,Integer。 | HEC端口。 | - |
HEC token | Yes,只有Event protocol选择HEC时有效,String。 | HEC token。 | |
HEC timeout | Yes,只有Event protocol选择HEC时有效,Integer。 | HEC超时时间。 | 默认: 120(s) |
开始工作
查询数据
首先确保创建的data input是启动状态。之后通过Splunk Web UI选择"App: Search & Reporting",将可以查到采集到的审计日志。
内部日志
- 使用
index="_internal" | search "SLS info"
可以查询SLS相关的信息。 - 使用
index="_internal" | search "error"
可以查询运行时的错误信息。
性能及安全
性能规格
该Add-on的性能及数据传输的吞吐量收到如下因素的影响:
- SLS endpoint:可以使用公网、经典/VPC网络或者全球加速服务入口。一般情况下,建议采用经典/VPC网络入口。
- 带宽:包括SLS与Splunk heavy forwarder间的带宽,和Splunk heavy forwarder与indexer之间的带宽。
- Splunk indexer处理能力:indexer的数据接收能力。
- shard数:对于单个SLS logstore,配置的shard数越多,数据传输能力越强。用户需要根据原始日志的生成速率确定Logstore的shard数。
- Splunk data input配置数:对于同一logstore,配置越多的data input(相同的消费组),吞吐量越大。需要注意,消费者的并发受到SLS logstore shard数的影响。
- Splunk heavy forwarder占用的CPU core数和内存:一版情况下一个Splunk data input需要消耗1~2G内存,占用1个CPU core。
当上述条件满足的情况下,一个Splunk data input可以提供1~2M/s的日志消费能力。
实际使用时,用户需要根据原始日志的生成速率确定Logstore的shard数,并创建相应的data input。此外,SLS的endpoit、带宽、Splunk的接收数据能力都是考虑的重要因素。
例如,一个Logstore有10M/s的日志生产能力,需要至少拆分出10个split,并且在Add-on中配置10个data input。如果是单机部署,需要具备10个空闲CPU core及12G的内存。
高可用性
消费组将检测点(check-point)保存在服务器端,当一个消费者停止,另外一个消费者将自动接管并从断点继续消费。可以在不同机器上创建Splunk data input,这样在一台机器停止或者损坏的情况下,其他机器上的Splunk data input创建的消费者可以自动接管并从断点进行消费。理论上,为了备用,也可以在不同机器上启动大于 Shard 数量的Splunk data input。
HTTPS
- SLS
如果服务入口(endpoint)配置为https://
前缀,如https://cn-beijing.log.aliyuncs.com
,程序与日志服务的连接将自动使用HTTPS加密。服务器证书 *.aliyuncs.com 是 GlobalSign 签发,默认大多数 Linux/Windows 的机器会自动信任此证书。如果某些特殊情况,机器不信任此证书,可以参考这里下载并安装此证书。 - Splunk
为了使用HTTPS的HEC能力,需要在Splunk HEC全局配置界面打开SSL功能。
AccessKey存储保护
SLS的AccessKey、Splunk的HEC token等关键信息,都保存着Splunk保密存储中,所以不用担心泄漏风险。
Add-on开发流程
阿里云日志服务Splunk Add-on使用Splunk提供的Add-on Builder工具开发的,使用Add-on Builder可以帮助开发者高效构建和验证add-on。本章节将介绍如何开发一个进行Data Collection的Add-on。
安装Splunk Add-on builder
从Splunkbase下载Splunk Add-on Builder,并完成安装。
创建Add-on
进入“Add-on builder”首页,并点击“New Add-on”。之后填写Add-on的描述信息。
配置Data Collection
点击“Configure Data Collection” -- “New input” -- “Modular input using myPython code”进入Create Data Input页面。
界面配置
- Data input properties:Source type name及Input name的命名。
-
Data input parameters:数据输入参数配置。
- 将左侧Component Library中的元素拖拽到中间Data Input Parameters区域,然后在右侧Property Editor进行相关属性的编辑。
- 支持文本框、下拉菜单等。
- Global Account需要与Add-on setup parameters中的Global account settings配合使用。
- Add-on setup parameters:启动参数配置。支持日志级别及全局账号等配置信息。
实现及Test
之后Add-on builder将会生成代码框架,并进入Test界面。
- 配置Setup参数
- 配置Input参数并测试。
下图:左侧是前面配置生成的操作界面;中间为生成的代码;右侧为点击Test按钮后的测试结果。
关键函数
-
use_single_instance_mode表示是否使用单例模式。
- 多例模式是针对于每一个data input都会创建一个实例。
- 单例模式多所有的data input只创建一个实例,需要开发者实现对多个data input的处理。
- 多例模式是默认行为,将use_single_instance_mode的注释去掉,就会开启单例模式。
# 多例模式实现
# The following example writes a random number as an event. (Multi Instance Mode)
# Use this code template by default.
import random
data = str(random.randint(0,100))
event = helper.new_event(source=helper.get_input_type(), index=helper.get_output_index(), sourcetype=helper.get_sourcetype(), data=data)
ew.write_event(event)
# 单例模式实现
# 需要使用者通过get_input_stanza_names获取到所有到input,并作为参数获取当前data input对应的index及sourcetype信息。
# The following example writes a random number as an event for each input config. (Single Instance Mode)
# For advanced users, if you want to create single instance mod input, please use this code template.
# Also, you need to uncomment use_single_instance_mode() above.
import random
input_type = helper.get_input_type()
for stanza_name in helper.get_input_stanza_names():
data = str(random.randint(0,100))
event = helper.new_event(source=input_type, index=helper.get_output_index(stanza_name), sourcetype=helper.get_sourcetype(stanza_name), data=data)
ew.write_event(event)
-
validate_input
- 针对于Data input parameters的输入校验。如果校验失败,可以raise错误,之后界面配置就会提示失败。
-
collect_events实现
- 核心的数据处理逻辑。开发者可以自行开发相关逻辑进行数据收集及数据转发。
- helper参数可以获取到Data input的所有配置参数信息。具体函数详见“Python helper functions”。
- ew参数可以通过Splunk私有协议,将event发送给Indexer。当然也可以绕过ew,通过HEC向indexer发送数据。
-
处理模式
- 可以不退出,一直处理。开发者可以根据自己的需求做sleep或者等待相应时间的处理。
- 如果处理完一批数据后退出,则会在data input “间隔”参数配置的时间后重启。
阿里云日志服务Add-on的实现
- collect_events中通过ConsumerWorker创建了消费组,对指定的SLS logstore进行实时消费。
- 对SLS实时消费获取的数据,通过注册给ConsumerWorker的processor经过简单的数据加工后,通过HEC或者ew将数据发送给indexer。
- collect_events不做退出,持续处于消费SLS数据的状态。