AWS IoT Core のポリシーリソースで指定できる client とは何か調べてみた

AWS
AWS
この記事は約6分で読めます。
結論

ユーザー側で指定するクライアント ID のことです。

調査経緯と結果

AWS IoT Core のアクションリソースが記載されているドキュメントでは、iot:Connect アクションをポリシーで定義する際、リソース情報に client を記載することになっています。

Resource で指定する ARN の例
arn:aws:iot:us-east-1:123456789012:client/myClientId

この client が何を指しているのか分からなかったので、調べてみました。

AWS IoT Core で client というリソースを作成したり、「モノ」を作成すると自動的に client が「モノ」に付与されたりすることはありません。

この client は、IoT Core への接続時にユーザー側で指定するクライアント ID のことを指します。
そのため、ポリシーで Resource の欄には、ユーザーが IoT Core への接続時に指定する予定のクライアント ID を指定する必要があります。
なお、AWS としては、クライアント ID = 「モノ」の名前 であることを推奨しています。
クライアント ID = 「モノ」の名前 で利用されることを想定しているため、このお作法は守った方がよいでしょう。

一般的なデバイスのユースケースでは、デフォルトの MQTT クライアント ID としてモノの名前が使用されます。MQTT クライアント ID、証明書、またはシャドウ状態をモノのレジストリ名として使用するというマッピングは強制されませんが、レジストリと Device Shadow サービスの両方で、モノの名前を MQTT クライアント ID として使用することをお勧めします。こうすることで、デバイスの証明書モデルや Shadows の柔軟性を失うことなく、IoT 群の秩序や利便性を維持することができます。

https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-thing-management.html

検証してみた

以下ドキュメントの手順に登場するサンプルアプリを利用して、iot:Connect アクション実行時の挙動を確認します。

Raspberry Pi または他のデバイスを接続する - AWS IoT Core
このセクションでは、AWS IoT で使用する Raspberry Pi を設定します。接続したい別のデバイスがある場合、Raspberry Pi の手順には、これらの指示をデバイスに合わせて適用するのに役立つ参照先が含まれています。

Resource が * の場合

Resource が * のポリシーを証明書にアタッチした状態で、接続が成功するか確認します。

python3 pubsub.py --topic topic_1 --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/certificate.pem.crt --key ~/certs/private.pem.key --endpoint xxx
Connecting to xxx.iot.ap-northeast-1.amazonaws.com with client ID 'test-336ffd69-33b5-424f-b477-6726fa34e391'...
Connected!

無事接続に成功しました。
上記では、上掲のドキュメントに記載されているコマンドを実行しており、実際にはこの後も処理が続いていますが、今回は iot:Connect アクションの実行結果のみ分かればよいので省略しています。

出力されている内容から、クライアント ID が test-336ffd69-33b5-424f-b477-6726fa34e391 だと分かります。
なお、この出力内容はソースコード内で出力されるように設定しているものなので、IoT Core への接続時に自動的に出力される仕様ではありません。
また、クライアント ID は、接続ごとに test-${ランダム文字列} となります。

Resource が ~client/hoge の場合

hoge というクライアント ID は接続時に指定されないため、接続できない結果となるはずです。

python3 pubsub.py --topic topic_1 --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/certificate.pem.crt --key ~/certs/private.pem.key --endpoint xxx
Connecting to xxx.iot.ap-northeast-1.amazonaws.com with client ID 'test-0620afac-8f60-467d-bc3e-b8b554866397'...
Traceback (most recent call last):
  File "/home/xxx/aws-iot-device-sdk-python-v2/samples/pubsub.py", line 78, in <module>
    connect_future.result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 440, in result
    return self.__get_result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 389, in __get_result
    raise self._exception
awscrt.exceptions.AwsCrtError: AWS_ERROR_MQTT_UNEXPECTED_HANGUP: The connection was closed unexpectedly.

期待通り、接続できませんでした。
ユーザー側で指定したクライアント ID が hoge と一致しなかったからです。

Resource が ~client/test-* の場合

接続時のクライアント ID は test-${ランダム文字列} となるので、接続成功が期待されます。

python3 pubsub.py --topic topic_1 --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/certificate.pem.crt --key ~/certs/private.pem.key --endpoint xxx
Connecting to xxx.iot.ap-northeast-1.amazonaws.com with client ID 'test-13ea418b-4cc7-4497-8010-bcad8c1d3c2a'...
Connected!

期待通り、接続に成功しました。

まとめ

AWS IoT Core のポリシーのアクション iot:Connect で、Resource に指定する client リソースは、AWS 側で設定されるものではなく、IoT Core への接続時にユーザー側で指定するクライアント ID のことを指します。

タイトルとURLをコピーしました