【備忘録】Greengrass(V1)のMQTTサーバ証明書について

#1　概要
Greengrass(V1)では、GreengrassデバイスがGreengrassコアデバイス（以下、コアデバイス）接続する際にグループ証明書を使っています。
Greengrassデバイスはデバイス証明書を用いてコアデバイスのMQTTサーバ証明書を検証します。
参考：[AWS IoT Greengrass セキュリティの概要](https://docs.aws.amazon.com/ja_jp/greengrass/v1/developerguide/gg-sec.html)

コアデバイスのMQTTサーバ証明書はデフォルトの有効期限が7日間となっています。
有効期限が切れる前のタイミングでコアデバイスがIoT Greengrassサービス（クラウド側）に接続し、新たなMQTTサーバ証明書を取得します。
当然、このタイミングでクラウド側と接続できる必要があります。

MQTTサーバ証明書の有効期限はデフォルトの7日から30日まで変更できます。
ベストプラクティスは短い期間でのローテーションです。
※ただし、申請すれば31日以上にもできるとのこと
参考：[AWS IoT Greengrass のデバイス認証と認可 - ローカル MQTT サーバーの証明書ローテーション](https://docs.aws.amazon.com/ja_jp/greengrass/v1/developerguide/device-auth.html)

MQTTサーバ証明書の更新はマネジメントコンソールから手動でも可能です。
今回は触ってみた際の結果を残しておきます。
#2　更新してみる
MQTTサーバ証明書を更新すると、MQTTサーバがいったん再起動するため、接続がいったん切断されます。
また、Greengrassデバイスはグループ証明書の再取得が必要になります。
今回は、AWS IoT Device SDK for PythonのSample実行時にどのような挙動をしたか備忘録として残します。
※サンプルコードの中身をまだ十分咀嚼できていないので、目に見える動きと試した手順を残すに留める

1.IoT Coreのマネジメントコンソールで左のメニューから Greengrass > クラシック(V1) > グループ の順にクリック
2.対象のグループをクリックし、設定 をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/533dcdbd-3352-4d80-22fe-20ddaf133c38.png)
3.「CAのローテーション」をクリックし、モーダルウィンドウで「今すぐローテーションと切断」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/d78f935f-7d66-f9f5-c2c8-2bf3cfd6bccb.png)
4.画面上部に「グループのCAが正常にローテーションされました」と表示されたら完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001693/a8ec2556-9511-d055-bb2c-00dd3b544fcb.png)
#3　結果
どのファイルが更新されているのか、ローテーション時に動いていたコアデバイス-Greengrassデバイス間のメッセージのやり取りがどうなっていたかの備忘録です。
##更新されたファイル
ローテーションの実行は `/greengrass/ggc/var/log/system/GGDeviceCertificateManager.log` に記載がありました。

```GGDeviceCertificateManager.log
[2021-03-29T21:17:54.888+09:00][INFO]-Message from cloud        {"topic": "$aws/things/Greengrass_Test_Core_20210308-gcm/shadow/update/delta"}
[2021-03-29T21:17:54.888+09:00][INFO]-New CertificateManagerService version: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[2021-03-29T21:17:54.888+09:00][INFO]-Starting the workflow of Certificate generation
```
ファイルとしては、以下が更新されていました。

* /greengrass/ggc/var/state/server/server.crt
* /greengrass/ggc/var/state/server/server.key

##グループ内でのMQTTのやり取り
今回は、AWS IoT SDK for Pythonの samples/greengrass にある `basicDiscovery.py` を実行しています。
GitHub：[AWS IoT SDK for Python](https://github.com/aws/aws-iot-device-sdk-python)
※AWS IoT SDK for Pythonのインストールと `basicDiscovery.py`の実行までの手順は以下を参照のこと
　[モジュール 4: AWS IoT Greengrass グループでのデバイスの操作](https://docs.aws.amazon.com/ja_jp/greengrass/v1/developerguide/module4.html)

MQTTサーバ証明書をローテーションする前のタイミングから、2台のGreengrassデバイス（ラズパイとMac）でそれぞれ以下を実施していました。

* ラズパイ：MQTTメッセージを送り続ける
* Mac：MQTTメッセージをサブスクライブし続ける

結果として、ローテーションのタイミングでいずれもいったん処理が止まりました。
ラズパイは少しの停止後、再度メッセージを送り続けていましたが、Mac側はサブスクライブは再開しませんでした。

なお、グループ証明書は `basicDiscovery.py` を実行したディレクトリ（カレントディレクトリで実行した）に `groupCA/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_CA_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.crt` として取得されました。
#4　おわりに
MQTTサーバ証明書のローテーション後、再接続、グループCAの再取得が必要になります。
サンプルコードでどのようにしているか整理し、次は自身でプログラムを書いてみようと思います。
#5　参考文献（文中で登場していないもの）

* [AWS Black Belt Online Seminar - AWS IoT Greengrass](https://d1.awsstatic.com/webinars/jp/pdf/services/20201215-AWS%20ioT%20Greengrass.pdf)
* [AWS IoT Greengrass のセキュリティのベストプラクティス](https://docs.aws.amazon.com/ja_jp/greengrass/v1/developerguide/security-best-practices.html)