今回起きた現象
オリジンサーバーはしっかりhttps化してあってwebからは何の問題もないのにCloudFrontでオリジンとの通信をhttps onlyにすると502エラーが出て通信できない。
原因1
まず一番の原因はサーバーに設定する証明書が間違っていたことです。
今回私は、オリジンサーバーをhttps化するためにLet’s Encryptを採用したのですがいつもcertbotが勝手に設定してくれていてサーバー証明書や中間証明書などがよくわかっていませんでした。
普通サーバー証明書を設定するときはサーバー証明書と中間証明書を含んだfullchain.pem
のパスを指定するのですが私はサーバー証明書のみのcert.pem
を指定してしまいました。これが原因でエラーが出てしまっていたんですね。
これどうやって気づいたかというんですけどAWSのドキュメントにこんなことが書いてあったんですね。
openssl s_client -connect origin domain name:443
まぁ簡単に言えば上のコマンド実行してエラーが出たらサーバー証明書に問題がある可能性があるってことなんですけどしっかりエラーが出たんですよね。
まぁ見事に上のコマンドでエラーが出たんですけど(トラブルシューティングに必死すぎてスクショ忘れました。)
Verify return code: 21 (unable to verify the first certificate)
解決法ggりました。そしたら「チェインに含まれる証明書が一つしかなく、かつそれが自己署名されていないために、証明書がまったく検証できない」ってことだったんでサーバーの設定見返してみたらしっかり証明書の種類を間違えていました。
解決策1
これに関しては普通に設定を変えるだけです。ほんと初歩過ぎました。
原因2
これで治ったーと思ってまたopensslのコマンド打ってなんもエラー出なかったぁーって思ったんですけどこれでも502エラーは治らないんですよね….
そしてまたドキュメント探ってたらすぐ下に
openssl s_client -connect origin domain name:443 -servername CNAME
めちゃくちゃ省略しているんですけどHostヘッダーをフォワードしてる場合は -servername
をつけて実行してねということです。これで実行してみるとしっかりエラーが出てこれもまた。
Verify return code: 21 (unable to verify the first certificate)
これでした。けど今まではオリジンサーバーHostに対するものだったのがそのCloudFrontに対するドメインに対してエラーが出ていたんですよ。
結果的に考えたらわかったかもしれないけどHostヘッダーをフォワードしているからオリジンサーバーの証明書にオリジンサーバーのドメインだけでなくCloudFrontに設定しているサーバーの分の証明書も必要だったってことです。
解決策2
普通に証明書の取り直しです。ほんと無料の証明書でよかったなと思いました。これで502エラーはなくなって正常に動作しました。
終わりに
原因1のほうはほんと初歩的だなぁと思いましたけど原因2のほうはほんと思いつかなかったですね。
ほんとAWSのドキュメント様様です。これで三日ぐらい悩みましたからね。
まぁ今回は勉強になったし同じように困っている人に届けばいいなぁっと思いました。
いかにドキュメントが偉大か改めて感じました。
参考にしたサイト
- AWS様のドキュメント
- HTTP 502 status code (Bad Gateway)
- ぷちめもさん(sslのエラーの時に参考にしました。)
- Verify return code: 21 (unable to verify the first certificate)
コメント