👀

【初心者向け】CloudFrontとALB間のHTTPS接続がうまくいかなかった件

2023/03/26に公開

はじめに

どうも、BASECAMP ESSENTIALS 参加者の崎山です!

今回苦戦したCloudFrontとALB間のHTTPS接続について書きたいと思います。
意外と初心者の方は引っかかる箇所だと思いますので、この記事が参考になればうれしいです。
ちなみに接続時のエラーは、HTTP 502 ステータス コード (Bad Gateway) が出力されました。

【引用:HTTP 502 status code (Bad Gateway)】
HTTP 502 ステータス コード (Bad Gateway) は、CloudFront がオリジン サーバーに接続できなかったため、要求されたオブジェクトを提供できなかったことを示します。

構成図

前提

なぜHTTPS接続ができなかったのか

CloudFrontを作成する時に、オリジンドメインを入力する項目があるかと思います。その時にプルダウンから対象のALBを選択してしまうと、対象が作成されたときにAWS側によって生成されたドメインが入力されます。このドメインにはSSL/TLS証明書が紐づいていないため、CloudFrontからALB(オリジン)に対してHTTPS接続を行ったとしてもネゴシエーションがうまくいかず、到達することができません。だからHTTP 502 ステータス コード (Bad Gateway) が出力されたのです。
オリジンドメインの入力画面
ALB作成時に生成されたDNSドメイン
ブラウザからのHTTPS接続失敗
ログからも502エラーによりアクセスが失敗していることが分かります。
またCloudFrontからALBへの接続が失敗しているため、ALBログには何も出力されていません。

CloudFrontの標準ログ
#Fields: date time x-edge-location sc-bytes c-ip cs-method cs(Host) cs-uri-stem sc-status cs(Referer) cs(User-Agent) cs-uri-query cs(Cookie) x-edge-result-type x-edge-request-id x-host-header cs-protocol cs-bytes time-taken x-forwarded-for ssl-protocol ssl-cipher x-edge-response-result-type cs-protocol-version fle-status fle-encrypted-fields c-port time-to-first-byte x-edge-detailed-result-type sc-content-type sc-content-len sc-range-start sc-range-end
2023-03-17	08:37:50	NRT57-P3	1194	xxx.xxx.xxx.xxx	GET	dpekz4s0xzujc.cloudfront.net	/	502	-	Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/111.0.0.0%20Safari/537.36	-	-	Error	zurs8x7CL4FSngdxjAkYoAE_dPTtiyGnS16GImPcfRwUl2eaHhfiBQ==	dpekz4s0xzujc.cloudfront.net	https	457	0.011	-	TLSv1.3	TLS_AES_128_GCM_SHA256	Error	HTTP/2.0	-	-	62612	0.011	OriginConnectError	text/html	951	-	-

ログの見方はこちら:標準ログ (アクセスログ) の設定および使用

オリジンドメインを修正する

今度はSSL/TLS証明書(ACM証明書)が紐づいているALBのドメインを入力します。
[cloudfront -> 対象ディストリビューション -> オリジン -> 対象オリジン -> 編集 -> 保存]
オリジンドメインの編集画面
ACM証明書
ALBに紐づく証明書

修正後の接続確認をする

CloudFrontのデプロイが完了したら、接続確認を行います。
ブラウザから接続確認
【CloudFrontログの見方】

CloudFrontの標準ログの確認
#Fields: date time x-edge-location sc-bytes c-ip cs-method cs(Host) cs-uri-stem sc-status cs(Referer) cs(User-Agent) cs-uri-query cs(Cookie) x-edge-result-type x-edge-request-id x-host-header cs-protocol cs-bytes time-taken x-forwarded-for ssl-protocol ssl-cipher x-edge-response-result-type cs-protocol-version fle-status fle-encrypted-fields c-port time-to-first-byte x-edge-detailed-result-type sc-content-type sc-content-len sc-range-start sc-range-end
2023-03-17	09:27:13	NRT57-C3	4549	xxx.xxx.xxx.xxx	GET	dpekz4s0xzujc.cloudfront.net	/icons/apache_pb2.gif	200	https://dpekz4s0xzujc.cloudfront.net/	Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/111.0.0.0%20Safari/537.36	-	-	Miss	nMAoqyTzFb1QlZL4XRhDbONVlqOX90hIkkMh97FpdfPGeFdhlokn1A==	dpekz4s0xzujc.cloudfront.net	https	141	0.022	-	TLSv1.3	TLS_AES_128_GCM_SHA256	Miss	HTTP/2.0	-	-	64277	0.022	Miss	image/gif	4234	-	-

【ALBログの見方】

ALBのアクセスログの確認
https 2023-03-17T09:27:13.101083Z app/alb-test/96e12a2c8669fbe5 70.132.40.151:63288 10.0.4.254:80 0.000 0.002 0.000 200 200 804 4483 "GET https://dpekz4s0xzujc.cloudfront.net:443/icons/apache_pb2.gif HTTP/1.1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36" ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 arn:aws:elasticloadbalancing:ap-northeast-1:XXXXXXXXXXXX:targetgroup/alb-tg/d3bb7ccab2dace96 "Root=1-XXXXXXX-2xxxxaf0e4752d74ebca925" "dpekz4s0xzujc.cloudfront.net" "arn:aws:acm:ap-northeast-1:XXXXXXXXXXXXX:certificate/ae66ff29-9f0c-4f59-bbfb-473a03b7df43" 0 2023-03-17T09:27:13.098000Z "forward" "-" "-" "10.0.4.254:80" "200" "-" "-"

# 70.132.40.151 = server-70-132-40-151.nrt57.r.cloudfront.net
# 10.0.4.254 = EC2(Web Server)

正常にHTTPS接続ができており、レスポンスが返ってきているのが分かります。

そもそもなぜSSL/TLS証明書が必要なのか

HTTPSはサーバとブラウザ間の通信を暗号化するための規格です。暗号化通信をするにあたってSSL/TLS証明書が必要となります。この証明書を使用して行われていることは、リクエスト先のサーバーの認証です。この認証が失敗した場合、暗号化通信はできません。

詳しくは下記を見て下さい。
Symantec - いまさら聞けない、SSLサーバ証明書とルート証明書の関係

最後に

今回CloudFrontを初めて触ったのですが、想像していたよりも難しいサービスでした。
そもそもHTTPSでSSL/TLS証明書がどのように使用されているのかが分かっていなかったため、
CloudFrontとオリジン間のHTTPS接続設定には苦戦しました。
ですが今回はいろいろと勉強になったので良かったです。

参考リンク一覧

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/using-https.html
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/using-https-viewers-to-cloudfront.html
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/using-https-cloudfront-to-custom-origin.html
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/http-502-bad-gateway.html
https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudfront-https-connection-fails/
https://dev.classmethod.jp/articles/amazon-cloudfront-cname-and-host-header-test/

デベキャン

Discussion