<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cloudfront | 伊東屋TECHブログ</title>
	<atom:link href="https://tech-itoya.com/tag/cloudfront/feed/" rel="self" type="application/rss+xml" />
	<link>https://tech-itoya.com</link>
	<description>千葉県・船橋市の総合園芸店が運営する技術ブログ</description>
	<lastBuildDate>Wed, 29 Oct 2025 14:43:58 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://tech-itoya.com/wp-content/uploads/2024/10/cropped-itoya-logo-32x32.png</url>
	<title>Cloudfront | 伊東屋TECHブログ</title>
	<link>https://tech-itoya.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Cloudfront を導入時はレートリミットにも気をつけよう</title>
		<link>https://tech-itoya.com/cloudfront-%e3%82%92%e5%b0%8e%e5%85%a5%e6%99%82%e3%81%af%e3%83%ac%e3%83%bc%e3%83%88%e3%83%aa%e3%83%9f%e3%83%83%e3%83%88%e3%82%82%e6%b0%97%e3%82%92%e3%81%a4%e3%81%91%e3%82%88%e3%81%86/</link>
					<comments>https://tech-itoya.com/cloudfront-%e3%82%92%e5%b0%8e%e5%85%a5%e6%99%82%e3%81%af%e3%83%ac%e3%83%bc%e3%83%88%e3%83%aa%e3%83%9f%e3%83%83%e3%83%88%e3%82%82%e6%b0%97%e3%82%92%e3%81%a4%e3%81%91%e3%82%88%e3%81%86/#respond</comments>
		
		<dc:creator><![CDATA[tori-dash]]></dc:creator>
		<pubDate>Sat, 04 Oct 2025 15:28:51 +0000</pubDate>
				<category><![CDATA[TECH記事]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Cloudfront]]></category>
		<guid isPermaLink="false">https://tech-itoya.com/?p=318</guid>

					<description><![CDATA[目次 はじめに構成図4XX 系エラーの原因原因1. WAF の Ratelimit による 403 エラー原因2. アプリケーション (laravel) API Throttle による 429 エラーCloudfron [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">はじめに</a></li><li><a href="#toc2" tabindex="0">構成図</a></li><li><a href="#toc3" tabindex="0">4XX 系エラーの原因</a></li><li><a href="#toc4" tabindex="0">原因1. WAF の Ratelimit による 403 エラー</a></li><li><a href="#toc5" tabindex="0">原因2. アプリケーション (laravel) API Throttle  による 429 エラー</a><ol><li><a href="#toc6" tabindex="0">Cloudfront で、CloudFront-Viewer-Address をヘッダーを付与</a></li><li><a href="#toc7" tabindex="0">ApacheでCloudFront-Viewer-Addressを受け取り、RemoteIP に設定</a></li></ol></li><li><a href="#toc8" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">はじめに</span></h2>



<p>先日ALBの前段にCloudFrontを導入した際に、4XX系のエラーが爆増する現象に遭遇しました</p>



<p>開発環境での確認段階で気づけたのでセーフでしたが、ある程度リクエスト量をかけないと再現しない現象で見落としそうになったため、備忘録を残しておきます</p>



<p>同様の構成を検討されている方々の参考になれば幸いです。</p>



<h2 class="wp-block-heading"><span id="toc2">構成図</span></h2>



<p>今回想定しているインフラの構成は以下です</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="882" height="224" src="https://tech-itoya.com/wp-content/uploads/2025/05/image.png" alt="" class="wp-image-330" srcset="https://tech-itoya.com/wp-content/uploads/2025/05/image.png 882w, https://tech-itoya.com/wp-content/uploads/2025/05/image-300x76.png 300w, https://tech-itoya.com/wp-content/uploads/2025/05/image-768x195.png 768w" sizes="(max-width: 882px) 100vw, 882px" /></figure>



<p>なお、Cloudfront の後ろに WAF を配置した理由は、<strong> CDNキャッシュ後にWAFを通すことでWAFルールが検査するリクエスト数が減る</strong>のでコストメリットがありそうと考えたためです。</p>



<h2 class="wp-block-heading"><span id="toc3">4XX 系エラーの原因</span></h2>



<p>Cloudfront 導入後に 4XX 系エラーが増加してしまった原因は大きく 2 つありました</p>



<ol class="wp-block-list">
<li><span class="marker-under"><strong>WAFのRatelimitルールによるブロック</strong></span></li>



<li><span class="marker-under"><strong>アプリケーション(PHP, Laravel)のRatelimit</strong></span></li>
</ol>



<p>両方に共通する根本原因は、Cloudfrontを経由することで、WAFやアプリケーションから見たクライアントのIPアドレスが、実際のユーザーのIPではなくCloudfrontのエッジサーバーのIPアドレスに置き換わってしまったことでした。</p>



<p>図解すると、以前は以下のように User IP を直接とれていましたが</p>



<figure class="wp-block-image size-full"><img decoding="async" width="878" height="216" src="https://tech-itoya.com/wp-content/uploads/2025/05/tori-20250505-1.png" alt="" class="wp-image-323" srcset="https://tech-itoya.com/wp-content/uploads/2025/05/tori-20250505-1.png 878w, https://tech-itoya.com/wp-content/uploads/2025/05/tori-20250505-1-300x74.png 300w, https://tech-itoya.com/wp-content/uploads/2025/05/tori-20250505-1-768x189.png 768w" sizes="(max-width: 878px) 100vw, 878px" /></figure>



<p>Cloudfront導入後は IP が置換されてしまうため、正しいクライアントIPが認識できなくなり、多数のリクエストがレートリミットでブロックされてしまいました。</p>



<figure class="wp-block-image size-full"><img decoding="async" width="855" height="204" src="https://tech-itoya.com/wp-content/uploads/2025/05/スクリーンショット-2025-05-05-104110.png" alt="" class="wp-image-329" srcset="https://tech-itoya.com/wp-content/uploads/2025/05/スクリーンショット-2025-05-05-104110.png 855w, https://tech-itoya.com/wp-content/uploads/2025/05/スクリーンショット-2025-05-05-104110-300x72.png 300w, https://tech-itoya.com/wp-content/uploads/2025/05/スクリーンショット-2025-05-05-104110-768x183.png 768w" sizes="(max-width: 855px) 100vw, 855px" /></figure>



<h2 class="wp-block-heading"><span id="toc4">原因1. WAF の Ratelimit による 403 エラー</span></h2>



<p>400 系エラーが増えた 1 つ目の原因は WAF によるレート制限です</p>



<p>WAFには、DDos的なアクセスへの対策として、同一IPからの一定レートを超えるアクセスはブロックするルールが設定されていました</p>



<p>ただ構成図で示した通り、今回はWAFの前段にCloudfrontがいるため、何も意識をしないと Cloudfront の IP を見てレート制限をかけてしまいます</p>



<p>対策としては、WAFのレート制限はIPアドレスをどの値で集計するか選ぶことが出来るため、<strong>Source IP を使った集計ではなく、<code>X-Fowarded-For</code> ヘッダーの値から集計するように設定する</strong>ことで、クライアントのIPを正しく判定できるようになりました。</p>



<p>コンソールから設定する場合、<strong><code>リクエストの集約</code>を [ヘッダー内のIPアドレス]、<code>ヘッダーフィールド名</code> を「X-Forwarded-For」に設定</strong>することで、Cloudfrontの前段にあるIPアドレスを見てレート制限をかけることができます</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="797" height="807" src="https://tech-itoya.com/wp-content/uploads/2025/05/tori-20250505-3.png" alt="" class="wp-image-331" srcset="https://tech-itoya.com/wp-content/uploads/2025/05/tori-20250505-3.png 797w, https://tech-itoya.com/wp-content/uploads/2025/05/tori-20250505-3-296x300.png 296w, https://tech-itoya.com/wp-content/uploads/2025/05/tori-20250505-3-768x778.png 768w" sizes="(max-width: 797px) 100vw, 797px" /></figure>



<h2 class="wp-block-heading"><span id="toc5">原因2. アプリケーション (laravel) API Throttle  による 429 エラー</span></h2>



<p>Webアプリケーション側でも、IPベースでのAPIのレート制限機能を持っています。<br>今回の環境でも、Laravel の API Throttle 機能が有効化されており、アプリケーションレイヤーでも 429 エラーを返していました</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>API Throttleの参考: <a href="https://kinsta.com/jp/blog/laravel-throttle/">https://kinsta.com/jp/blog/laravel-throttle/</a></p>
</blockquote>



<p>そこで、対策として以下の設定を追加しました</p>



<ol class="wp-block-list">
<li><span class="marker-under"><strong>Cloudfront で、CloudFront-Viewer-Address をヘッダーを付与して後続のALBに流す</strong></span></li>



<li><span class="marker-under"><strong>Apche で CloudFront-Viewer-Address を受け取り、RemoteIP として扱う設定を追加する</strong></span></li>
</ol>



<h3 class="wp-block-heading"><span id="toc6">Cloudfront で、CloudFront-Viewer-Address をヘッダーを付与</span></h3>



<p>Cloudfront では後続のALBになどにHTTPリクエストをリレーする際、追加ヘッダーを設定することができ、そのうちの一つに「CloudFront-Viewer-Address」というヘッダーがあります。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><code>CloudFront-Viewer-Address</code>&nbsp;– ビューワーの IP アドレスと、リクエストのソースポートを示します。例えば、<code>198.51.100.10:46532</code>&nbsp;のヘッダー値は、ビューワーの IP アドレスが 198.51.100.10 で、リクエストのソースポートが 46532 であることを意味します。</p>
</blockquote>





<a rel="noopener" href="https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html" title="CloudFront &#12398;&#12522;&#12463;&#12456;&#12473;&#12488;&#12504;&#12483;&#12480;&#12540;&#12434;&#36861;&#21152;&#12377;&#12427; - Amazon CloudFront" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Fdocs.aws.amazon.com%2Fja_jp%2FAmazonCloudFront%2Flatest%2FDeveloperGuide%2Fadding-cloudfront-headers.html?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">CloudFront &#12398;&#12522;&#12463;&#12456;&#12473;&#12488;&#12504;&#12483;&#12480;&#12540;&#12434;&#36861;&#21152;&#12377;&#12427; - Amazon CloudFront</div><div class="blogcard-snippet external-blogcard-snippet">CloudFront HTTP リクエストヘッダーを追加して、ビューワーのデバイスタイプ、IP アドレス、地理的位置、リクエストプロトコル (HTTP または HTTPS)、HTTP バージョン、TLS 接続の詳細、および JA4 フィンガ...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">docs.aws.amazon.com</div></div></div></div></a>




<p>これを使えば後続処理に、実際のリクエスト元の IP を渡すことができます</p>



<p>以下のようなオリジンリクエストポリシーを作成し、対象のビヘイビアに紐づけることで、「CloudFront-Viewer-Address」ヘッダーを後続に送ることができます。</p>



<ul class="wp-block-list">
<li><strong>ポリシー名等: 任意</strong></li>



<li><strong>ヘッダー: すべてのビューワーヘッダーと次の Cloudfront ヘッダー</strong></li>



<li><strong>add header: CloudFront-Viewer-Address</strong></li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="429" src="https://tech-itoya.com/wp-content/uploads/2025/10/tori-20251004-1-1024x429.png" alt="" class="wp-image-335" srcset="https://tech-itoya.com/wp-content/uploads/2025/10/tori-20251004-1-1024x429.png 1024w, https://tech-itoya.com/wp-content/uploads/2025/10/tori-20251004-1-300x126.png 300w, https://tech-itoya.com/wp-content/uploads/2025/10/tori-20251004-1-768x322.png 768w, https://tech-itoya.com/wp-content/uploads/2025/10/tori-20251004-1-1536x644.png 1536w, https://tech-itoya.com/wp-content/uploads/2025/10/tori-20251004-1.png 1811w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"><span id="toc7">ApacheでCloudFront-Viewer-Addressを受け取り、RemoteIP に設定</span></h3>



<p>上記ステップにより、Cloudfront から CloudFront-Viewer-Address ヘッダーが送られてきます。</p>



<p>これを Apache 側で RemoteIP としてセットしてあげることで、PHPなどアプリケーション層でも正しいIPを認識できるようになります。</p>



<p>CloudFront-Viewer-Address は形式に少し癖があり、<code><strong>198.51.100.10:46532</strong></code> のように IP アドレスの後ろにポート番号がついてしまうため、これを取り除いてあげる必要があります。</p>



<p>apache の httpd.conf ファイルに以下を追加してあげることで、Remote IP に正しいIPが設定されました。</p>



<pre class="wp-block-code"><code>... (もとの設定) ...

# CloudFront-Viewer-Address から IP 部分のみを抽出 (例: CloudFront-Viewer-Address: 192.30.252.129:443)
SetEnvIf CloudFront-Viewer-Address "^(&#91;0-9.]+):" VIEWER_IP=$1

# 抽出した IP アドレスを RemoteIPHeader として使用
RequestHeader set X-VIEWER-IP %{VIEWER_IP}e env=VIEWER_IP
RemoteIPHeader X-VIEWER-IP

... (もとの設定) ...</code></pre>



<h2 class="wp-block-heading"><span id="toc8">まとめ</span></h2>



<p>Cloudfront 導入時などはIPがつけ変わるため、後段のアプリケーションやWAFなどでIP制限をかけている場合はそこにも注意が必要だよというお話でした。</p>
		<div class="wpulike wpulike-heart " ><div class="wp_ulike_general_class wp_ulike_is_restricted"><button type="button"
					aria-label="いいねボタン"
					data-ulike-id="318"
					data-ulike-nonce="d63181ca08"
					data-ulike-type="post"
					data-ulike-template="wpulike-heart"
					data-ulike-display-likers=""
					data-ulike-likers-style="popover"
					class="wp_ulike_btn wp_ulike_put_image wp_post_btn_318"></button><span class="count-box wp_ulike_counter_up" data-ulike-counter-value="+1"></span>			</div></div>
	]]></content:encoded>
					
					<wfw:commentRss>https://tech-itoya.com/cloudfront-%e3%82%92%e5%b0%8e%e5%85%a5%e6%99%82%e3%81%af%e3%83%ac%e3%83%bc%e3%83%88%e3%83%aa%e3%83%9f%e3%83%83%e3%83%88%e3%82%82%e6%b0%97%e3%82%92%e3%81%a4%e3%81%91%e3%82%88%e3%81%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
