使用athena从aws waf日志中的rulegrouplist获取terminatingrule

kgsdhlau  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(428)

我按照这些说明把我的aws waf数据放到雅典娜表中。
我想查询的数据,以找到最新的请求与块的行动。此查询适用于:

SELECT
  from_unixtime(timestamp / 1000e0) AS date,
  action,
  httprequest.clientip AS ip,
  httprequest.uri AS request,
  httprequest.country as country,
  terminatingruleid,
  rulegrouplist
FROM waf_logs
WHERE action='BLOCK'
ORDER BY date DESC
LIMIT 100;

我的问题是清楚地确定“终止规则”——请求被阻止的原因。举个例子,结果是

terminatingrule = AWS-AWSManagedRulesCommonRuleSet

rulegrouplist = [
  {
    "nonterminatingmatchingrules": [],
    "rulegroupid": "AWS#AWSManagedRulesAmazonIpReputationList",
    "terminatingrule": "null",
    "excludedrules": "null"
  },
  {
    "nonterminatingmatchingrules": [],
    "rulegroupid": "AWS#AWSManagedRulesKnownBadInputsRuleSet",
    "terminatingrule": "null",
    "excludedrules": "null"
  },
  {
    "nonterminatingmatchingrules": [],
    "rulegroupid": "AWS#AWSManagedRulesLinuxRuleSet",
    "terminatingrule": "null",
    "excludedrules": "null"
  },
  {
    "nonterminatingmatchingrules": [],
    "rulegroupid": "AWS#AWSManagedRulesCommonRuleSet",
    "terminatingrule": {
      "rulematchdetails": "null",
      "action": "BLOCK",
      "ruleid": "NoUserAgent_HEADER"
    },
    "excludedrules":"null"
  }
]

我想分成一列的数据是 rulegrouplist[terminatingrule].ruleid 它的值为 NoUserAgent_HEADER aws提供了有关查询嵌套athena数组的有用信息,但我一直无法得到想要的结果。
我把这个问题定义为一个aws问题,但是由于athena使用sql查询,所以任何具有良好sql技能的人都有可能解决这个问题。

yx2lnoni

yx2lnoni1#

我还不完全清楚你到底想要什么,但我假设你是在数组元素之后 terminatingrule 不是 "null" (我也会假设如果有多个你想要第一个)。
你链接的文档说 rulegrouplist 列为 array<string> . 原因是 string 不是复杂类型是因为这个列似乎有多个不同的模式,一个例子是 terminatingrule 属性不是字符串 "null" ,或结构/对象- 用雅典娜的类型系统无法描述的东西。
不过,这不是问题。在处理json时,可以使用一整套json函数。这里有一种方法 json_extract 结合 filter 以及 element_at 删除 terminatingrule 属性是字符串“null”,然后选择剩余元素中的第一个:

SELECT
  element_at(
    filter(
      rulegrouplist,
      rulegroup -> json_extract(rulegroup, '$.terminatingrule') <> CAST('null' AS JSON)
    ),
    1
  ) AS first_non_null_terminatingrule
FROM waf_logs
WHERE action = 'BLOCK'
ORDER BY date DESC

你说你想要“latest”,这对我来说是不明确的,可能意味着第一个非空元素和最后一个非空元素。上面的查询将返回第一个非null元素,如果需要最后一个,可以将第二个参数改为 element_at 到-1(雅典娜的数组索引从1开始,-1从末尾开始计数)。
要返回json的单个ruleid元素:

SELECT from_unixtime(timestamp / 1000e0) AS date, action, httprequest.clientip AS ip, httprequest.uri AS request, httprequest.country as country, terminatingruleid, json_extract(element_at(filter(rulegrouplist,rulegroup -> json_extract(rulegroup, '$.terminatingrule') <> CAST('null' AS JSON)  ),1), '$.terminatingrule.ruleid') AS ruleid
FROM waf_logs
WHERE action='BLOCK'
ORDER BY date DESC
5kgi1eie

5kgi1eie2#

我也有同样的问题,但是theo发布的解决方案对我不起作用,即使表是根据原始帖子中链接到的说明创建的。
以下是对我有效的方法,基本上与theo的解决方案相同,但没有json转换:

SELECT
  from_unixtime(timestamp / 1000e0) AS date,
  action,
  httprequest.clientip AS ip,
  httprequest.uri AS request,
  httprequest.country as country,
  terminatingruleid,
  rulegrouplist
  element_at(filter(ruleGroupList, ruleGroup -> ruleGroup.terminatingRule IS NOT NULL),1).terminatingRule.ruleId AS ruleId
FROM waf_logs
WHERE action='BLOCK'
ORDER BY date DESC
LIMIT 100;

相关问题