[アップデート] AWS AppSync で AWS WAF が利用可能になったので IP 制限してみよう

「API Gateway に出来て、なんで AppSync には出来へんのや・・・」と枕を濡らした夜もあったよね。それも今日までだ。
2020.10.02

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

本日のアップデートにより AWS AppSync で AWS WAF を利用できるようになりました!

AWS AppSync の AWS WAF 対応

従来、AWS AppSync のセキュリティ機能としては「APIキー認証」「IAM認証」「OpenIDConnect認証」「Cognito認証」といった 4 つの認証を提供していますが、それ以外の IP 制限といった機能はありませんでした。

今回 AWS WAF サポートによって IP 制限は勿論のこと XSS、SQL インジェクション、Rate Limit など様々な観点での Web の脅威から AppSync GraphQL API を保護することが可能となりました!

注意事項

API で AWS WAF が有効になっている場合、AWS WAF ルールは APIキー、IAM、OIDCトークン、Cognitoユーザープールなどの認証よりも前に評価されます。

対応リージョン

AWS WAF および AWS AppSync の両方が利用可能なリージョンで利用できます。

AWS AppSync API への IP 制限を AWS WAF でやってみる

今回は事前に東京リージョンにデプロイした AppSync のサンプルプロジェクト「イベントアプリ」に対して、IP 制限を AWS WAF で実装したいと思います。

現在は IP 制限していませんので、下記のとおりリクエストが可能です。

$ curl -XPOST $APPSYNC_API_URL \
    -H "Content-Type:application/graphql" \
    -H "x-api-key:$APPSYNC_API_KEY" \
    -d '{"query": "query ListEvents { listEvents { items { id } } }"}'
{"data":{"listEvents":{"items":[{"id":"9f67d9ad-3927-47f2-9f1f-54e3f2175a39"}]}}}

AWS WAF 設定

AWS WAF コンソールから [IP sets] を開き、[Create IP set] をクリックします。任意の IP set name を入力し、Region は AppSync API を作成したリージョンを指定します。IP version を指定し、IP addresses に許可したい IP アドレスを入力し、[Create IP set] をクリックします。

次に [Web ACLs] を開き [Create web ACL] をクリックします。任意の Name および CloudWatch metric name を入力し、Resource typeRegional resources (Application Load Balancer, API Gateway, AWS AppSync) を選択します。Region は AppSync API 作成したリージョンを指定します。

[Associated AWS resources] で [Add AWS resources] をクリックし、AWS AppSync を選択します。リスト内の保護対象の API を選択し [Add] できましたら [Next] へ進みます。

Rules の [Add rules] から [Add my own rules and rule groups] を選択します。(マネージドルールを使用したい場合は [Add managed rule groups] を選択してください)

Rule builder を選択し、任意の Name を入力します。今回は IP 制限をしたいので TypeRegular rule を選択します。

今回、デフォルトは Block を想定しているので、[If a request] では許可ルールを設定したいので matches the statement を選択し、InspectOriginates from an IP address inIP set は先の手順で作成した IP set を指定します。

次に IP address to use as the originating address では Source IP address を選択します。前段に CloudFront などによって送信元 IP が変わってしまうため X-Forwarded-For ヘッダーなどで送信元 IP を判断したい場合は、IP address in header をご利用ください。

ActionAllow を選択し [Add rule] します。

Default actionBlock を選択し [Next] をクリックします。(許可された IP 以外はすべて Block されます)

Set rule priority はルールの評価順を指定します。今回は 1 つなのでそのまま [Next]をクリックします。(複数のルールを指定される場合は、上から順に評価されますので適切に並べ替えてください)

Configure metrics では CloudWatch メトリクス名や、WebACL ルールにマッチした際のログの取得を設定しますが、今回はデフォルトのまま [Next] に進みます。

さいごにサマリーが表示されますので内容を確認し、[Create web ACL] をクリックし設定完了です。

アクセスしてみる

まず、許可されている IP からのリクエスト

$ curl https://checkip.amazonaws.com/
52.193.231.243

$ curl -XPOST $APPSYNC_API_URL \
   -H "Content-Type:application/graphql" \
   -H "x-api-key:$APPSYNC_API_KEY" \
   -d '{"query": "query ListEvents { listEvents { items { id } } }"}'
{"data":{"listEvents":{"items":[{"id":"9f67d9ad-3927-47f2-9f1f-54e3f2175a39"}]}}}

次に、許可されていない IP からのリクエスト

$ curl https://checkip.amazonaws.com/
58.xx.xx.xx

$ curl -XPOST $APPSYNC_API_URL \
   -H "Content-Type:application/graphql" \
   -H "x-api-key:$APPSYNC_API_KEY" \
   -d '{"query": "query ListEvents { listEvents { items { id } } }"}'
{
  "errors" : [ {
    "errorType" : "WAFForbiddenException",
    "message" : "Forbidden"
  } ]
}

期待したとおりリクエストが弾かれましたね!

検証は以上です!

さいごに

Amazon API Gateway か AWS AppSync かの判断に迷った際、AWS WAF が使えないことによるセキュリティ機能差によって AWS AppSync の採用を見送った方も居られるかと思いますので、今回のアップデートは本当に待望の機能といえるのではないでしょうか。

AWS WAF は Web アプリケーションのセキュリティレベル向上には欠かすことの出来ないサービスかと思いますので、AWS AppSync ユーザーには是非とも利用を検討いただければと思います。

以上!大阪オフィスの丸毛(@marumo1981)でした!