[update] AWS WAFがリクエストへのカスタムヘッダ挿入をサポートしました

AWS WAFでリクエストへのカスタムヘッダ挿入がサポートされました。リクエストが検証され、許可もしくはカウントとなった場合に指定したカスタムヘッダをリクエストに挿入することができます。実際にAWS WAFを設定し挙動を確認してみました。
2021.03.31

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

はじめに

清水です。本エントリでお届けするアップデート情報はこちら!AWS WAFでリクエストへカスタムヘッダを挿入すること(Request Header Insertion)が可能になりました。(2021/03/29にポストされたアップデート情報になります。)

AWS WAFによりリクエストが検証され、許可もしくはカウントとなった場合、あらかじめ指定したカスタムヘッダをリクエストに挿入することができます。例えばアプリケーション側でWAFによって評価されたリクエストであることを確認後に処理を行ったり、ヘッダの有無によって異なる処理を行う、またレポートや分析のためにアプリケーションログにカスタムヘッダ情報を記録する、などといったユースケースを想定しているようです。

本エントリでは、このAWS WAFのカスタムヘッダ挿入を実際に試し、アプリケーション側でそのヘッダ内容を確認してみたのでまとめてみたいと思います。

AWS WAFでカスタムヘッダを挿入してみた

では実際にAWS WAFを設定して、カスタムヘッダ挿入を確認してみたいと思います。

カスタムヘッダ挿入設定前の確認

事前準備として、特定のIPアドレスからのアクセスをカウントし、それ以外のIPアドレスからのアクセスを許可するWeb ACLを作成しておきます。ALB+EC2の環境に紐付け、EC2側ではApache+PHPが稼働します。以下2つのphpファイルを用意し、HTMLならびにテキストベースのアクセスでレスポンスとしてリクエストヘッダ情報を返すようにします。

header_html.php

<?php

foreach (getallheaders() as $name => $value) {
    echo "<p>";
    echo "$name: $value\n";
    echo "</p>";
}

?>

header_text.php

<?php

foreach (getallheaders() as $name => $value) {
    echo "$name: $value\n";
}

?>

AWS WAFでカスタムヘッダを挿入しない場合の挙動は以下のようになります。

% curl https://www.example.net/header_text.php
X-Forwarded-For: XXX.XXX.XXX.XXX
X-Forwarded-Proto: https
X-Forwarded-Port: 443
Host: www.example.net
X-Amzn-Trace-Id: Root=1-6XXXXXXX-XXXXXXXXXXXXXXXXXXXc683
user-agent: curl/7.53.1
accept: */*

AWS WAFにカスタムヘッダの設定

続いて実際にAWS WAFへカスタムヘッダを設定していきます。まずは特定のIPでカウントするルールへの設定です。対象のルールの[Edit]ボタンで進みます。

ルール設定画面の最下部、Actionの項目に下にCustom requestの項目があります。文字列をクリックして内容を展開し、[Add new custom header]ボタンを押しましょう。

KeyとValue欄に、それぞれHeader nameとHeader valueを入力するように促されます。今回は以下のように設定しました。

  • Key (Header name)
    • Count-Action-Header
  • Value (Header value)
    • Count-Value

[Save rule]ボタンで以下画面に進み、[Save]ボタンで設定を完了させます。

この段階でルール詳細画面では、以下のように設定したカスタムヘッダ内容が確認できます。

続いて特定のIP以外の場合の設定です、ルールにマッチしない場合のデフォルトアクションでAllowとしています。このデフォルト設定の[Edit]ボタンから進みます。

設定のダイアログが現れます。Custom requestの項目があるので、文字列をクリックして詳細を展開します。

展開すると先ほどと同じように[Add new custom header]ボタンが現れるのでこちらを押下します。

KeyとValue欄に、それぞれHeader nameとHeader valueを入力しましょう。こちらは以下のように設定しました。

  • Key (Header name)
    • Allow-Action-Header
  • Value (Header value)
    • Allow-Value

[Save]ボタンで設定を完了します。以下のようにカスタムリクエストヘッダ内容が確認できます。

AWS WAFでカスタムヘッダが挿入されることの確認

以上でAWS WAF側のカスタムヘッダ挿入の設定は完了です。では実際にリクエスト時にカスタムヘッダが挿入されているか確認してみましょう。

まずは特定のIPアドレス以外でアクセスしたケースです。

% curl https://www.example.net/header_text.php
X-Forwarded-For: XXX.XXX.XXX.XXX
X-Forwarded-Proto: https
X-Forwarded-Port: 443
Host: www.example.net
X-Amzn-Trace-Id: Root=1-6XXXXXXX-XXXXXXXXXXXXXXXXXXXXabea
user-agent: curl/7.64.1
accept: */*
x-amzn-waf-allow-action-header: Allow-Value

