目的
ALBのSNIサポートによって複数の証明書を選択した際に、この機能を理解しておらずHTTPSリクエストが失敗するインシデントを引き起こしてしまいました。そのためALBのSNIに関する注意点を備忘録としてまとめます。また、本記事はドメイン移行を実施する際の参考になると思います。
ALBのSNIサポートについて
ALBで複数のドメインを捌きたい際に、これまでは複数のALBを用意する必要がありました。しかしAWSのアップデートにより、同一のロードバランサで複数の証明書を使えるようになりました。
Application Load BalancerがSNIを利用した複数のTLS証明書のスマートセレクションをサポートしました
インシデント内容について
インシデントは単純に HTTPSリクエストが失敗する という問題です。
イベント発生時系列
簡単にインシデント発生に陥ったイベントを時系列にまとめます。
(1) サードパーティからImportしたEV証明書(prod.exaple.com
)が近日中に失効することが発覚。
(2) 急遽ACMで発行した証明書(*.exaple.com
)をALBに追加。この時はSNIより複数のSSL証明書がアタッチされている状態。
(3) リリース時にRoute53でこのALBを向くように加重ルーティングポリシーを変更。
(4) リリース後にアプリケーションへのHTTPSリクエストが失敗していることが発覚。
直接原因
本番リリースの30分前にサードパーティからインポートした証明書が失効していたことがわかりました。
これによってALBがこの期限切れ証明書を掴んだままHTTPSリクエストが失敗したことが原因です。
応急処置
ALBやACM、Route53など残留していたExpireした証明書を消去することでHTTPSリクエストが失敗する問題は消えました。
根本原因
ALBが選択する証明書の優先順位
ALBは以下の優先順位によって、複数存在する証明書から最適な証明書を動的に判断します。
ロードバランサーは、SNI をサポートするスマート証明書の選択アルゴリズムを使用します。クライアントから提供されたホスト名が証明書リスト内の単一の証明書と一致する場合、ロードバランサーはこの証明書を選択します。クライアントが提供するホスト名が証明書リストの複数の証明書と一致する場合、ロードバランサーはクライアントがサポートできる最適な証明書を選択します。証明書の選択は、次の条件と順序に基づいて行われます。
(1)パブリックキーアルゴリズム (RSA よりも ECDSA が優先)
(2)ハッシュアルゴリズム (MD5 よりも SHA が優先)
(3)キーの長さ (最大が優先)
(4)有効期間
Application Load Balancer 用の HTTPS リスナーを作成する
今回のケースでALBに追加した全ての証明書は(1)-(3)の条件は同じであったので、(4)により有効期限内のACM発行ものが選択されるのでは?と思い、さらにドキュメントを読み込みました。
見落としていたところ
結論から言うとまず ALBは完全修飾ドメインに一致する証明書が優先的に選択されます。
前節ではSNIの選択優先順位を挙げましたが、以下の文章を見落としていました。
ロードバランサーは、SNI をサポートするスマート証明書の選択アルゴリズムを使用します。クライアントから提供されたホスト名が証明書リスト内の単一の証明書と一致する場合、ロードバランサーはこの証明書を選択します。
そういえばサードパーティからImportされた証明書はEV SSLでした。ACMではEV SSLは使えません。
EV SSLは証明書にワイルドカードが許されないためprod.exaple.com
で作成していました。
また今回ACMで急遽発行した証明書は*.exaple.com
でありワイルドカードがついていました。
これによりリクエストしたドメインが期限切れの証明書がサポートするドメインに完全一致していたため期限切れの証明書が引き続き選択されたことでHTTPSリクエストが失敗しました。
根本原因を特定してしまえば「なんだこんなことか」となってしまいますが、業務の中では見落としてしまいました。
今後の予防策
証明書の有効期限管理を徹底する。
ACMから発行したSSL証明書については、自動更新が適用されるため失効について意識することは少ないと思います。しかし今回はサードパーティからインポートしたSSL証明書であるため自動更新はされません。今後の対策として、Cloudwatchアラームにを使用して、Slack等にも期限アラートを構築したいと思います。
AWS Certificate Manager が Amazon CloudWatch を介した証明書の有効期限の監視の提供を開始
証明書更新のアップデート手順の更新
今回はALBのSNIで優先的に選択されるSSL証明書の期限がExpireしたため、HTTPSリクエストが失敗しました。期限切れという事態が生じてしまった場合に、SNIのリストから削除する等の手順を追加しました。現在この部分についてのCloudwatchイベントはサポートされていないようです。
まとめ
今回はALBのSNIによって引き起こしたインシデントと原因解明、今後の対策を共有しました。
そもそも証明書の有効期限が管理できていかなったことが問題ではありますが、その上でHTTPSリクエスが失敗する障害を引き起こしてしまいました。今後は失敗から学んだ対策を組織内に浸透させて,同じような事象が発生しないようにしたいです。