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

2020-04-22

概要

はじめに

  • 今回は、CloudFront とオリジン間の通信にHTTPSを使用する設定をご紹介します。本記事で紹介する設定によって、クライアント → CloudFront → オリジン間の通信が全てHTTPS となります。
  • 参考として、CloudFront の基本的な設定から代替ドメイン名(CNAME)の設定までを下記記事にまとめています。下記の記事では、クライアントからCloudFrontまでのアクセスをHTTPS通信とし、CloudFront からオリジンまでのアクセスをHTTP通信としております。
 

前提条件

  • 事前に、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 接続を中断します。
   

参考資料