マネージドルールCommonRuleSetのログをAthenaで確認する

AWSが提供しているマネージドルールCommonRuleSetに関するログをAthenaで確認します。WAF v2やCommonRuleSetの設定方法はこちらののブログをご覧ください。

事前準備

こちらののブログの通り、WAF v2を設定しておきます。

Athenaでのテーブル作成

Athenaコンソールで2019年12月分のテーブルを作成します。クエリは以下の通りです。s3-bucketnameは環境ごとに置き換えてください。

CREATE EXTERNAL TABLE `waflogs_201912`(
  `timestamp` bigint,
  `formatversion` int,
  `webaclid` string,
  `terminatingruleid` string,
  `terminatingruletype` string,
  `action` string,
  `httpsourcename` string,
  `httpsourceid` string,
  `rulegrouplist` array<string>,
  `ratebasedrulelist` array<
                      struct<
                        ratebasedruleid:string,
                        limitkey:string,
                        maxrateallowed:int
                            >
                           >,
  `nonterminatingmatchingrules` array<
                                struct<
                                  ruleid:string,
                                  action:string
                                      >
                                     >,
  `httprequest` struct<
                      clientip:string,
                      country:string,
                      headers:array<
                              struct<
                                name:string,
                                value:string
                                    >
                                   >,
                      uri:string,
                      args:string,
                      httpversion:string,
                      httpmethod:string,
                      requestid:string
                      > 
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
 'paths'='action,formatVersion,httpRequest,httpSourceId,httpSourceName,nonTerminatingMatchingRules,rateBasedRuleList,ruleGroupList,terminatingRuleId,terminatingRuleType,timestamp,webaclId')
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://s3-bucketname/2019/12'

以下のようにテーブルが作成されます。

プレビューすると、ログが表示されます。formatversionが"1"ですね。Classicとログフォーマットは変わらないようです。

ブロックした通信を表示する

action = 'BLOCK'の通信を見てみます。

SELECT from_unixtime(timestamp/1000, 'Asia/Tokyo') AS JST, * FROM waflogs_201912 WHERE action = 'BLOCK';

検証環境では、4件のブロックがありました。1件は私によるもので、他は外部からの攻撃と思われます。rulegrouplistのterminatingrule中のruleidがブロックしたルールです。UserAgent_BadBots_HEADERで、2件。CrossSiteScripting_BODYで1件。NoUserAgent_HEADERは1件検知しています。WAF Classicでは、直感的なではない文字列のIDが表示されていましたが、「UserAgent_BadBots_HEADER」のようにわかりやすいIDになりました。

ルールを例外に登録する

「UserAgent_BadBots_HEADER」ルールをWeb ACLコンソールから編集し、カウントモードにします。マネージドルール全体ではブロックし、UserAgent_BadBots_HEADERのみカウントで動きます。この状態でテストコマンドを送ると、通信は許可されます。

テストコマンドは以下の通りです。

curl -H 'User-Agent:' http://elb-dnsname

ALLOWされたログを抽出します。

SELECT from_unixtime(timestamp/1000, 'Asia/Tokyo') AS JST, * FROM waflogs_201912 WHERE action = 'ALLOW';

excludedrulesに注目します。NoUserAgent_HEADERが「EXCLUDED_AS_COUNT」つまり、カウントで動作していることがわかります。例外登録されていない場合は、"excludedrules":"null"になります。

終わりに

AWSが提供しているマネージドルールCommonRuleSetのS3に出力されたログをAthenaで確認しました。WAFログのフォーマットは1でClassicとv2で共通のようです。マネージドルールの例外登録にはrulegrouplistのterminatingrule中のruleidに注目します。ruleidは「NoUserAgent_HEADER」といった形で確認できます。NoUserAgent_HEADERを例外に登録したところ、通信が許可されました。ログのexcludedrulesを見るとNoUserAgent_HEADERが例外登録され、カウントで動作している様子がわかりました。