2021/09/30 から、OpenSSL1.0.x でLet'sEncryptの証明書を使っているところと接続できなくなる問題とEC2での対策方法

現象

$ echo|openssl s_client -connect helloworld.letsencrypt.org:443 -servername helloworld.letsencrypt.org
Verify return code: 20 (unable to get local issuer certificate)
  • OpenSSLを使っている、curl やRuby なども影響を受ける

原因

  • Let'sEncryptの証明書チェーンは、R3 --> ISRG Root X1 --> DST Root CA X3 となっている
  • この、DST Root CA X3 が 2021/09/30 に期限切れとなった
  • トラストストアには、ISRG Root X1 と、DST Root CA X3 が入っているが、OpenSSL 1.0.x では、 証明書チェーンの中に、トラストストアにあるが、期限切れの証明書があると、検証が失敗扱いになる という挙動がある

歴史的経緯

Let'sEncrypt がルート証明書を DST Root CA X3 から ISRG Root X1 に変更しようとする流れ

  • もともとの Let'sEncrypt のルート証明書は、DST Root CA X3
  • Let'sEncrypt は、ルート証明書を ISRG Root X1 に変えようとしていた
  • しかし、古いクライアントでは、トラストストアに、ISRG Root X1 が無いため、中間証明書を DST Root CA X3ISRG Root X1 のクロスサイン証明書にしていた(これにより、どちらかがトラストストアにあれば検証が通る)
  • その後、2021/09/30 に DST Root CA X3 の期限が切れるため、ルート証明書を ISRG Root X1 だけにする動きが始まる

Android7.1 問題と苦肉の策

  • しかし、Android7.1以前のバージョンにはISRGのルート証明書が入っていないため、ルート証明書を切り替えると、Android7.1以前でLet'sEncryptの証明書が使えなくなるという問題が判明
  • で、Let'sEncryptは苦肉の策として、以下のようにルート証明書を変更するとアナウンス
R3 --> ISRG Root X1 --> DST Root CA X3
  • ルート証明書の上にルート証明書をチェーンするという荒業
  • これをすると、Android7.1以前では、ISRGがトラストストアにないため、DSTまで遡る。ここで、2021/09/30 以降は、DSTの有効期限が切れてしまうが... Android7.1では、証明書の有効期限チェックを行わない ため、問題が解決すると... 解決...?
  • ISRGをトラストストアにもつ、他のクライアントではDSTまで遡らないため、特に問題はないはずだったが...

OpenSSL 1.0.x では Android互換チェーン の検証に失敗する

  • しかし、OpenSSL 1.0.x では、上記の「Android互換チェーン」については検証が失敗扱いとなる。これは、OpenSSL1.0.xで、信頼チェーンの間に無効な証明書があって、さらにそれがトラストストアに登録済だと、検証が失敗するという挙動(仕様?)のため

👇 Let'sEncrypt による、OpenSSL 1.0.x では Android互換チェーン の検証に失敗する件の記事

community.letsencrypt.org

  • OpenSSL 1.1.0 では修正済みで、1.0.x はたくさんの脆弱性があるので、さっさとバージョンをあげようとアナウンスしている

対策

OpenSSL公式は、トラストストアにて、期限切れのDSTのルート証明書を削除するようにと、アナウンスしている

https://t.co/bL7HmxKqcr?amp=1 www.openssl.org

AWS(EC2)では、ルート証明書のyumパッケージである ca-certificates にて、上記の対応を済ませたバージョンを配布しているので、yum update ca-certificates すれば解決する

aws.amazon.com

AWSでは、さらにこちらで手動対策方法もアナウンスしている

aws.amazon.com

参考

songmu.jp

songmu.jp

www.walbrix.co.jp