MNTSQ Techブログ

「MNTSQ(モンテスキュー)」のTechブログです。

CloudFrontのVPC Originの利用と静的リソースの配信について(副題: ひょっとしたらさよならパブリックサブネット)

MNTSQ Tech Blog TOP > 記事一覧 > CloudFrontのVPC Originの利用と静的リソースの配信について(副題: ひょっとしたらさよならパブリックサブネット)

SREチームマネージャーの藤原です。

本エントリでは、現在構築中の新サービスにて利用する予定の CloudFrontおよびVPC Originの活用と、CloudFrontを経由した静的リソース配信について解説します。

シンプルな構成へのCloudFrontの導入

まずは非常にシンプルなアプリケーションを考えてみます(図1)。

単一のバックエンドのコンピューティングリソースに外部向けのAPIと内部向けのAPIがある場合、インターネットからアクセス可能な外部向けのロードバランサーと、内部からのみアクセス可能な内部向けのロードバランサーを分けて設定するパターンがあります。

図1. シンプルな構成のウェブアプリケーション

このような構成の場合、静的リソース(画像やjs, cssなど)はバックエンドのコンピューティングリソースから配信することになります。静的リソースはコンピューティングリソースを消費しない形で配信したいところです。

そこで、CDNとオブジェクトストレージを活用します。AWSの場合、CloudFrontとS3を利用することになります。この場合、インターネットと外部向けアプリケーションロードバランサーの間にCloudFrontのディストリビューションを配置、静的リソース配信用のS3バケットを作成することになります(図2)。

図2. 単純にCloudFrontディストリビューションと静的リソース配信用バケットを導入

CloudFrontと静的リソース配信用バケットの間については、OAC(Origin Access Control)を利用することでセキュアに接続できます1

図2の構成では静的リソースをCDNを用いてコンピューティングリソースを使用することなく効率的に配布することができます。 さらに、外部向けアプリケーションロードバランサーからの動的リソース配信と同じドメイン名を使って静的リソースを配信できるため、CORS2などを意識する必要もありません。

ただし、この構成では、CloudFrontディストリビューションと外部向けアプリケーションロードバランサーの間に課題が埋まっています。

外部向けアプリケーションロードバランサーの抱える課題

外部向けアプリケーションロードバランサーはパブリックIPアドレスを持っています。 また、AWSマネージドなFQDNも持つため、CloudFrontを経由せずに直接アクセスが可能です(図3)。

図3. インターネットから外部向けアプリケーションロードバランサーへの直アクセス(破線部)

一定以上の利用があるサービスを運用したことのある方にはわかると思いますが、ロードバランサーIPアドレスAWSマネージドなFQDNを直接指定したHTTPリクエストは、想像以上に多く発生します3

ロードバランサーへの直接アクセスをブロックしつつ、CloudFrontを経由したアクセスを通したい場合、次のような対策が基本として考えられます。

  1. CloudFrontでHTTPヘッダを追加し、ロードバランサのリスナールールで特定のヘッダがある場合のみリクエストをフォワードする4
  2. CloudFrontのAWSマネージドプレフィックスリストをロードバランサーのセキュリティグループに適用する5

それでも、外部向けアプリケーションロードバランサーにはパブリックなIPアドレス(やAWSマネージドなFQDN)が割り当てられたままです。そこで「パブリックIPアドレスFQDNも持たないロードバランサーをCloudFrontのオリジンとして使えないだろうか」と考えたくなります。この考えを実現してくれるのがCloudFrontのVPC Originです。

CloudFrontのVPC Origin

CloudFrontのVPC Origin機能を利用すると、プライベートサブネット内にENI(Elastic Network Interface)が作成されます。このENIを経由して、CloudFrontディストリビューションとアプリケーションロードバランサー間の通信が行われます(図4)。

図4. VPC Originの利用によるENIの設置

VPC Originを利用することで、CloudFrontディストリビューションのオリジンを、パブリックサブネットに配置された外部向けロードバランサーではなく、プライベートサブネットに配置されたロードバランサー(以前の図における内部向けロードバランサー)とすることができます。

プライベートサブネットに配置されたアプリケーションロードバランサーは内部向けのため、パブリックIPアドレスを持ちません。これにより、CloudFrontディストリビューションを経由しないインターネットからの直接アクセスを完全に排除できます

VPC Originを導入した後の構成

VPC Originを導入した後の構成としては図5のようになりました。

図5. VPC Origin導入後の構成

図1と図5を比較すると、以下の機能的な違いがあります。

  • 静的リソースを配信用バケットで提供することで、コンピューティングリソースを消費せずに配布できるようになった

図2と図5を比較すると、主な差分は次の2点です。

  1. アプリケーションロードバランサーへのインターネットからの直接アクセス経路が完全に排除された
  2. 外部ロードバランサーと内部ロードバランサーが一本化され、内部ロードバランサー相当のもののみとなった

単純な構成の差分としてはここまでです。運用時も見据えると以下の観点でメリデメが生じます。

  • メリット
    1. アプリケーションロードバランサーへのインターネットからの直アクセスを考える必要がない(セキュリティ的なメリット)
    2. 設定管理対象の削減(構成管理上のメリット)
  • デメリット
    1. アプリケーションロードバランサーの設定が複雑化する可能性(構成管理上顕在化する可能性のあるもの)
      • 外部向けと内部向けのリスナールール両方を一つのリスナー設定に含める必要がある

アプリケーションロードバランサーのリスナールールは外部向けと内部向けの両方を単一の場所にまとめて記述する必要があるため、複雑なルールを設定する場合は注意が必要です。

一方で、設定が一箇所にまとまることで「あれ、これはどのロードバランサに含まれていたっけ?」といった混乱が起きにくくなるため、リスナー設定がシンプルな場合はデメリットは最小化できます。

今回設計したサービスではリスナールールに複雑な要素がほとんどなかったため、外部向けと内部向けのロードバランサーを一つに統合した際のデメリットの顕在化はほぼなく、直接アクセス経路の排除というメリットのみを実質的に得ることができました。

まとめ

本エントリでは、CloudFrontのVPC Originの利用による構成への影響、CloudFrontを使った静的リソースの配信について触れました。 特にCloudFrontのVPC Originを利用することでパブリックサブネットの利用を最小化することはセキュリティ観点でポジティブに捉えて良いでしょう。 今後はCloudFront + VPC Origin + ロードバランサーの組み合わせがAWSの構成のデファクトスタンダードとなる可能性もあるかもしれないとも感じました。

また、静的リソース配信についてはCloudFront + S3の組み合わせが大量アクセスを捌くといった観点でも非常に重要なので設定しない手はないと言えるでしょう。