注目の記事

【アップデート】Amazon CloudFront を経由しないアクセスのブロックが簡単になりました

CloudFront の IP が Managed Prefix List でサポートされたので、CloudFront を経由しない想定外のアクセスを簡単にブロックできるようになりました。オリジンを直接アクセスされて負荷が上がったり、AWS WAF を迂回したアクセスなどを簡単に塞ぐことができます。

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

ウィスキー、シガー、パイプをこよなく愛する大栗です。

先程のアップデートで CloudFront の IP アドレスが Managed Prefix List でサポートされました。これにより CloudFront を経由しない不正なアクセスを簡単に弾くことが可能になります。CMS など CloudFront を使う機会が多いサービスではぜひご利用ください。また CloudFront で AWS WAF を使ってセキュリティを向上している場合の迂回路を塞ぐことができます。

Amazon CloudFront now supports a managed prefix list

CloudFront を経由しないアクセス

今まで AWS で CloudFront を経由したアクセスだけ強制させる場合は、CloudFront ではカスタムヘッダを付与して、その値を ALB や Web サーバで検証する方法が取られていました。

リクエストにカスタム HTTP ヘッダーを追加するための CloudFront 設定

しかし、ドキュメントに下記の記述があるようにはカスタムヘッダの名前と値を秘密にする必要がありました。

重要
このユースケースは、カスタムヘッダー名と値の機密性維持を信頼しています。ヘッダー名と値が機密でない場合、他の HTTP クライアントは、Application Load Balancer に直接送信するリクエストにヘッダー名や値を含める可能性があります。これにより、リクエストをしていない時に、リクエストが CloudFront から送信されたかのように Application Load Balancer を動作させる可能性があります。これを防ぐためには、カスタムヘッダー名と値を機密にしておきます。

それ以外の方法としては CloudFront の IP アドレスの CIDR を確認して、それ以外をセキュリティグループで弾く方法もありますが、CIDR 多数であり不定期で変動するためメンテナンスが大変でした。(2022年2月8日時点で CloudFront の CIDR は 131個でした)

AWS IP アドレスの範囲

最初の方法では、カスタムヘッダを使用するため L7 での判断が必要になるので対応出来るサービスが限られます。2番目の方法ではメンテナンスコストが発生します。(自動化すれば良いんですけど面倒ですよね。。。)

ここで AWS がメンテナンスしてくれる Managed Prefix List で CloudFront が対象となったためユーザー側でのメンテナンスが不要になり、セキュリティグループやルートテーブルAWS Firewall Managerなど様々な機能で利用できるようになります。

やってみる

Amazon VPC のコンソールを開き、Managed Prefix Listsを選択します。ここではリージョンをバージニア北部にしています。

ここでcom.amazonaws.global.cloudfront.origin-facingを選択します。Prefix list ID がpl-3b927c52となっていますがアカウント横断で共通でリージョン毎に定義されているものです。

Entries タブを開くと登録されている CIDR が表示されています。https://ip-ranges.amazonaws.com/ip-ranges.jsonではCLOUDFRONTが131個と異なっています。もしかするとサーバサイドへアクセスするリージョナルエッジキャッシュに限定されて Managed Prefix List に登録されているのかもしれません。

では以下のような構成で実際に試してみます。CloudFront と EC2 は良い感じに仕立てておきます。

セキュリティグループのインバウンドルールの設定を行います。

HTTP で EC2 へアクセスするので Type をHTTPにします。Source を選択すると一番下に Prefix lists が出てくるので CloudFront のリストを選択します。

EC2 は Amazon Linux 2 で以下のようなコマンドを実行して準備しておきました。

Apache HTTP Server と PHP をインストールします。

$ sudo yum install -y httpd php

アクセス時の情報を見たいので、phpinfo()の結果を表示するページを作ります。

$ cat << EOF | sudo tee /var/www/html/index.php
> <?php
>     phpinfo(INFO_VARIABLES);
> EOF

Apache HTTP Server を起動します。

$ sudo systemctl start httpd

ポート 80 で http でアクセスできることを確認します。

$ curl http://127.0.0.1:80/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<style type="text/css">
・
・
・

CloudFront は下記のエントリなどを参考に設定しましょう。

実際にアクセスしてみます。

まずは CloudFront 経由でアクセスします。普通にアクセスできます。CloudFront 側のアクセス元であるREMOTE_ADDR64.252.110.121になっています。これは Managed Prefix List のエントリの64.252.64.0/18の範囲となります。 アクセス先のオリジンはec2-52-3-227-179.compute-1.amazonaws.comとなっています。

では、オリジンであるec2-52-3-227-179.compute-1.amazonaws.comへ直接アクセスしてみましょう。セキュリティグループでアクセスが許可されていないため以下のようになります。

さいごに

CloudFront はアクセスの高速化とオリジンの負荷軽減を主な目的に使用しますが、オリジンに直接アクセスされてしまうとオリジンの負荷が上がってしまいます。そのため CloudFront 以外からのアクセスをブロックすることは重要です。今まではリソースの負荷やメンテナンスの負荷が上がる方法が取られていましたが、今回の Managed Prefix List 対応により簡単に設定でブロックできますので、CloudFront を使われている方々はご利用頂ければと思います。