【API Gateway】AWS SAM を使ってIP アドレス制限をかけてみた

記事タイトルとURLをコピーする

こんにちは、ディベロップメントサービス1課の山本です。
暑くなってきて、サウナが気持ちいい季節になってきました。

本日は AWS Serverless Application Model (以降はSAM) を使って、API Gateway に IPアドレス制限をかける方法をご紹介します。 開発中のAPIをテストしたいけど、認証機能の実装は未完、フルオープンにもしたくないという方は必見です。

この記事の対象者は?

この記事は以下の方々に向けて書かれています

  • API Gateway に IP アドレス制限をかけたい
  • SAM を使って管理したい

進め方

以下のAWS公式ドキュメントを参考にします。 repost.aws

AWS::Serverless::Api -> ApiAuth -> ResourcePolicy -> CustomStatements
にIPアドレス制限用のリソースポリシーを追記していきます。

後半にSAM特有の簡単な設定方法を記載いたしますので、最後までご覧頂ければと思います。

※ リソースポリシーの設定は REST API のみのため、HTTP API は非対応となります。

SAM テンプレート

sam init コマンドで取得できるHello World のテンプレートをベースにして
Globals の設定に リソースポリシーの内容を追記します。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: sam-app

Globals:
  Function:
    Timeout: 3
    MemorySize: 128
  # IPアドレス制限を追加↓
  Api:
    Auth:
      ResourcePolicy:
        CustomStatements:
          [
            {
              "Effect": "Allow",
              "Principal": "*",
              "Action": "execute-api:Invoke",
              "Resource": "execute-api:/*",
            },
            {
              "Effect": "Deny",
              "Principal": "*",
              "Action": "execute-api:Invoke",
              "Resource": "execute-api:/*",
              "Condition":
                {
                  "NotIpAddress":
                    {
                      "aws:SourceIp":
                        [
                          "{許可したいIPアドレス}",
                        ],
                    },
                },
            },
          ]
  # IPアドレス制限を追加↑

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

リソースポリシー

リソースポリシー

IP アドレス制限の確認

許可されたIP アドレスからのアクセス

{
  "message": "hello world"
}

禁止された IP アドレスからのアクセス

{
  "Message": "User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:ap-northeast-1:************:endqsfr6uk/Prod/GET/hello with an explicit deny"
}

無事、IP アドレス制限をかけることができました。

おまけ(IpRangeWhitelist)

AWS::Serverless::Api -> ApiAuth -> ResourcePolicy
の内容を調べる最中、おやっと思う項目を見つけました。

IpRangeWhitelist
許可する IP アドレスまたはアドレス範囲です。
タイプ: リスト
必須: いいえ
AWS CloudFormation との互換性: このプロパティは AWS SAM に固有であり、AWS CloudFormation に同等のものはありません。

これを使えば、もっと簡単に書けるのでは? 試してみます。

SAM テンプレート(IpRangeWhitelist を利用)

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: sam-app

Globals:
  Function:
    Timeout: 3
    MemorySize: 128
  # IPアドレス制限を追加↓
  Api:
    Auth:
      ResourcePolicy:
        IpRangeWhitelist:
          - "{許可したいIPアドレス}"
  # IPアドレス制限を追加↑

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

リソースポリシー(IpRangeWhitelist を利用)

IP アドレス用のリソースポリシーが自動生成されてます。
SAM で構築したAPIパスにリソースも限定されているため、設定が安全かつ楽になってます。

IpRangeWhitelist を使ったリソースポリシー

まとめ

  • SAM の CustomStatements にリソースポリシーの内容を記載することで IP アドレス制限は可能
  • SAM の IpRangeWhitelist を利用することで、IP アドレスを記載するだけでリソースポリシーが自動生成される
  • 安全かつ楽な IpRangeWhitelist を利用しましょう

さいごに

常に簡単な方法を模索していきます!

山本 真大(執筆記事の一覧)

アプリケーションサービス部 ディベロップメントサービス1課

2023年8月入社。カピバラさんが好き。