CloudFront + EC2インスタンスでACMで発行した証明書を適用したら、結局他の証明書も必要になった話。

先にまとめ

CloudFront⇔ELB以外のカスタムエンドポイントの通信をhttpsにしようとすると、結局ACM以外の証明書がいる。

起きたこと。

証明書の期限が近づき、そういえばこのサーバーはCloudFront使ってたよなーと。

EC2 のWebサーバーへ CloudFront 経由で AWS WAF を導入

これでWAFを入れるときには、まだ手前の証明書が残っていたのでCOMODOで発行した証明書を使っていました。

でもってお金かかるので、どうせCloudFront使ってるならACM使えばいいじゃないと。

AWS Certificate ManagerでSSL証明書を発行する

上記手順で、発行してブラウザから確認。

よーし発行できた!サーバーもいじらずに証明書を変えられるなんて便利だなー!

と、思っていたのですが、疑問点が浮かび上がりました。

ユーザー⇔CloudFront間はこれでOKですが、CloudFront⇔インスタンス間は?

つまりここ。

もともと証明書を使用していたサーバーと、CloudFront間の通信はリクエストをCloudFrontでそのまま流すようにしていたはず。

ということは、httpsで来たらhttpsを流すはず。なので、httpsでインスタンスとやり取りをやるはず。=SSL証明書いるじゃん。

とはいえ、ACMの証明書をそのまま使えばOKなので、手はあるのでは・・・と思いきや、

CloudFront とカスタムオリジンとの間の通信に HTTPS を必須にする

オリジンが Elastic Load Balancing ロードバランサーの場合、AWS Certificate Manager (ACM) が提供する証明書を使用できます。信頼されたサードパーティー認証機関が署名して ACM にインポートされた証明書を使用することもできます。
ELB ロードバランサー以外のオリジンの場合、信頼されたサードパーティー認証機関 (CA) (Comodo、DigiCert、Symantec など) によって署名された証明書を使用する必要があります。

だめだとしっかり書いてありますね。

CloudFront + ロードバランサー + ec2ならばロードバランサーとEC2を同一ネットワークに置き、インターネットを通さないで頑張ることで平文通信などはできそうですが、グローバルにあるCloudFrontに関してはまずい場合がある。

結局証明書を発行、2個の証明書を管理することに。

まぁ、インスタンスでLettsを使って発行したのをACM(CloudFront用)に適用する手間がなくなったのと、信用度合いの高い証明書でユーザーとCloudFrontが通信できるようになったのはいいことか。

まとめ

WAFだけの導入でもケチらずロードバランサー入れて導入にしとけば良かった。

おまけ

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

気づかなかった場合や、自己証明書でいいやとかやると死んでいた模様。