亚马逊云科技 WAF 部署小指南(三):使用 OpenSearch 进行 WAF 安全调查

94504177fb6ba03ae6c9861d1219f24e.gif

 

前文提要

❖ 亚马逊云科技 WAF 部署小指南(一):WAF原理、默认部署及日志存储

❖ 亚马逊云科技 WAF 部署小指南(二):使用经济实用的 Log Insights 进行日志分析

点击上方链接即可【阅读】!

 

方案介绍

当我们按照 WAF 部署小指南(一) 构建好 WAF 的架构以后。日常安全运维的工作也要随之展开。在 WAF 部署小指南(一) 、(二) 中我们已经介绍了两种日志存储归档和查询的方法,分别是 S3存储+Athena 查询以及 Log insight 查询的方法。这两种方法成本比较低。适合查询工作不频繁的使用场景。

动态资源和数据资源丰富的网站,由于对攻击者具有比较大的吸引力。需要根据安全事件响应的要求开展专业的安全运营工作。这时我们就需要一个安全日志分析系统(SIEM)来帮助我们更高效的完成日常的安全日志初步分析,以及深入分析的工作。由于这些工作对于这一类组织发生的频度较高。所以通常由承担安全运营职责的专职人员来完成,而且用户通常会选择以图形化菜单操作为主的方式完成日志分析和调查的工作。从而提高每一个安全事件响应调查的效率。满足组织对安全调查响应的服务时效要求。

Amazon WAF 可以支持与主流的图形化调查 SIEM 产品如OpenSearch, Elastic Search, Splunk, Sumo Logic 的集成。本文我们将主要介绍如何快速的启用亚马逊云科技的 OpenSearch 作为 WAF 的 SIEM 平台。快速开展安全运营工作。

本文的环境搭建完成后,您可以对Amazon WAF日志图形化分析以及安全运营有一个清楚的了解。本文为了让大家对Amazon WAF 及 SIEM 系统有一个系统的认识。特意演示了每一个组件手动操作配置的步骤,并解释了技术原理。如果想要更快部署,亚马逊云科技有一个专门的Log hub解决方案,可以用 Cloudformation 自动化部署一套和本方案使用体验完全一致、兼具安全和成本灵活性的架构。对于安全,定制化有更高要求的组织。Log hub 也很适合。目前已经有很多用户升级到了 Log hub 方案。具体可以参考下周发布的 WAF 部署小指南 (四) 。

内容简介

本文分为六个步骤为您讲述如何创建使用 OpenSearch 进行WAF安全调查的环境。

  • 步骤一: 按照WAF部署小指南 (一) 的步骤完成 WAF 的部署,确保通过 WAF 能够访问后端的 Echo-Server 网页。

  • 步骤二: 创建 OpenSearch 访问环境。

  • 步骤三: 导入 OpenSearch Dashboard

  • 步骤四: 创建 Kinesis Firehose, 将 WAF 日志转发到 OpenSearch 集群中

  • 步骤五: 映射 Firehose IAM Role 到 OpenSearch 用户

  • 步骤六: 使用 OpenSearch Dashboard,开展 WAF 日志调查工作

架构图:

d59044b0b617ab6907acf5c7d2f62cc1.png

步骤一:完成 Amazon WAF 的部署

按照 WAF 部署小指南 (一) 的步骤完成 WAF 的部署,确保通过 WAF 能够访问后端的 Echo-Server 网页。

步骤二:创建 OpenSearch 访问环境

1. 登录亚马逊云科技控制台,选择 OpenSearch 服务,选择 Create domain:

2. 选择 Production (生产环境),并选择1.1版本

4bf8f2b78bc8e95d1b3a63a4939720af.png

3. 等待15分钟左右,OpenSearch 节点准备好了以后进行下一步

d20a789c9a8a713fb04681d9dc0d14e2.png

4. 完成以后得到 OpenSearch Dashboards URL:

9bf15cceb804fe49706c3eaf1910adb7.png

8537fd23b02cd60bb5393d4e8a83ca13.png

5. 点击Dashboard URL进入 login 状态。输入创建 dashboard 时输入的用户名密码

6. 选择 Global tanent:

d43f8c5e8d60016b5b6443f88634ae9b.png

注意如果选错了,可以到右上角切换 tenant 改过来。Private tenant 各用户的数据不能共享。不适合 SIEM 的场景。

4bfe3019f2ae936fac04ff439e07bc4d.png

这样我们就准备好了 OpenSearch 的日志存储集群。

