AWSの自社認証局への移行に備える方法

タイトルは思いつかなかったのでパクりました。

 `[Action Required] Amazon S3 and Amazon CloudFront migrating default certificates to Amazon Trust Services in March 2021` というメールが飛んできており、何をしたらよいか？と聞かれたので調べました。TLS接続ができなくなるなんて考えてもなかったので漠然と大丈夫だろうとは思ってましたが、いざ聞かれると不安だったので。


結論としては利用しているアプリケーションによるとしか言えません。アプリによってルート証明書の管理の仕方が違うからです。
詳しくはAWSのBlogで「[AWSの自社認証局への移行に備える方法](https://aws.amazon.com/jp/blogs/news/how-to-prepare-for-aws-move-to-its-own-certificate-authority/)」という記事があるので読みましょう。



概要
==========

メール中にあったAWSのBlogの「[AWSの自社認証局への移行に備える方法](https://aws.amazon.com/jp/blogs/news/how-to-prepare-for-aws-move-to-its-own-certificate-authority/)」に書いてある通り、AWSのサービスは徐々にAWSの自社認証局から証明書を発行する方向になっているようです。
自社認証局の証明書が扱えないと2021/03以降にS3やCloudFrontの利用に影響があるから確認してね、というのがこのメールの内容でした（と機械翻訳から解釈）。



動きを見てみる
==========

以下で確認してみます。手元の環境はWindows 10でアップデートはちゃんとしている環境です。

- "eu-north-1" にS3バケットを作成する（AWSの自社認証局を使っているリージョンを選ぶ）
- S3バケットにアクセスできることを確認する（SSLエラーでなければよい。なので、Access Deniedでもよい。）
- ルート証明書を失効させる
- S3バケットにアクセスできなくなることを確認する

まずはChromeで試しました。
Chromeはルート証明書は内部で持ってると思っていたんですが、[Windowsの場合はOSの証明書ストアを見ているようです。](https://www.chromium.org/Home/chromium-security/root-ca-policy)

Windowsではcertmgrにある「信頼されたルート証明機関」にある証明書を「信頼されていない証明書」にドラッグ＆ドロップすると失効にできます。（他の環境では最初はなかったりしたので、1度アクセスしないと出てこないかもしれません。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52527/e442a8d4-daa8-bc1d-cb8f-f2f46d3452ea.png)

失効後に再度アクセスしてみます。しかし、問題なくアクセスできたので困惑します。
調べてみると別のルート証明書を使って検証がパスされていました。クロスルートな証明書になっているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52527/0f9435e2-f700-7f66-6f2b-112c8544a50b.png)

上記のAWSのBlogにある Starfield Class 2 Certification Authority 等の関係なさそうな証明書が書かれていたのは、このために必要だったようです。

この証明書も含めて~~手あたり次第~~失効させてみると、確かにアクセスできなくなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52527/241b2ccf-ded1-0ebc-6a95-8ce4ef168c41.png)


余談ですがqiita.comもAmazon Root CA 1（おそらくAWS Certificate Manager）から証明書を発行しているのでアクセスできなくなります。



対応は？
==========

様々としか言えません。「対応方法がないとかこの記事は無価値！」という感じですが、そもそもアプリがルート証明書を自前で管理している可能性もあるためです。

例えば、現在のAWS CLIは内部のbotocore（Python用のAWS SDK）がcacert.pemを持っています。インストーラで入れた場合は以下です。

- AWS CLI v1: `C:\Program Files\Amazon\AWSCLI\runtime\Lib\site-packages\botocore\cacert.pem`
- AWS CLI v2: `C:\Program Files\Amazon\AWSCLIV2\botocore\cacert.pem`

つまり、OSが持つ証明書ストアを使っていないのでcertmgrで失効させても aws s3コマンドは通ります。逆を言えば、cacert.pemから当該の証明書を削除すると認証ストアが正しい状態だろうがアクセスできなくなります。

実際にAWS CLI v1で証明書を削除して試したところ以下のようなエラーになります。

```
SSL validation failed for https://バケット名.s3.eu-north-1.amazonaws.com/?list-type=2&prefix=&delimiter=%2F&encoding-type=url [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
```

他にもJavaならJAVA_HOMEの`jre\lib\security\cacerts`で持っており、keytoolで確認できます。aliasは違うかもしれません。

```
keytool -list -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -v -alias "amazonrootca1 [jdk]"
```


このようにルート証明書の管理はアプリケーションによるので対応方法は何とも言えない、という感じです。

といっても、blogに書かれている通りで、Amazon側もかなり配慮しています。

> AWS は Amazon Trust Services 認証局 があらゆるところで確実に使えるようにするために、2005年以降のほとんどのブラウザで信頼されているルート認証局である Starfield Services の認証局の一つを購入しました。これは Amazon Trust Services で発行された証明書を使うために何もする必要が無いことを意味しています。

2006年ごろからアップデートを一切行っていないような環境や、ルート証明書を自前で管理しているようなことをしていなければ問題はまずないと思います。
もし心配なら軽くチェックしてみましょう。httpsリクエストを投げて通るか試すだけでよいのでそう難しくはないはずです。