CloudFront-オリジン間をHTTPS通信にする
Contents
概要
はじめに
- 今回は、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 接続を中断します。