步骤三:导入 OpenSearch Dashboard

准备好了 OpenSearch 的集群,我们就拥有了一个可以通过 HTTP API 接口注入日志由 OpenSearch 进行索引的日志搜索平台。纯日志的搜索已经可以通过 Discover 菜单开展了。为了使得安全日志可以使用图形化界面进行搜索。我们需要导入 dashboard, 为图形化日志分析做准备:

1. 按照下图导入 Dashboard 的 ndjson 文件
*dashboard的ndjson文件链接在这里https://d1p2gj1617sb0r.cloudfront.net/blog/sample-waf-dashboard-opensearch.ndjson。

25b818f72b0405025d4d494cb40390cb.png

点击导入的 dashboard,已经可以看到 WAF dashboard 的框架。下面我们再把 OpenSearch 的输入 Index Template 设定一下:

08fc69e77d79389953d223ff8893d8df.png

步骤四: Index Template 的设定

Index Template 的设定是让 OpenSearch 在对 WAF 输入的日志进行索引写入的时候。对每个 json 单元做不同的数据类型设定。以便后面查询的时候可以根据特定字段来进行查询和汇总。这个部分如果预先不设定好,有些 Dashboard 的图形化显示会不能正常工作。

*注意我们下周即将发布的 WAF 部署小指南 (四) 的 Log hub 解决方案里这部分工作都是自动完成的。有兴趣大家可以尝试。

*如果 Mapping 设置未完成而日志已经写入。则已经写入的日志不能有效搜索。需要等下一个 index 周期(一小时或者一天)以后,新的 index 生成才能生效。

1. 点击 OpenSearch 的 Dev Tool。

83ac6bd517fcc6ac3628cd5d61797ea8.png

2. 在左边边框输入我们准备好的 Mapping 设置,得到“Acknowledged”表示设置成功了。

*注意我们这里的 json 设置是对每个 WAF 日志字段做过精细调整的。目的是把 WAF 日志的可搜索性再提高一些。所以设置的 json 文件会比较长。

具体的设置命令由于太长放在附录一里。

b4d321f6d058ee742e680f167d8c0563.png

至此,我们的 OpenSearch 分析日志的准备工作基本完成。可以开始做 WAF 日志的设定,把日志引入 OpenSearch 了。

步骤四: 创建 Kinesis Firehose, 将 WAF 日志转发到 OpenSearch 集群中

1. 找到我们在 WAF 部署小指南 (一) 准备的 WAF Web ACL。把日志输出转到步骤二创建的 OpenSearch 集群里。

92304c4b2eb19faf1bdf51f8502cdeac.png

2. 创建一个新的 Kinesis Data Firehose Delivery stream:

 注意这里的 Delivery stream 的名称仍然需要以 aws-waf-logs- 开始。

dac56d4e007ae4f74a67fb746c34bc29.png

20e3a2b02ef69a858a4bf8f6b76ec92f.png

等待2分钟左右 Delivery Stream 创建完毕。

3. 创建好以后关联到 WAF logging 设置里。

b41d4d586e847674ae3b092490d268db.png

步骤五:映射 Firehose IAM Role 到 OpenSearch 用户

完成这个工作以后,我们需要把 Firehose Delivery Stream 的 IAM Role 映射到 OpenSearch 的用户里。从而使得 Firehose 写入 OpenSearch 日志的动作不被拒绝。

1. 获取 Kinesis Delivery Stream 的 IAM Role ARN:

759ff0618e4050cf5990cbebdd253ca5.png

6727045d744e50be89e57e5641f4a81b.png

2. 点击 IAM Role 进入 IAM 界面拷贝 Role ARN。

得到类似arn:aws:iam::123456789000:role/service-role/KinesisFirehoseServiceRole-aws-waf-logs-us-east-1-1234567890406 的 IAM Role ARN。这是 Firehose 做写入动作的服务角色。下面需要在 OpenSearch 里赋予它写入 OpenSearch 的能力。

509c7260c97e49ead42c87e4bc74883a.png

3. 进入之前的 OpenSearch  左侧菜单点击 OpenSearch Plugins – Security – Roles – all_access:

805334d5380d2660321b111b276ee846.png

5d4636cfd48fa21d59380ffd281364d1.png

4. 点击 Mapped users:

e63f21472c22298fd671d917bb4790bf.png

5. 进入 Manage Mapping 设置加入 Kinesis Firehose 的 IAM ARN

8558dd78b16765b2a22f0583caad94e3.png

