AWS IoT Coreの証明書を使ってGCPのCloud IoT Coreに接続する方法を紹介します!

これまでAWSのIoT Coreをずっと使ってきましたが、初めてGCPのIoT Coreに触れてみました。大きな違いは、証明書の発行機能がないこと。これはAzureも同様なので、AWSだけが特殊なのかもしれません。AWSのIoT Coreで発行した証明書でGCPも接続できるか試したところ、意外とすんなり行きましたので紹介です。


手順

AWS IoT Coreの証明書を作成

AWSのCLIで実行します。

aws iot create-keys-and-certificate \
  --certificate-pem-outfile certification.pem \
  --public-key-outfile public.key \
  --private-key-outfile private.key
💡
作成した証明書は手元に保管ください。

Cloud IoT Core APIの有効化

IoTのAPIを有効化します。

レジストリを作成

レジストリを作成します。Cloud Pub/Subのトピックも必要です。

💡
Cloud Pub/Subを指定しなくてもレジストリの作成はできるのですが、MQTTでのPublish/Subscribeに失敗してしまいます。

デバイスを作成

次はデバイスを作成します。

認証部分がオプションとなっていますが、先程AWSで作成した証明書をペーストします。

💡
証明書を登録します

パスワードを生成

MQTT接続のパスワードが必要ですので生成します。パスワードとしてJWTを生成します。(参考サイト① 参考サイト②

プロジェクトIDはGCPのプロジェクトのID、アルゴリズムはRS256を指定します。

 def create_jwt(project_id, private_key_file, algorithm):
     """Creates a JWT (https://jwt.io) to establish an MQTT connection.
     Args:
     project_id: The cloud project ID this device belongs to
     private_key_file: A path to a file containing either an RSA256 or
             ES256 private key.
     algorithm: The encryption algorithm to use. Either 'RS256' or 'ES256'
     Returns:
         A JWT generated from the given project_id and private key, which
         expires in 20 minutes. After 20 minutes, your client will be
         disconnected, and a new JWT will have to be generated.
     Raises:
         ValueError: If the private_key_file does not contain a known key.
     """

     token = {
         # The time that the token was issued at
         "iat": datetime.datetime.now(tz=datetime.timezone.utc),
         # The time the token expires.
         "exp": datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=20),
         # The audience field should always be set to the GCP project id.
         "aud": project_id,
     }

     # Read the private key file.
     with open(private_key_file, "r") as f:
         private_key = f.read()

     print(
         "Creating JWT using {} from private key file {}".format(
             algorithm, private_key_file
         )
     )

     return jwt.encode(token, private_key, algorithm=algorithm)

これで準備は完了です。

💡
パスワードの作成はちょっと手間ですね

接続

以下の情報をMQTTクライアントに指定して接続します。

設定項目 内容
プロトコル mqtts
ホスト名 mqtt.googleapis.com
ポート番号 8883
クライアントID projects/{GCPプロジェクトID}/locations/{リージョン}/registries/{レジストリ名}/devices/{デバイス名}
ユーザー名 unused
パスワード 上記手順内で生成したもの
ルートCA https://pki.goog/roots.pem をダウンロードしたファイル
証明書 AWS Iot Coreで生成したファイル
プライベートキー AWS Iot Coreで生成したファイル
💡
AWSで生成した証明書を使用します

Pub/Subしてみる

AWSと違い、PublishできるトピックとSubscribeできるトピックが限られているようです。

Publish

  • テレメトリー イベントをパブリッシュする
/devices/{デバイス名}/events

デバイスの状態を設定する

/devices/{デバイス名}/state

Subscribe

  • コマンドを受信する
devices/{デバイス名}/commands
💡
うまくいきました

接続自体は簡単にできました。AWSのIoT Coreと同じようなサービスと思っていましたが、証明書の発行機能がなかったり、トピックに制限があったりかなり異なる印象でした。Cloud Pub/Subで受けたあとのことはまだ理解できていないので、今後取り組んでいこうと思います。また、Azureも挑戦しようと思います。