通过Elasticsearch的插件“Shield”和“Watcher”进行对非法访问的监视和审核
总而言之
大家是否正在使用Elasticsearch的插件?
目前,Elastic公司提供了一些插件,如”Marvel”、”Shield”和”Watcher”,在正式运营时都非常有用,可以说是必不可少的。
本次我们将利用Elasticsearch的付费插件”Shield”来输出Elasticsearch的审计日志,并使用”Watcher”从审计日志中检测到恶意访问并触发警报(发送邮件)。
一开始
盾是什么意思
这是一个链接:https://www.elastic.co/products/shield
它是Elasticsearch的安全插件。
通过使用Shield,您可以对Elasticsearch的访问进行身份验证和授权,
还可以设置IP过滤和审计日志输出等功能。
观察者指的是
公式网址:https://www.elastic.co/products/watcher
Watcher是Elasticsearch的检测警报插件。
通过使用Watcher,可以从注册在索引中的数据中检测特定的关键词,并执行诸如发送电子邮件等的操作。
在阅读本文之前
如果您想要了解有关Shield认证和授权等方面的详细信息,请参考我之前发布的这篇文章。
使用Elasticsearch插件”Shield”来确保ELK的安全性!尝试在Kibana上实现身份验证和授权。
环境信息
-
- OS:CentOS6.5 on VirtualBox + Vagrant
-
- Logstash 2.1.1
-
- Elasticsearch 2.1.0
-
- Kibana 4.3.0
- Java 1.8.65
审计证据输出
使用遮罩屏幕安装1
/usr/share/elasticsearch/bin/plugin install elasticsearch/shield/latest
需要設定輸出功率的問題。
由于默认情况下审计证据日志的输出是无效的,因此在elasticsearch.yml中添加以下内容。
shield.audit.enabled: true
设定输出目标
监审证据日志可选择”文件输出”和”导入到Elasticsearch索引”。可以在`shield.audit.outputs`中进行指定。本次选择了同时指定两种输出方式。
shield.audit.outputs: [index, logfile]
确认产出
完成設定后,重新启动Elasticsearch并确认审核跟踪日志的输出。
默认情况下,文件将输出到/var/log/elasticsearch/elasticsearch-access.log中。
[2015-12-19 04:04:36,480] [Taskmaster] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__indexing_audit_user], action=[indices:data/write/bulk]
[2015-12-19 04:04:36,480] [Taskmaster] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__indexing_audit_user], action=[indices:data/write/bulk[s]], indices=[.shield_audit_log-2015.12.19]
[2015-12-19 04:04:36,515] [Taskmaster] [transport] [access_granted] origin_type=[rest], origin_address=[127.0.0.1], principal=[kibana4_server], action=[cluster:monitor/nodes/info]
[2015-12-19 04:04:36,515] [Taskmaster] [transport] [access_granted] origin_type=[rest], origin_address=[127.0.0.1], principal=[kibana4_server], action=[cluster:monitor/nodes/info[n]]
[2015-12-19 04:04:36,526] [Taskmaster] [transport] [access_granted] origin_type=[rest], origin_address=[127.0.0.1], principal=[kibana4_server], action=[cluster:monitor/health], indices=[.kibana]
从Kibana中查看到Elasticsearch的导入情况,如下所示。
日志条目类型
只有在发生以下类型的事件时,才会生成审计证迹日志。
关于日志格式的问题
我将简单说明一下日志的格式。
[<时间戳>] [<本地节点信息>] [<层级>] [<条目类型>] <属性列表>
* <时间戳>…记录时间戳
* <本地节点信息>…输出日志的节点信息
* <层级>…与日志条目相关的层级(可为rest、transport、ip_filter之一)
* <条目类型>…条目类型(参见上述说明)
* <属性列表>…与事件相关的属性信息
异常访问检测和警报
下一步,使用Watcher来检测和发送电子邮件通知有关非法访问的信息。
本次将定义“非法访问”为“当日志类型为anonymous_access_denied的日志被输出到审计日志时”。
anonymous_access_denied指的是“由于请求被拒绝而输出的日志,原因是未附加认证令牌”。
观察者安装1
/usr/share/elasticsearch/bin/plugin install elasticsearch/watcher/latest
请重新启动Elasticsearch,并确认Watcher已经启动。
如果warcher_state为started,那就OK了。
由于已经安装了shield,所以请指定用户名和密码进行GET请求。
curl -XGET -u admin 'http://localhost:9200/_watcher/stats?pretty'
Enter host password for user 'admin':
{
"watcher_state" : "started",
"watch_count" : 0,
"execution_thread_pool" : {
"queue_size" : 0,
"max_size" : 0
},
"manually_stopped" : false
}
观看的定义
通过发送POST请求并添加Watcher索引来添加Watch定义。
curl -XPUT -u admin 'http://localhost:9200/_watcher/watch/log_error_watch' -d '{
"trigger" : {
"schedule" : {
"interval" : "10s"
}
}
, "input" : {
"search" : {
"request" : {
"indices" : [ ".shield_audit_log-*" ]
, "body" : {
"query" : {
"bool" : {
"must" : [
{ "match": { "event_type" : "anonymous_access_denied"}}
]
, "filter" : [
{ "range": { "@timestamp" : { "gte": "{{ctx.trigger.scheduled_time}}||-10s" }}}
]
}
}
}
}
}
}
, "condition" : {
"compare" : {
"ctx.payload.hits.total" : {
"gt" : 0
}
}
}
, "actions" : {
"email_admin" : {
"email": {
"to" : "<Your Mail Address>"
, "subject" : "【ERROR】Elasticsearch不正アクセス({{ctx.payload.hits.total}}件)"
, "body" : {
"text" : "{{ctx.payload.hits.hits}}"
}
}
}
}
}'
以上的定义是在每10秒钟的间隔内搜索已注册的Elasticsearch审计日志索引,并在检测到非法访问日志时通过电子邮件进行通知。
让我们按照顺序来看下去吧。
Watch的定义可以大致分为四个部分,即trigger(触发器)、input(输入)、condition(条件)和actions(动作)。
触发 (chū fā)
在这里,我们使用计划触发器以10秒的间隔启动监视器来定义触发器。
"trigger" : {
"schedule" : {
"interval" : "10s"
}
}
请参考以下链接:https://www.elastic.co/guide/en/watcher/current/trigger.html
请给我一个中文的翻译选项:
输入
输入定义了Watcher的审计目标。
这里从.shield_audit_log索引中注册的文档中提取event_type字段为anonymous_access_denied的内容。
通过筛选时间戳大于「Watcher启动被调度的时间 – 10秒」的日志,以避免对已经检测过的日志进行重复检测。
"input" : {
"search" : {
"request" : {
"indices" : [ ".shield_audit_log-*" ]
, "body" : {
"query" : {
"bool" : {
"must" : [
{ "match": { "event_type" : "anonymous_access_denied"}}
]
, "filter" : [
{ "range": { "@timestamp" : { "gte": "{{ctx.trigger.scheduled_time}}||-10s" }}}
]
}
}
}
}
}
}
请参考以下链接获取更多信息:https://www.elastic.co/guide/en/watcher/current/input.html
状态
在这里,我们定义了只有当输入的项目数大于或等于0时才执行操作的条件。
"condition" : {
"compare" : {
"ctx.payload.hits.total" : {
"gt" : 0
}
}
}
请查阅:https://www.elastic.co/guide/en/watcher/current/condition.html
行动
当检测到watch对象时,定义相应的操作。
操作可以包括发送邮件、与Slack集成、与Hipchat集成、输出日志等多种方式,
但在此处我们选择发送邮件操作。
"actions" : {
"email_admin" : {
"email": {
"to" : "<Your Mail Address>"
, "subject" : "【ERROR】Elasticsearch不正アクセス({{ctx.payload.hits.total}}件)"
, "body" : {
"text" : "{{ctx.payload.hits.hits}}"
}
}
}
}
参考:https://www.elastic.co/guide/en/watcher/current/actions.html
请查看以下链接,获取更多关于操作的详细信息。
需要在elasticsearch.yml中设置邮件帐户才能发送电子邮件。
本次将使用GMail的SMTP服务器。三十二
watcher.actions.email.service.account:
gmail_account:
profile: gmail
smtp:
auth: true
starttls.enable: true
host: smtp.gmail.com
port: 587
user: <Google Account>
password: <Google Password>
参考:https://www.elastic.co/guide/en/watcher/current/email-services.html#gmail
确认
完成此步骤后,请重新启动Elasticsearch,以验证审计追踪日志的检测和邮件发送。
非法访问
没有认证令牌,无法调用Elasticsearch的API。会出现认证错误。
curl -XGET 'http://localhost:9200'
{"error":{"root_cause":[{"type":"security_exception","reason":"missing authentication token for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"shield\""}}],"type":"security_exception","reason":"missing authentication token for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"shield\""}},"status":401}
监审证据日志确实输出到Elasticsearch的.shield_audit_log索引中。
[2015-12-20 22:56:50,628] [Plug] [rest] [anonymous_access_denied] origin_address=[::1], uri=[/]
电子邮件通知
当我查看Gmail时,确实收到了警报邮件。非常好,一切都很顺利。
觀看定義刪除。
将不再需要的Watch定义按如下方式删除。
curl -XDELETE -u admin 'http://localhost:9200/_watcher/watch/log_error_watch'
总结
你觉得如何呢?继前一篇文章之后,我试着使用Elasticsearch的插件来提升安全性。如果Watcher的定义可以在Kibana上通过图形界面进行,那就太好了。如果有机会的话,我还想尝试与Slack和Hipchat进行整合。
由于错过了Elasticsearch的Advent Calender活动的第一天,真的抱歉m(_ _)m
如果您有相关知识或经验的话
如果将Shield的审计痕迹日志输出设置为“启用”,并将输出目标指定为“导入到Elasticsearch索引”,然后启动Kibana,将会导致审计痕迹日志的索引导入进入无限循环。
行为是这样的,Kibana将读取索引的操作作为审计日志导入到索引中,然后Kibana又会进一步读取该索引…循环往复。
也许将审计痕迹日志的输出级别设置为ERROR等可以解决问题,但如果有任何见解,请不吝赐教。
[2015-12-20 23:16:39,379] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__indexing_audit_user], action=[indices:data/write/bulk[s]], indices=[.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,222] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/write/index], indices=[.triggered_watches]
[2015-12-20 23:16:49,277] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,277] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,279] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,281] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,285] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,287] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,293] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,295] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,297] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,298] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,300] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,302] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/read/search[phase/query]], indices=[.shield_audit_log-2015.12.19,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,305] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/write/index], indices=[.watch_history-2015.12.20]
[2015-12-20 23:16:49,344] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__watcher_user], action=[indices:data/write/delete], indices=[.triggered_watches]
[2015-12-20 23:16:49,395] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__indexing_audit_user], action=[indices:data/write/bulk]
[2015-12-20 23:16:49,397] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__indexing_audit_user], action=[indices:data/write/bulk[s]], indices=[.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,397] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__indexing_audit_user], action=[indices:data/write/bulk[s]], indices=[.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20]
[2015-12-20 23:16:49,398] [Plug] [transport] [access_granted] origin_type=[local_node], origin_address=[127.0.0.1], principal=[__indexing_audit_user], action=[indices:data/write/bulk[s]], indices=[.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20,.shield_audit_log-2015.12.20]
只提供其他参考来源,不包括官方网站。
-
- http://dev.classmethod.jp/cloud/aws/using-elasticsearch-plugin-shield/
- http://dev.classmethod.jp/cloud/aws/using-elasticsearch-plugin-watcher/
在安装任何插件之前,必须先安装许可证/license,方法是执行/usr/share/elasticsearch/bin/plugin install elasticsearch/license/latest。
在Gmail的设置中,需要将“访问低安全性应用程序”设为“启用”。
由于尝试从Watcher发送电子邮件时出现了UnsupportedDataTypeException错误,我们正在执行此文章中提到的解决方法。是否是个问题?