マネージドルール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が例外登録され、カウントで動作している様子がわかりました。