6. 添加 Backend roles,填入之前的 Firehose IAM Role ARN “arn:aws:iam::123456789000:role/service-role/KinesisFirehoseServiceRole-aws-waf-logs—us-east-1-1234567890406”. 点击 Map ,完成添加动作。

85b7c278eb2227ac9c0bbc34ff94ec81.png

注意以上步骤如果不做,我们的 OpenSearch 内部是看不到日志的。并且会在 Delivery Stream 的如下位置看到 OpenSearch 返回的错误信息:

76a73efb848ac5f54b435fe4802966bb.png

具体错误信息如下:

Error received from the Amazon OpenSearch Service cluster. {"error":{"root_cause":[{"type":"security_exception","reason":"no permissions for [indices:data/write/bulk] and User [name=arn:aws:iam::123456789000:role/service-role/KinesisFirehoseServiceRole-aws-waf-logs—us-east-1-1234567890000, backend_roles=[arn:aws:iam::123456789000:role/service-role/KinesisFirehoseServiceRole-aws-waf-logs—us-east-1-1234567890000], requestedTenant=null]"}],"type":"security_exception","reason":"no permissions for [indices:data/write/bulk] and User [name=arn:aws:iam::123456789000:role/service-role/KinesisFirehoseServiceRole-aws-waf-logs—us-east-1-1234567890000, backend_roles=[arn:aws:iam::123456789000:role/service-role/KinesisFirehoseServiceRole-aws-waf-logs—us-east-1-1234567890000], requestedTenant=null]"},"status":403}

*左滑查看更多

我们在配置中遇到这个错误的技术人员不在少数。虽然大家经过仔细分析,最终都解决了这个问题。但也花了不少时间。所以特别在这里着重强调一下。

步骤六:使用 OpenSearch Dashboard,开展 WAF 日志调查工作

完成以上工作以后,我们的 WAF 日志分析系统就基本完成了。

现在来看看整体的 Dashboard 效果:

1. 首先我们会有全局的一个了解。知道 WAF 在过去的特定时间段允许和拒绝的请求情况。并且可以根据 WAF ACL Rule 的匹配来做特定的检查。注意这里我们是全量的日志分析。

1c56c06c8b48bcec9a699db6b99272d3.png

2. 然后,对于要进行深入安全调查工作的人员,我们主要会使用下面一个表:

6ded884040865a9089cba05e9adc13ca.png

3. 现在我们来用点击的方式制作几个过滤条件来做组合查询。

首先选择 Block 的 WAF 请求:

4c5c622c675be120f1ecd870c441f711.png

然后选择表中的 httpRequest.country。点击浮窗里的+号。即过滤同是来自法国的请求。

39807c8e052f3e3f86bd8156ea2cf06e.png

然后我们添加第三个条件,选择 httpRequest.clientIp。点击浮窗里的 – 号。即过滤除了来自92.42.109.58 的 client 请求。

c2b7231b50ed1fe0cf514ccc9bff582e.png

三个过滤条件叠加查询的结果,让我们了解到来自法国被阻断的请求中还有21条来自另外一个 clientIp 的请求:

02aa30967458103e6b2a77da2c990df9.png

值得一说的是,Dashboard 里的构成的三个过滤条件,都是以 DQL 这种 json 格式的查询语句来构成的。执行下面的操作可以看到这些语句:

a3b7432606c66235ed799ac3b9320bbe.png

7cea4384ed779e379d27a2f5f00c5f02.png

6b036ec4c2839a68a0ab9c71fdc68d58.png

b3b6e4533dcf7c83e409b77de00b4b91.png

可以看到,每一个条件都是以 DSL 的 json 格式表达出来的。有了 dashboard, 我们就可以把灵活的查询语言以拖拉拽的方式组合成一个复杂的查询策略。完成我们每天不同的查询任务。

小结

通过以上的步骤,我们使用亚马逊云科技的 OpenSearch 创建了一个 WAF 的日志分析系统。这个系统,对于有安全运营需求的企业是非常必要的。通过搭建这个系统,我们了解了 WAF 日志如何通过 Kinesis Firehose 导入。如何创建一个基于 OpenSearch 的托管日志分析平台。导入我们准备好的 WAF 日志分析 Dashboard。并完成 OpenSearch index template 的设定,保证 WAF 日志的有效搜索。最后我们演示了如何用鼠标点击的方式完成一个比较复杂的日志搜索任务,在 Dashboard 上成功显示了搜索结果。

