CloudFront経由の通信だけをAPI Gatewayで許可する方法を調査した話

アイキャッチ画像

背景について

あるアプリケーションでMicrosoft 365と連携するためのプラグインを使用するため、CloudFront、WAF、API Gatewayを利用した環境が構築されていました。

WAFではIPアドレスによるアクセス制限を設定していましたが、API GatewayのURLへ直接アクセスされた場合、WAFによる制限を経由せずにアクセスできてしまうという問題がありました。

そこで、API Gatewayへ直接アクセスされた場合でも、許可されていない通信を受け付けない仕組みについて調査することになりました。

また、私自身はAWSを利用した実務経験がなかったため、各サービスの役割や通信の仕組みを調べながら検証を進めました。

各機能について

1.  CloudFront 

Webサイトや画像、動画などのコンテンツを、ユーザーに近い拠点(エッジロケーション)から配信することで、表示速度を向上させるAWSのCDN(Content Delivery Network)サービスです。 

2. WAF(Web Application Firewall) 

Webアプリケーションへの通信を監視し、不正なアクセスや攻撃を防ぐためのAWSのセキュリティサービスです。IPアドレスや特定の通信パターンなどを条件に、アクセスを許可・拒否できます。 

3.  API Gateway

APIの作成・公開・管理を行うためのAWSのマネージドサービスです。クライアントからのリクエストを受け取り、Lambda※1や他のAWSサービス、外部のWebサービスなどへ処理をつなぐ役割を持ちます。 

※1 Lambdaとは、サーバーを用意・管理することなく、必要なときにプログラムを実行できるAWSのサーバーレスサービスです。API GatewayやS3などのAWSサービスをきっかけに処理を実行できます。

検討した方法

1. API Gatewayのデフォルトエンドポイントを非アクティブにする

API Gatewayでは、デフォルトでexecute-apiのエンドポイント※2が有効になっており、CloudFrontを経由せずにAPI Gatewayへ直接アクセスできることが分かりました。

そのため、CloudFrontに設定しているWAFだけでは、API Gatewayへの直接アクセスを制限できない状態でした。

そこで、API Gatewayのデフォルトエンドポイントを非アクティブにすることで、直接アクセスを防げるのではないかと考えました。

しかし、今回の構成ではCloudFrontのオリジンとしてAPI Gatewayのデフォルトエンドポイントを使用していたため、この方法では実現できませんでした。

※2 execute-apiのエンドポイントとは、API GatewayでAPIを作成した際に自動的に発行されるデフォルトのURLです。このURLを使用することで、API Gatewayへ直接アクセスできます。

2. API Gatewayのリソースポリシーを確認 

API Gatewayのリソースポリシー※3を確認したところ、アクセス元を制限する設定は行われておらず、特に制限がかけられていない状態でした。

そのため、API Gatewayのデフォルトエンドポイントへ直接アクセスした場合でも、リクエストを受け付けることができる状態となっていました。

リソースポリシーでIPアドレスによるアクセス制限を設定する方法もありましたが、CloudFront側にもアクセス制限を設定してほしいという要望があったため、別の方法を調査することになりました。

※3 リソースポリシーとは、API Gatewayに対して、どのアクセス元からの通信を許可または拒否するかを設定できるアクセス制御機能です。IPアドレスやAWSアカウントなどを条件に、APIへのアクセスを制限できます

解決方法について

CloudFrontも含めたアクセス制限を設けるために調査を行った結果、以下の解決方法を確認することができました。

1. CloudFrontにカスタムヘッダーを設定して、通信時に検証する方法

CloudFrontからAPI Gatewayへリクエストを送信する際に、CloudFront側で特定のカスタムヘッダー※4を付与し、API Gateway側でその値を検証する方法を検討しました。

CloudFrontを経由した通信には設定したカスタムヘッダーが付与されます。一方、API Gatewayのデフォルトエンドポイントへ直接アクセスした場合には、このヘッダーは付与されません。

そのため、API Gateway側でカスタムヘッダーの有無や値を確認し、正しい値が設定されているリクエストのみを許可することで、CloudFrontを経由していない通信を制限できます。

※4 カスタムヘッダーとは、HTTPリクエストに独自の情報を追加するためのヘッダーです。特定の値を付与し、受信側でその値を確認することで、通信元の判別やアクセス制御に利用できます。 

2. CloudFrontからAPI Gatewayの通信をmTLSで認証する方法

CloudFrontとAPI Gatewayの間でmTLS(mutual TLS)※5を利用し、クライアント証明書を用いて通信元を認証する方法です。

通常のTLSではサーバー側の証明書を検証しますが、mTLSではサーバー側だけでなく、通信するクライアント側の証明書も検証します。

これにより、正しいクライアント証明書を持つ通信のみをAPI Gateway側で受け付けることで、CloudFrontを経由していない直接アクセスを制限できます。

※5 mTLS(mutual TLS)とは、通常のTLS通信で行うサーバー側の証明書確認に加えて、クライアント側の証明書も確認する認証方式です。通信する双方が証明書を確認することで、より安全に通信相手を認証できます。

まとめ

今回の調査では、CloudFrontにWAFを設定してIP制限を行っていても、API Gatewayのデフォルトエンドポイントへ直接アクセスされた場合には、CloudFrontやWAFを経由しない通信経路が存在することが分かりました。

そのため、CloudFront側だけでアクセス制限を行うのではなく、API Gateway側でも直接アクセスを防ぐ仕組みを設ける必要があります。

今回は、CloudFrontからカスタムヘッダーを付与してAPI Gateway側で検証する方法や、mTLSを利用して通信元を認証する方法について調査しました。

AWSで複数のサービスを組み合わせる場合は、それぞれのサービス単体の設定だけでなく、想定していない経路から直接アクセスできないかを含めて、通信経路全体を確認することが重要だと感じました。