📑

API Gateway使用時、Lambda オーソライザーを用いて、外部からのアクセスを制限する

に公開

概要

API Gateway使用時、外部からのAPIのアクセスを制限したい場合、どう対応すればよいでしょうか。

APIGatewayは、オーソライザー(認可)というAPI Gateway が 受け取ったリクエストの認証・認可 を行う設定ができます。

APIGatewayのオーソライザー(認可)は下記二種類あります。

  • JWT(JSON Web Token)
    • 一般的にはAmazon Cognito ユーザープールを作成し、JWTを発行する。Lambdaより実装が容易だが、メールアドレスまたは電話番号の登録が必要。
  • Lambda
    • 認証ロジックを Lambda 関数で定義する。柔軟性がありカスタマイズが可能。

本ドキュメントでは、API Gateway のオーソライザーのうち、Lambda オーソライザーについて解説します。

実装手順

  • オーソライザー用のLambdaを作成します。

    • 関数名

      • agw-access-permission(例)
    • 環境変数

      キー
      ALLOWED_IP 許可するIP(例:111.222.333.444)
      ALLOWED_TOKEN 任意のトークン(例:Ab12Xy34)
    • コードソース(Pythonの場合)

      ※APIGatewayのAPIタイプはHTTP APIを使用しています。

      import os
      import logging
      
      # CloudWatch Logs用のロガー設定
      logger = logging.getLogger()
      logger.setLevel(logging.INFO)
      
      def lambda_handler(event, context):
          allowed_ip = os.environ.get("ALLOWED_IP")
          allowed_token = os.environ.get("ALLOWED_TOKEN")
      
          source_ip = (
              event.get("requestContext", {})
              .get("http", {})
              .get("sourceIp")
          )
          token = event.get("headers", {}).get("authorization")
      
          logger.info(f"[INFO] Source IP: {source_ip}")
          logger.info(f"[INFO] Token: {token}")
          logger.info(f"[INFO] Allowed IP: {allowed_ip}")
          logger.info(f"[INFO] Allowed Token: {allowed_token}")
      
          if source_ip == allowed_ip and token == allowed_token:
              return {
                  "isAuthorized": True,
                  "context": {
                      "ip": source_ip,
                      "token": token
                  }
              }
          else:
              # ログにエラーとして記録
              if source_ip != allowed_ip:
                  logger.error(f"[ERROR] IPアドレスが不一致: 受信IP={source_ip}, 許可IP={allowed_ip}")
              if token != allowed_token:
                  logger.error(f"[ERROR] トークンが不一致: 受信トークン={token}, 許可トークン={allowed_token}")
      
              return {
                  "isAuthorized": False,
                  "context": {
                      "ip": source_ip,
                      "token": token
                  }
              }
      
      
  • APIGatewayのオーソライザーの設定をします。

    • APIGateway>API>{対象のAPIGateway}>認可からオーソライザーを作成してアタッチを選択します。
    • オーソライザーの名前を入力します。(agw-access-permission-authorizer)
    • 前手順で作成したLambda(agw-access-permission)を指定します。

アクセス許可確認

  • 許可されたIPの外部環境からコマンドプロンプトで下記コマンドを実行します。

    • Authorizationヘッダーは設定したALLOWED_TOKENを入力します。
    • 下記のようなリスポンスがあり、正常に実行できることを確認します。
    C:\Users\NaoyaTamatsu>curl -H "Authorization: Ab12Xy34" https://dg9t6zkw2i.execute-api.ap-northeast-1.amazonaws.com
    {"isAuthorized": true, "context": {"ip": "111.222.333.444", "token": "Ab12Xy34"}}
    

アクセス制御確認

  • 許可していないIPの外部環境からコマンドプロンプトで下記コマンドを実行します。

    • 下記のようなリスポンスがあり、アクセスがブロックされることを確認します。
    C:\Users\NaoyaTamatsu>curl -H "Authorization: Ab12Xy34" https://dg9t6zkw2i.execute-api.ap-northeast-1.amazonaws.com
    {"message":"Forbidden"}
    
  • 異なるALLOWED_TOKENを使用した時についても、アクセスがブロックされることを確認します。

    C:\Users\NaoyaTamatsu>curl -H "Authorization: test" https://dg9t6zkw2i.execute-api.ap-northeast-1.amazonaws.com
    {"message":"Forbidden"}
    

実行ログ確認

  • CloudWatch Logsを確認すると、実行ログの詳細を確認できます。

    • /aws/lambda/stnw-jcc-stg-toc-lambda-agw-access-permission
    REPORT RequestId: 24f9e55f-b57e-4c91-aaee-0554a354b18b Duration: 1.85 ms Billed Duration: 2 ms Memory Size: 512 MB Max Memory Used: 35 MB
    2025-07-11T06:05:34.308Z
    START RequestId: d39edf81-4b21-4e3d-8ad2-7c1e92f00c82 Version: $LATEST
    2025-07-11T06:05:34.309Z
    [INFO] 2025-07-11T06:05:34.309Z d39edf81-4b21-4e3d-8ad2-7c1e92f00c82 [INFO] Source IP: 111.222.333.444
    2025-07-11T06:05:34.309Z
    [INFO] 2025-07-11T06:05:34.309Z d39edf81-4b21-4e3d-8ad2-7c1e92f00c82 [INFO] Token: test
    2025-07-11T06:05:34.309Z
    [INFO] 2025-07-11T06:05:34.309Z d39edf81-4b21-4e3d-8ad2-7c1e92f00c82 [INFO] Allowed IP: 111.222.333.444
    2025-07-11T06:05:34.309Z
    [INFO] 2025-07-11T06:05:34.309Z d39edf81-4b21-4e3d-8ad2-7c1e92f00c82 [INFO] Allowed Token: Ab12Xy34
    2025-07-11T06:05:34.309Z
    [ERROR] 2025-07-11T06:05:34.309Z d39edf81-4b21-4e3d-8ad2-7c1e92f00c82 [ERROR] トークンが不一致: 受信トークン=test, 許可トークン=Ab12Xy34
    2025-07-11T06:05:34.310Z
    END RequestId: d39edf81-4b21-4e3d-8ad2-7c1e92f00c82
    

参考

株式会社トッカシステムズ

Discussion