IPアドレス一致のルールには合致せず、デフォルトアクションでリクエストが許可されます。その際に指定したカスタムヘッダが挿入されていますね。指定したヘッダ名の前にx-amzn-waf-のプレフィックスが付与される点にも注意しましょう。(AWS WAF Developer Guideに記載があります。)さらに細かな点ですが、ヘッダ名は小文字で置き換わるようです。

続いては特定のIPアドレスからアクセスしたケースです。

% curl https://www.example.net/header_text.php
X-Forwarded-For: XXX.XXX.XXX.XXX
X-Forwarded-Proto: https
X-Forwarded-Port: 443
Host: www.example.net
X-Amzn-Trace-Id: Root=1-6XXXXXXX-XXXXXXXXXXXXXXXXXXXb4b9
user-agent: curl/7.64.1
accept: */*
x-amzn-waf-count-action-header: Count-Value
x-amzn-waf-allow-action-header: Allow-Value

IPアドレス一致のルールに合致するので、この段階で一つ目のカウント時に指定したカスタムヘッダが挿入されます。ただしこのルールではカウントのみで、実際にはリクエストは後続のデフォルトアクションで許可されるので、2つ目の許可時のカスタムヘッダも挿入されます。

私は設定しながら、特定のIPアドレスからのアクセスケースでは、カウント時に指定したカスタムヘッダだけが挿入されるのかな、というイメージを持っていましたが、デフォルトアクションの許可時のカスタムヘッダも挿入されますね。こちらはAWS WAF Developer Guideにも記載がありました。

ということで、AWS WAFで許可もしくはカウント時に指定したカスタムヘッダが挿入されることが確認できました。

カスタムヘッダ挿入が重複するケース

ここまでの検証の中で、同じヘッダ名でカスタムヘッダの挿入が重複した場合にどうなるのか、という点が気になりました。上記の例の、特定のIPアドレスからアクセスしたケース、カウントと許可の際にカスタムヘッダが挿入されますが、このヘッダ名が重複している場合ですね。

ということで、以下のようにヘッダ名を同じ、ヘッダの値のみカウント、許可で区別したカスタムヘッダを設定して試してみます。

  • IP一致ルール(カウント)に設定したカスタムヘッダ
    • Key (Header name)
      • Action-Header
    • Value (Header value)
      • Count-Value
  • デフォルトルール(許可)に設定したカスタムヘッダ
    • Key (Header name)
      • Action-Header
    • Value (Header value)
      • Allow-Value

IP一致ルールに合致する、特定のIPアドレスからアクセスしてみます。結果は以下のように、デフォルトルール(許可)で設定されたカスタムヘッダでアプリケーションに届く(上書きされる)、となりました。

% curl https://www.example.net/header_text.php
X-Forwarded-For: XXX.XXX.XXX.XXX
X-Forwarded-Proto: https
X-Forwarded-Port: 443
Host: www.example.net
X-Amzn-Trace-Id: Root=1-6XXXXXXX-XXXXXXXXXXXXXXXXXXXX645d
user-agent: curl/7.64.1
accept: */*
x-amzn-waf-action-header: Allow-Value

まとめ

AWS WAFの新機能、リクエストへのカスタムヘッダ挿入について確認してみました。先にお伝えしたAWS WAFのカスタムレスポンス対応と合わせて、AWS WAFでヘッダ情報をカスタマイズすることが可能になりました。この許可、カウントの際のカスタムヘッダ挿入と、ブロックの際のカスタムレスポンス対応、AWSマネジメントコンソールでは設定箇所も似ていたりします。Actionの項目でAllowかCountを選択していればCustom requestとしてリクエストヘッダのカスタマイズができ、Blockを選択すればCustom responseがカスタマイズできる、という具合です。2つあわせて確認しておきたいなと思いました。