先にまとめ
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 接続を中断します。
気づかなかった場合や、自己証明書でいいやとかやると死んでいた模様。