AWS WAFマネージドルール導入と運用の勘所

マネージドルールを使うことでユーザー側でルールを作成する必要がなくなり、安く早くWAFを利用できるようになりました。 一方でマネージドルールやAWS WAFでは要件を満たせないため、パートナー製品のWAFを使うこともよくあります。 AWS WAFマネージドルール導入時にどのようなことに気をつけたり、どのような運用が必要になるかをご紹介します。
2019.07.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

マネージドルールを使うことでユーザー側でルールを作成する必要がなくなり、安く早くWAFを利用できるようになりました。 一方でマネージドルールやAWS WAFでは要件を満たせないため、パートナー製品のWAFを使うこともよくあります。 AWS WAFマネージドルール導入時にどのようなことに気をつけたり、どのような運用が必要になるかをご紹介します。

導入

マネージドルールを購入します。ルールの選定基準ですが、一覧から用途に合うものを選ぶと良いかと思います。 例えば、ボットから保護したい場合は「AWS WAF の F5 ルール – ボット保護ルール」、Apacheを使っている場合は「Trend Micro Managed Rules for AWS WAF – WebServer (Apache、Nginx)」といった形です。

Web ACLのルールに、マネージドルールを追加します。デフォルトのアクションを許可、マネージドルールをカウントにします。マネージドルールを初めからブロックで導入するとアプリケーションに影響が出る可能性があります。

開発環境と本番環境で同じマネージドルールの導入しましょう。開発環境で見つかった誤検知を本番環境に適用できるからです。

後述の解析のために、ログをKinesis Data Firehoseを利用してS3に出力するように設定します。

参考:ウェブ ACL トラフィック情報のログ記録 - ウェブ ACL でログ記録を有効にするには

ルール最適化の手法

WAFのルールの最適化というと、アプリケーション個別のルールを作り込むイメージを持たれる方が多いと思います。マネージドルールでは良くも悪くも作りこみはできません。また、マネージドルールに具体的にどのようなルールがあるのかユーザー側では確認できません。

マネージドルールでは誤検知が発生したルールを除外できます。カウントモードで導入し、しばらく様子をみてからルールIDを指定する形で除外する対応になります。除外するとマネージドルールをブロックにしていても、そのルールIDについてはカウント(ブロックしない)される動きになります。

参考:[新機能]AWS WAFマネージドルールで誤検知対応できる例外ルールの設定が可能になりました

CloudWatchメトリクスによる概要の確認

マネージドルールに一致した通信数をざっくりと確認するには、CloudWatchメトリクスが適しています。1日に何回もカウントされているのであれば、ルールの除外が必要な可能性があります。以下はサンプルですが、1分間で最大87カウント発生しています。仮に開発環境でこのような状況であれば、ルールの除外が必要かと思います。

開発環境のカウントログを抽出する

開発環境からの接続であれば、正常なユーザーのアクセスと見なせるケースがほとんどかと思います。Athenaでカウントする例を紹介します。

データベースの作成

Athenaのコンソールから、データベースを作成します。

create database awswaf;

テーブルの作成

2019年7月のログを集計する場合は、LOCATION 's3://bucketname/2019/07/といった形で作成します。

