概要

はじめに

  • 今回は、CloudFront とオリジン間の通信にHTTPSを使用する設定をご紹介します。本記事で紹介する設定によって、クライアント → CloudFront → オリジン間の通信が全てHTTPS となります。
  • 参考として、CloudFront の基本的な設定から代替ドメイン名(CNAME)の設定までを下記記事にまとめています。下記の記事では、クライアントからCloudFrontまでのアクセスをHTTPS通信とし、CloudFront からオリジンまでのアクセスをHTTP通信としております。
概要はじめに今回は、CloudFront のディストリビューションに代替ドメイン名(CNAME)を設定する方法をまとめます。代替ドメイン名の設定によって、ディストリビューションにデフォルトで割り当てられたドメイン名ではなく独自のドメイン名 (例: www.example.com) が...

前提条件

  • 事前に、SSL 証明書を準備します。証明書は、CloudFrontのディストリビューションと、オリジンに設定する2つの証明書が必要になります。今回は、Certificate Manager(ACM)で証明書を発行します。

CloudFront-オリジン間をHTTPS通信にする

概要図

  • やりたいことを図示すると下記となります。CloudFrontからオリジン(ELB)間もHTTPSとするため、証明書は2つ準備します。

オリジンの設定

  • CloudFront のコンソールを開きます。左のメニューより[Distributions]を選択し、[Create Distribution]を押します。
  • Origin Domain Name(オリジンドメイン名)を指定します。今回は、ELB 名を指定しています。(← 詳細は後述しますが、私の場合この指定の方法でハマりました)
  • CloudFront → オリジン間をHTTPS通信とするため、Origin Protocol Policy(オリジンプロトコルポリシー)を”HTTPS Only” とします。Minimum Origin SSL Protocol(最小限のオリジン SSL プロトコル)は、TLSv1.2とします。

キャッシュ動作の設定

  • Viewer Protocol Policy(オリジンプロトコルポリシー)をHTTPS Only(HTTPS のみ)とし、クライアントからのアクセスがHTTPS を使用している場合にのみコンテンツにアクセス可能とします。これで、クライアント → CloudFront → オリジン間の通信が全てHTTPS となります。

オリジンをHTTPS通信にしたらCloudFrontから502エラー

オリジンの設定でハマったこと

  • ディストリビューションを作成してデプロイの完了後、クライアントからcurlコマンド確認した結果、CloudFrontからエラーが返りました。「502 ERROR ERROR: The request could not be satisfied」のエラーです。
  • 今回、私がハマったところは、前述のOrigin Domain Name(オリジンドメイン名)にELB名を指定していたため、証明書のコモンネームと一致せず、502エラーとなりました。
niikawa@niikawa1:~$ curl https://niikawa-test.example.com/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>502 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
CloudFront wasn't able to connect to the origin.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: fBFXRSG-Z3z7qnrPkU1vK7pfIU9sMCKyFanvdbHU8cl6IHb-amGg0A==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>niikawa@niikawa1:~$
  • 正しくは、Origin Domain Name(オリジンドメイン名)をELB名ではなく、カスタムドメイン名で指定します。
  • あらかじめ、カスタムドメイン名に指定したELBに証明書が設定され、Route 53 にDNSレコード登録されている必要があります。

CloudFrontから502エラーとなるその他のケース

  • 私がハマったケース以外に、502エラーとなるその他のケースをご紹介します。証明書が失効しているケースやオリジンサーバーに自己署名証明書を使用している場合に、CloudFrontから502エラーを返します。CloudFrontのオリジンには自己署名証明書ではなく、ACMを使用しましょう(ACMで証明書を発行する or ACMに証明書をインポートする)。
    • クライアントからオリジンまでの流れは下記となり、いずれも証明書を2つ準備しています。
    • クライアント → CloudFront (TLS @ACM) → ELB (TLS @ACM) → Nginx (http)
      -> 200 OK
    • クライアント → CloudFront (TLS @ACM) → ELB (pass-thru) → Nginx (TLS @自己署名)
      -> 502エラー
  • 以下Amazon CloudFront開発者ガイドの抜粋です。

失効した証明書、無効な証明書、または自己署名証明書をオリジンサーバーが返したり、間違った順番の証明書チェーンを返したりした場合、CloudFront は TCP 接続を中断し、HTTP ステータスコード 502 (Bad Gateway) を返して、X-Cache ヘッダーを Error from cloudfront に設定します。中間証明書を含め、証明書チェーンが完全でない場合も、CloudFront は TCP 接続を中断します。

参考資料

概要はじめに今回は、CloudFront のディストリビューションに代替ドメイン名(CNAME)を設定する方法をまとめます。代替ドメイン名の設定によって、ディストリビューションにデフォルトで割り当てられたドメイン名ではなく独自のドメイン名 (例: www.example.com) が...
CloudFront とカスタムオリジン間の通信に HTTPS を必須にする場合、CloudFront がディストリビューションに割り当てたドメイン名 (d111111abcdef8.cloudfront.net など) を使用しているか、独自の代替ドメイン名 ( example.com など) を使用しているかによって、実...

元記事はこちら

CloudFront-オリジン間をHTTPS通信にする