对Amazon WAF日志进行细粒度的过滤

0
1
使用Amazon WAF,可以通过预设和自定义的安全规则来帮助阻止恶意流量,从而保护您的应用程序免受常见的网络漏洞和攻击尝试,包括 SQL 注入、跨站脚本 (XSS) 攻击、跨站请求伪造 (CSRF)、文件包含等。对Amazon WAF的日志进行采集和分析,对于优化WAF规则、响应安全事件以及对应用进行进一步加固而言,是一种最佳实践。但是对于Amazon WAF日志的采集、存储、分析都会产生后续的成本,比如S3存储的成本,Athena的查询成本,OpenSearch集群的成本等。在实际的业务场景中,有时候某些特定的高频Web访问本身就产生很大流量,产生大量的Amazon WAF日志,比如健康检查和测试的Web请求,如果能对这些分析中不需要的日志加以过滤,可以节省大量日志采集、存储以及分析产生的成本。 目前Amazon WAF的日志过滤功能支持两种类型的过滤规则,一种是基于Rule action的规则,即从Allow, Block, Count, CAPTCHA和Challenge几种action中选择或排除特定action的日志,显然这种过滤依然比较粗,无法进行更细粒度的日志选择。另一种过滤方式是基于label的过滤,但这种过滤方式只能选择特定的日志标签,无法实现更复杂的过滤逻辑,比如基于网址、访问路径、来源地址的日志过滤。 在Amazon WAF的使用事件中,笔者摸索出了一种可以实现更精细的Amazon WAF日志过滤规则的方法,这里供大家参考。 直接上示例,这里简便起见以terraform模板的形式说明,也可以遵循同样的逻辑通过其他形式配置。 基本的思路是创建一个专门用于过滤日志的Web ACL规则,规则的action设置为count,仅用于打标签。 以下代码创建了一个自定义web规则,为来自于CN,访问/testuri路径的访问打上“demo:ignorelog"的标签 ``` resource "aws_wafv2_web_acl" "demo_web_acl" { name = "demoWebACL" scope = "REGIONAL" description = "Tag requests that do not need to be sent to logs" default_action { allow {} } rule { name = "CombinedConditionsForIgnoreLog" priority = 1 action { count {} } statement { or_statement { statement { and_statement { statement { geo_match_statement { country_codes = ["CN"] } } statement { byte_match_statement { field_to_match { uri_path {} } positional_constraint = "EXACTLY" search_string = "/testuri" text_transformation { priority = 0 type = "NONE" } } } } } statement { byte_match_statement { field_to_match { single_header { name = "User-Agent" } } positional_constraint = "CONTAINS" search_string = "demo.app" text_transformation { priority = 0 type = "NONE" } } } } } rule_label { name = "demo:ignorelog" } visibility_config { cloudwatch_metrics_enabled = false sampled_requests_enabled = true } } visibility_config { cloudwatch_metrics_enabled = false sampled_requests_enabled = true } } ``` 其后的处理就比较直接了,在log过滤规则中指定drop label为"demo:ignorelog"的请求即可: ``` loggingConfiguration = { logDestinationConfigs = [ "arn:aws-cn:firehose:cn-north-1:xxxxxxxxxxxx:deliverystream/aws-waf-logs-xxxxxx" ] loggingFilterConfigs = { defaultBehavior = "DROP", filters = [ { behavior = "DROP" conditions = [ { actionCondition = null labelNameCondition = "demo:ignorelog" }, ] requirement = "MEETS_ALL" }, { behavior = "KEEP", ...此处省略... } ] } redactedFields = [] }, ``` 这样就实现了Amazon WAF日志的复杂逻辑细粒度过滤。label是Amazon WAF一个非常重要的功能特性,类似的基于label,还可以实现很多复杂的WAF处理逻辑,比如将Managed rulegroup与自定义的rulegroup相结合,实现类似于“仅对agent为demo.app的访问请求进行SQL注入检查”的逻辑,这里就不再展开。使用Amazon WAF,可以通过预置和可定制的安全规则来帮助阻止恶意流量,从而保护您的应用程序免受常见的网络漏洞和攻击尝试,包括 SQL 注入、跨站脚本 (XSS) 攻击、跨站请求伪造 (CSRF)、文件包含等。对Amazon WAF的日志进行采集和分析,是优化WAF规则,响应安全事件,对应用进行进一步加固的最佳实践。但是对于Amazon WAF日志的采集、存储、分析都会产生后续的成本,比如S3存储的成本,Athena的查询成本,OpenSearch集群的成本等。在实际的业务场景中,有时候某些特定的高频Web访问本身就产生很大流量,产生大量的Amazon WAF日志,比如健康检查和测试的Web请求,如果能对这些分析中不需要的日志加以过滤,可以节省大量日志采集、存储以及分析产生的成本。 目前Amazon WAF的日志过滤功能支持两种类型的过滤规则,一种是基于Rule action的规则,即从Allow, Block, Count, CAPTCHA和Challenge几种action中选择或排除特定action的日志,显然这种过滤依然比较粗,无法进行更细粒度的日志选择。另一种过滤方式是基于label的过滤,但这种过滤方式只能选择特定的日志标签,无法实现更复杂的过滤逻辑,比如基于网址、访问路径、来源地址的日志过滤。 在Amazon WAF的使用事件中,笔者摸索出了一种可以实现更精细的Amazon WAF日志过滤规则的方法,这里供大家参考。 直接上示例,这里简便起见以terraform模板的形式说明,也可以遵循同样的逻辑通过其他形式配置。 基本的思路是创建一个专门用于过滤日志的Web ACL规则,规则的action设置为count,仅用于打标签。 以下代码创建了一个自定义web规则,为来自于CN,访问/testuri路径的访问打上“demo:ignorelog"的标签 ``` resource "aws_wafv2_web_acl" "demo_web_acl" { name = "demoWebACL" scope = "REGIONAL" description = "Tag requests that do not need to be sent to logs" default_action { allow {} } rule { name = "CombinedConditionsForIgnoreLog" priority = 1 action { count {} } statement { or_statement { statement { and_statement { statement { geo_match_statement { country_codes = ["CN"] } } statement { byte_match_statement { field_to_match { uri_path {} } positional_constraint = "EXACTLY" search_string = "/testuri" text_transformation { priority = 0 type = "NONE" } } } } } statement { byte_match_statement { field_to_match { single_header { name = "User-Agent" } } positional_constraint = "CONTAINS" search_string = "demo.app" text_transformation { priority = 0 type = "NONE" } } } } } rule_label { name = "demo:ignorelog" } visibility_config { cloudwatch_metrics_enabled = false sampled_requests_enabled = true } } visibility_config { cloudwatch_metrics_enabled = false sampled_requests_enabled = true } } ``` 其后的处理就比较直接了,在log过滤规则中指定drop label为"demo:ignorelog"的请求即可: ``` loggingConfiguration = { logDestinationConfigs = [ "arn:aws-cn:firehose:cn-north-1:xxxxxxxxxxxx:deliverystream/aws-waf-logs-xxxxxx" ] loggingFilterConfigs = { defaultBehavior = "DROP", filters = [ { behavior = "DROP" conditions = [ { actionCondition = null labelNameCondition = "demo:ignorelog" }, ] requirement = "MEETS_ALL" }, { behavior = "KEEP", ...此处省略... } ] } redactedFields = [] }, ``` 这样就实现了Amazon WAF日志的复杂逻辑细粒度过滤。label是Amazon WAF一个非常重要的功能特性,类似的基于label,还可以实现很多复杂的WAF处理逻辑,比如将Managed rulegroup与自定义的rulegroup相结合,实现类似于“仅对agent为demo.app的访问请求进行SQL注入检查”的逻辑,这里就不再展开。
1
目录
关闭