CREATE EXTERNAL TABLE IF NOT EXISTS awswaf.waflogs_201907
(
`timestamp` bigint,
formatVersion int,
webaclId string,
terminatingRuleId string,
terminatingRuleType string,
action string,
httpSourceName string,
httpSourceId string,
ruleGroupList array < struct <
ruleGroupId: string,
terminatingRule: string,
nonTerminatingMatchingRules: array < struct < action: string, ruleId: string > >,
excludedRules: array < struct < exclusionType: string, ruleId: string > >
> >,
rateBasedRuleList array < struct < rateBasedRuleId: string, limitKey: string, maxRateAllowed: int > >,
nonTerminatingMatchingRules array < struct < action: string, ruleId: string > >,
httpRequest struct <
clientIp: string,
country: string,
HTTPVersion: 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'
LOCATION 's3://bucketname/2019/07/';

カウントログの抽出

カウントログを抽出します。

SELECT from_unixtime(timestamp/1000, 'Asia/Tokyo') AS JST, *
FROM awswaf.waflogs_201907,
UNNEST(nonTerminatingMatchingRules) t(nonTermRule)
WHERE nonTermRule.action = 'COUNT'
ORDER BY timestamp DESC;

ログは以下のように見えます。ダウンロードを押すとCSVでダウンロードできます。

開発環境のカウントログを分析する

CSVファイルを分析します。除外候補となるIdはruleGroupList中のterminatingRuleに含まれるruleIdです。マネージドルール内のルールIDというとわかりやすいでしょうか。CSVファイルをエクセルで開いた場合は、以下のように確認できます。「01ee3d34-5247-4b83-b586-017a2edb4009」がルールIDです。

HTTPリクエスト(httprequest)は以下のように確認できます。curlでXSSルールに一致することを狙った通信を発生させたところ、マネージドルールに一致しました。ログからIPアドレス、国、ユーザーエージェント、args、メソッドなどを確認できます。

{clientip=999.999.999.999, country=JP, httpversion=HTTP/1.1, headers=[{name=Host, value=elbname-xxxxxxx.ap-northeast-1.elb.amazonaws.com}, {name=User-Agent, value=curl/7.54.0}, {name=Accept, value=*/*}], uri=/, args=<script src="https://(略)"></script>, httpmethod=GET, requestid=null}

ルールを例外に登録する

ルールIDを例外に登録します。Edit WebACLを選択します。

確認したIDを追加します。開発環境と本番環境のWeb ACLどちらにも例外登録します。

本番環境のカウントログを抽出する

カウントした通信を抽出します。開発環境のカウントログを抽出すると同様です。

本番環境のカウントログを分析する

ダウンロードしたCSVファイルから、ルールIDでユニークな物を抽出します。 エクセルで集計する場合は、ruleGroupList中のterminatingRuleをカンマ区切りでわけ、ユニークをとるとわかりやすいです。 ルールIDごとに国別に通信を見ていきます。日本向けのサービスの場合、JPの通信がある場合は例外登録の候補になります。海外からのIPの場合、怪しい通信である可能性が高いです。もっとも海外からもアクセスが多いサイトの場合、この方法は使えません。 この作業を許容できない場合は、お金をかけてパートナー製品のWAFを使いセキュリティオペレーションセンターと契約すると良いでしょう。

実際にマネージドルールで防げた攻撃

マネージドルールを導入することで、防げた攻撃の例を一部ですがご紹介します。著名な攻撃や攻撃コードが出回っている脆弱性について、守れることを確認できました。

Apache Struts 2における脆弱性をついたと思われる攻撃

Content-Type#cmds=(#iswin?{'cmd.exe'(略))のようなアプリケーションで使用していないコマンドが書かれていました。 CVE-2017-5638に関する攻撃と思われます。

特定のファイルをPUTする攻撃

FxCodeShell.jspをPUTしようとした通信がありました。「FxCodeShell.jsp put」で調べると、Tomcatの脆弱性をついた攻撃として著名なようです。

XSSと思われる攻撃

XSSが成立するか確認するようなリクエスト < script >alert(1)< /script > がありました。

まとめ

AWS WAFマネージドルールの導入時にどのようなことに気をつけたり、どのような運用が必要になるかをご紹介しました。 マネージドルールはカウントモードで導入します。最初からブロックで導入するとアプリケーションに影響が出る可能性があります。導入後はCloudWatchメトリクスで概要を確認しつつ、開発環境で得られた誤検知を除外していきます。また、Athenaでご紹介したような攻撃が発生しているか確認できます。チューニングはルールの除外になる点やログからはボディを確認できない点はご留意ください。マネージドルールはお金をかけずにライトに使う用途に適しています。