API GatewayのリソースポリシーでAPIにアクセスできる送信元IPアドレスを制限する

API Gatewayで送信元IPアドレスを制限するだけならリソースポリシーで設定できますよという小ネタ。
2021.02.17

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

データアナリティクス事業本部の貞松です。
案件絡みで発生した調べごとの備忘録的なやつです。

API GatewayからデプロイしたパブリックなAPIがあまりにも無防備なので、せめて送信元IPアドレスで制限したいと思い、調べてみたところリソースポリシーでサックリ設定できそうなのでやってみました。

API Gatewayで適当なAPIをデプロイ

確認の為にAPI Gatewayに適当なAPIをデプロイしておきます。
今回はアクセス制御を確認するだけなので、特に中身のないAPIです。

GETでアクセスすると "hello" と返ってくるだけです。
この段階では特に何事もなくアクセスできています。

API Gatewayのリソースポリシーを設定

API Gatewayのリソースポリシーを作成・更新するための権限

API Gatewayのリソースポリシーを作成・更新するためには、apigateway:UpdateRestApiPolicyだけでなくapigateway:PATCH権限が必要です。

API Gatewayのリソースポリシーの作成

次にAPI Gatewayのリソースポリシーを設定していきます。
初期状態のリソースポリシー画面は空っぽの状態です。

実はリソースポリシー画面の下部に制御するパターンに応じたテンプレートを展開してくれるボタンがあるので、今回の要件に対しては「IP Range Denylist」をクリックして、展開されたテンプレートを編集すれば簡単に設定ができます。

展開されたコードは以下の通りです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/{{stageNameOrWildcard}}/{{httpVerbOrWildcard}}/{{resourcePathOrWildcard}}",
            "Condition" : {
                "IpAddress": {
                    "aws:SourceIp": [ "{{sourceIpOrCIDRBlock}}", "{{sourceIpOrCIDRBlock}}" ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/{{stageNameOrWildcard}}/{{httpVerbOrWildcard}}/{{resourcePathOrWildcard}}"
        }
    ]
}
  • Resourceの指定
    • execute-api:/{{stageNameOrWildcard}}/{{httpVerbOrWildcard}}/{{resourcePathOrWildcard}}の箇所
    • リソース個別に指定する場合は、execute-api:/dev/GET/helloのような形式で指定します
    • リソースをまとめて指定する場合は、execute-api:/*/*/*のようにワイルドカードで指定します
  • aws:SourceIpの指定
    • 個別のIPアドレスを指定、あるいはCIDRブロックを指定します
    • リスト形式で複数指定することも可能です

Deny設定内にあるConditionの配下をIpAddressにするとブラックリスト、NotIpAddressにするとホワイトリストを設定することができます。逆で設定しないように注意してください。

ちなみにaws:SourceIpは、パブリックAPIに対する外部の送信元IPアドレス指定に使用します。
プライベートAPIに対するVPCからの送信元IPアドレスを指定する場合は、代わりにaws:VpcSourceIpを指定する点に注意してください。

リソースポリシーの記述が完了したら、右下のSaveボタンをクリックして設定を保存します。

リソースポリシー設定後にAPIを再デプロイする

リソースポリシーを設定した段階では、APIにポリシーが反映されません。必ずAPIの再デプロイを実行してください。

送信元IPアドレスをブラックリストに設定した場合の動作

Conditionの配下をIpAddressとして、送信元IPアドレスをaws:SourceIpに指定してAPIを再デプロイします。
APIにアクセスすると以下の結果になります。

アクセスが拒否されました。

送信元IPアドレスをホワイトリストに設定した場合の動作

Conditionの配下をNotIpAddressとして、送信元IPアドレスをaws:SourceIpに指定してAPIを再デプロイします。
APIにアクセスすると以下の結果になります。

正常にアクセスできました。

ちなみに送信元IPアドレスとは異なるアドレスを設定してみたところ、以下の通りちゃんとアクセスが拒否されました。

まとめ

API Gatewayのリソースポリシーでチョイチョイと設定するだけで送信元IPを制限することができました。
本格的なエンドポイント防御の為にはAWS WAFの導入を検討するのが良さそうですが、差し当たりのアクセス制限を施すにはこれでも良さそうです。

参考URL