有了这个日志分析系统,我们就可以以无代码的方式完成安全运营的工作了。本文的操作略显复杂,但比起从安装 ELK 套件开始搭建一个日志分析平台还是简单了很多。如果想要进一步简化,我们可以参考下周即将发布的 WAF 部署小指南 (四) ,尝试使用自动化部署的 Log hub 解决方案。

附录一

OpenSearch WAF 日志 index mapping 的设置:

PUT _index_template/awswaf-waf-logs
    {
    "index_patterns": [
        "awswaf-waf-*"
    ],
    "template": {
        "settings": {
            "index": {
                "number_of_shards": "5",
                "number_of_replicas": "1"
            }
        },
        "mappings": {
            "properties": {
                "terminatingRuleId": {
                    "type": "keyword"
                },
                "terminatingRuleType": {
                    "type": "keyword"
                },
                "ruleGroupList": {
                    "properties": {
                        "terminatingRule": {
                            "properties": {
                                "action": {
                                    "type": "keyword"
                                },
                                "ruleId": {
                                    "type": "keyword"
                                }
                            }
                        },
                        "ruleGroupId": {
                            "type": "keyword"
                        }
                    }
                },
                "httpSourceId": {
                    "type": "keyword"
                },
                "labels": {
                    "properties": {
                        "name": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "ignore_above": 256,
                                    "type": "keyword"
                                }
                            }
                        }
                    }
                },
                "webaclId": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "ignore_above": 256,
                            "type": "keyword"
                        }
                    }
                },
                "@timestamp": {
                    "path": "timestamp",
                    "type": "alias"
                },
                "webaclName": {
                    "type": "keyword"
                },
                "action": {
                    "type": "keyword"
                },
                "httpRequest": {
                    "properties": {
                        "args": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "ignore_above": 256,
                                    "type": "keyword"
                                }
                            }
                        },
                        "country": {
                            "type": "keyword"
                        },
                        "headers": {
                            "properties": {
                                "name": {
                                    "type": "keyword"
                                },
                                "value": {
                                    "type": "text",
                                    "fields": {
                                        "keyword": {
                                            "ignore_above": 256,
                                            "type": "keyword"
                                        }
                                    }
                                }
                            }
                        },
                        "httpVersion": {
                            "type": "keyword"
                        },
                        "requestId": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "ignore_above": 256,
                                    "type": "keyword"
                                }
                            }
                        },
                        "clientIp": {
                            "type": "ip"
                        },
                        "httpMethod": {
                            "type": "keyword"
                        },
                        "uri": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "ignore_above": 256,
                                    "type": "keyword"
                                }
                            }
                        }
                    }
                },
                "httpSourceName": {
                    "type": "keyword"
                },
                "formatVersion": {
                    "type": "keyword"
                },
                "timestamp": {
                    "format": "epoch_millis",
                    "type": "date"
                }
            }
        },
        "aliases": {
            "awswaf-waf": {}
        }
    }
}

*左滑查看更多

本篇作者

2f8e42675989bd1a239ef0d2eddaaa3e.png

崔俊杰

亚马逊云科技解决方案架构师

亚马逊云科技解决方案架构师,负责亚马逊云科技边缘云安全相关的服务产品。为亚马逊云用户提供DDoS防御/网站前端安全防御/域名安全相关的产品咨询。对Cloudfront, Shield, WAF, Route53,Global Accelerator等边缘云安全相关产品有深入了解。在计算机安全,数据中心和网络领域有多年的工作经验。

864504df68eecf35b13000317f403667.png

孙健

亚马逊云科技大数据解决方案架构师

负责基于亚马逊云科技的大数据解决方案的咨询与架构设计,同时致力于大数据方面的研究和推广。在大数据运维调优、容器解决方案,湖仓一体以及大数据企业应用等方面有着丰富的经验。

2767c7d2e526717eb6ea7e16a4a93269.png

戴晓斌

亚马逊云科技创新解决方案架构师

主要负责云上解决方案的设计与研发。在无服务器,容器,数据分析等方面有丰富的经验。

e2823bc6f9cdf91e2469df3b8c8c7554.png

任少鹏

亚马逊云科技解决方案架构师

负责传统金融客户的云上解决方案技术支持,有近20年软件架构设计及前后端开发工作经验。

0daabbacc87833bfaddd1eb780931426.png

6cf2f1ad1d3f7e3d2ca302d2a2965295.gif

d8133176f57087080dc00460b86fb362.gif

听说,点完下面4个按钮

就不会碰到bug了!

dc83ee8557268c3f58db26db28fab315.gif

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值