Howto

EdgeLock SE050 を使用して AWS IoT Core へ接続する〜AWS IoT Device SDK v2 編〜(Armadillo-IoT G4)

Howto で出来ること

AWS IoT Device SDK v2 を利用して、NXP Semiconductors 製 EdgeLock SE050 (以下「EdgeLock SE050」) にプリインストールされた X.509 証明書を用いたデバイス認証によって単一のデバイスを AWS IoT Core に接続する。

Howto の概要

  • Armadillo-IoT ゲートウェイ G4 向けの Howto
  • AWS CLI を利用して AWS IoT Core にデバイスをプロビジョニングします
  • EdgeLock SE050 を利用して AWS IoT Core の接続認証を行います
    • SDK は aws-iot-device-sdk-python-v2 を利用します
    • pkcs#11 モジュールを利用して Edgelock SE050 にアクセスします
    • Alpine Linux コンテナ上に接続環境を構築します
    • message の送信については aws-iot-device-sdk-python-v2 にある samples/pubsub.py を参考にしてください

EdgeLock SE050

EdgeLock SE050 は IoT アプリケーション向けのセキュアエレメントです。様々なアルゴリズムに対応した暗号エンジン、セキュアストレージを搭載します。内部処理は秘密鍵を露出させることなくセキュアに暗号処理を行うことができます。外部インターフェースは I2C を採用します。また、EdgeLock SE050 はターンキーソリューションとして利用を開始してすぐにクラウドサービスなど PKI を基にしたサービスに接続することができます。チップ固有の X.509証明書などが事前にプロビジョニングされた状態で出荷されます。

AWS IoT Core

AWS IoT Core は IoT に特化した AWS のクラウドサービスです。 メッセージを各種 AWS サービスにルーティングするゲートウェイの役割はもちろん、接続時の相互認証やデバイス管理の役割を持ちます。AWS IoT Core は幅広い顧客の要件に応えることができることも大きな特徴です。通信プロトコルとして MQTT、HTTPS、MQTT over WSS、LoRaWAN などに対応し、デバイスの認証として X.509 証明書、AWS 認証情報、Amazon Cognito やカスタム認証トークンといった様々なデバイス認証情報を利用することができます。また、クラウドサービスサイドのプロビジョニング方法として X.509証明書や IAM ユーザー、クレーム証明書を選択することが可能です。AWS IoT Core に接続するアプリケーションを開発するためには AWS IoT Device SDK が AWS によって OSS として用意されています。C、C++、python、JAVA、JavaScript といった言語でデバイスアプリケーションを開発することができます。

セットアップ作業の流れと実運用について

以下に接続までの流れを示します。これらの作業はセットアップ時に一度だけ行います。セットアップが完了した後には Armadillo IoT ゲートウェイ G4 を AWS IoT Core に接続する IoT デバイスとして利用することができます。

  • 1.(AWS アカウント、IAM ユーザーを作る)
  • 2.EdgeLock SE050 から証明書を抜き出す
  • 3.AWS の Root CA 証明書を取得する
  • 4.AWS IoT Core にプロビジョニングする
    • AWS IoT Thing をつくる
    • AWS IoT Policy をつくる
    • 証明書を登録する
    • 証明書に AWS IoT Thing と AWS IoT Policy をアタッチする
  • 5.AWS IoT Core に接続するために必要な情報
  • 6.デバイスアプリケーションを実行する

実運用について

Edgelock SE050 には NXP Semiconductors によって署名された X.509 証明書とその対となる鍵がチップ製造時に書き込まれています。 これらの X.509 証明書と鍵は固有であるためデバイス認証に適しています。秘密鍵は Edgelock SE050 内部から抜き出すことはできないので漏洩のリスクはありません。 加えて、書き込み済みの状態でチップが納品されるので、製造時の鍵や X.509 証明書の生成、書き込み工程を省略できます。

Edgelock SE050 に書き込まれた X.509 証明書と鍵のリストについては以下を参照してください。
Armadillo に搭載される Edgelock SE050 は SE050C1 で Variant Cになります。
SE050 configurations

ここでは AWS IoT Core 接続におけるクライアント認証のために、Edgelock SE050 から抜き出した X.509 証明書 をどのように運用するのか考えていきます。

まず、大きく分けて 2つの工程を行う必要があります。

  • Edgelock SE050 から証明書を抜き出す
  • AWS IoT Core で証明書などのプロビジョニングを行う

Edgelock SE050 に書かれる X.509 証明書はデバイス固有です。 同じものがないためにそれぞれのデバイスから証明書を抜き出して、AWS IoT Core に登録する必要があります。 製品の組み立てなどの製造工程があるのであれば、製造担当者が製造工程の中で証明書を抜き出しておくことが考えられます。 詳しくは後述しますが、抜き出し処理はデバイス毎にコマンドを実行して、証明書をファイルにします。 証明書の取得自体には特別な権限は必要ないですが、すり替えには注意が必要です。 抜き出した証明書を後段の SE などの担当者に渡して、デバイスそれぞれについて証明書などのプロビジョニングを行ってもらうことが考えられます。 単体については後述しますが、台数が多い場合は AWS CLI などを利用したスクリプトを利用してまとめて作業することも可能です。 AWS CLI を利用する場合に、プロビジョニング環境は AWS へネットワーク接続が可能であればどんなデバイスでもかまいません。PC や Armadillo (本howto では Armadillo を利用) を利用できます。

アカウント情報の管理について
プロビジョニングを行う際には、IAM ユーザーの情報が必要になります。
情報が漏洩すると攻撃者によるプロビジョニングが可能になり、クラウドへの攻撃につながる可能性があります。
そのためアカウント情報の管理がとても重要になってきます。不要な環境からは情報を削除することをお勧めします。
プロビジョニング方法について
プロビジョニングを行う方法は運用のユースケースにあわせていくつか用意されています。
詳しくは以下を参照してください。
AWS IoT Coreデベロッパーガイド

AWS アカウント、IAMユーザーを作成する

すでにアカウントと IAM ユーザーをお持ちの方はここはスキップしてください。

AWS アカウントの作成方法については、 こちら を参照してください。

利用可能なIAMユーザーがない場合は、IAMユーザーを作成してください。 IAMユーザーの作成方法については、 こちら を参照してください。

AWSIoTConfigAccess の権限について
AWS CLI を利用して IoT Core へ デバイスをプロビジョニングするために
プロビジョニングを担当する IAM ユーザーは AWSIoTConfigAccess の権限が必要です。

権限を確認するには、AWS マネジメントコンソールから Identity and Access Management (IAM) へ行き、
ナビゲーションペインで [ユーザー] を選択します。コンソールには、AWS アカウント内のユーザーが表示されます。
目的のアカウントのアカウント権限を確認してください。
AWSIoTConfigAccess 権限がなければ、同じ画面から[アクセス権限の追加] を行ってください。

EdgeLock SE050 から証明書を抜き出す

以下を参考にセットアップ作業を行う前に EdgeLock SE050 の Deep Power-down を解除して、ミドルウェアのインストールと証明書の取得作業をしてください。 本 howto では、Cloud connection key 0, RSA2048, Die Individual を利用します。証明書は 0xF0000111 になります。

Armadillo-IoT G4 向け

plug-and-trust パッケージの更新について
EdgeLock SE050 向けの Plug&Trust MW のビルド済みパッケージである plug-and-trust パッケージは
Edgelock SE050 内のリソースにアクセスするための openssl engine や pkcs#11 モジュールなどを含みます。
本 howto で利用する pkcs#11 モジュールは 2022 年 9 月初めのリリースから対応しました
(対応開始バージョン alpine: 4.2.0-r2, debian: 4.2.0-2)。
それ以前にパッケージをインストールされた方は、環境が構築されたコンテナ上でパッケージのアップデートをお願いします。

コンテナを立ち上げる

証明書を取得したコンテナ上で作業を続けます。

AWS の Root CA 証明書を準備する

サーバー認証するために AWS の Root CA 証明書が必要です。Amazon Root CA 1の証明書をダウンロードしてください。

AWS CLI のインストール

Edgelock SE050 から証明書とリファレンスキーを取得した環境

[container ~]# apk add --no-cache python3 py3-pip
[container ~]# pip3 install --upgrade pip
[container ~]# pip3 install --no-cache-dir awscli

設定

[container ~]# aws configure

以下は設定例です。書き換えて適切な値を入力してください。AWS Access Key ID と AWS Secret Access Key については、IAM ユーザー作成時に表示/csv取得されてそれ以降は取得することができません。作成時の情報を参照してください。

これ以降、セキュリティ上の配慮から 情報の一部を"*"で隠しています。ご容赦ください。

  • AWS Access Key ID [****************X*4H]:
  • AWS Secret Access Key [****************1*gz]:
  • Default region name []: ap-northeast-1
  • Default output format []: json

AWS IoT Thing をつくる

AWS IoT Thing は、モノと呼ばれ、特定のデバイスまたは論理エンティティ (センサーなど) を表します。 Armadillo を利用して構築された IoT 機器をモノとして扱うことができます。

まず 素の thing を作り、この後で構築していきます。 以下の txt ファイルは、確認のための stdout と、後ほど参照するためのファイルへの出力です。 リダイレクトやパイプの方法はお任せします。

--thing-name は このデバイスの名称です。任意の名称をつけてください。

[container ~]# aws iot create-thing --thing-name dev1 | tee thing_dev1.txt

出力結果

{
    "thingName": "dev1",
    "thingArn": "arn:aws:iot:ap-northeast-1:9**********3:thing/dev1",
    "thingId": "6*****fd-aa53-*8*1-a*8b-a*******90*4"
}
AWS IoT Thing について
AWS IoT Thing についての詳しい情報は以下を参照してください。
AWS IoT Coreデベロッパーガイド

AWS IoT Policy を作る

AWS IoT Policy は IAM ポリシーと同様のルールで JSON 形式で記述します。 AWS IoT Thing からのメッセージブローカー、MQTT通信の送受信、シャドウへのアクセスといった AWS IoT Core へのアクセス権を設定することができます。

ポリシーを記載したファイルを作ります。ここでは、例として全アクセスを許すポリシーを作ります。 実運用の際には最小権限の原則に則したポリシーを検討することをおすすめします。

[container ~]# cat << EOF > my_aws_iot_policy_rule.txt
{
  "Version": "2012-10-17",
  "Statement": [
    {
       "Effect": "Allow",
       "Action": "iot:*",
       "Resource": "*" 
    }
  ]
}
EOF

上記で作ったポリシーを登録します。

--policy-name のパラメータは このポリシーの名称です。任意の名称をつけてください。 --policy-document のパラメータは 上記で作ったファイルです。

[container ~]# aws iot create-policy --policy-name iot_policy \
--policy-document file://my_aws_iot_policy_rule.txt | tee aws_iot_policy.txt

出力結果

{
    "policyName": "iot_policy",
    "policyArn": "arn:aws:iot:ap-northeast-1:9********3:policy/iot_policy",
    "policyDocument": "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n       \"Effect\": \"Allow\",\n       \"Action\": \"iot:*\",\n       \"Resource\": \"*\" \n    }\n  ]\,
    "policyVersionId": "1"
}
AWS IoT Policy について
AWS IoT Policy についての詳しい情報は以下を参照してください。
AWS IoT Coreデベロッパーガイド

証明書の登録

AWS IoT Thing と AWS IoT Core は接続する際に相互認証を行っています。 クライアントである AWS IoT Thing には、クライアント認証の方法がいくつかサポートされています。 ここでは NXP Semiconductors によって署名され Edgelock SE050 のチップ製造時に 書き込まれた X.509 証明書を利用したクライアント認証を採用します。 サーバー認証については AWS より Root CA の証明書が配布されているのでそちらを利用します。

--certificate-pem のパラメータは Edgelock SE050 から取得した証明書です。 --status で証明書を登録と同時に有効にしています。もし不都合がある場合は INACTIVE と指定することで無効の状態で証明書を登録できます。

[container ~]# aws iot register-certificate-without-ca \
--certificate-pem file://device_cert.pem \
--status ACTIVE | tee aws_iot_cert.txt

出力結果

{
    "certificateArn": "arn:aws:iot:ap-northeast-1:9**********3:cert/9e4********************80db********************e9e8********7ef1c",
    "certificateId": "9e4********************80db********************e9e8********7ef1c"
}

証明書に AWS IoT Policy を紐づける

証明書にポリシーを紐づけることで、証明書を利用するデバイスの AWS IoT Core へのアクセス権を指定することができます。 以下は例なので、書き換えて適切な値を入力してください。

--policy-name は 上記で作成したポリシーの名称です。 --target の引数とするのは証明書の登録時に戻ってきた certificateArn です。

[container ~]# aws iot attach-policy \
--policy-name iot_policy \
--target "arn:aws:iot:ap-northeast-1:9**********3:cert/\
9e4********************80db********************e9e8********7ef1c"

AWS IoT Thing に証明書を紐づける

プロビジョニングの最後に AWS IoT Thing に証明書を紐づけます。 以下は例なので、書き換えて適切な値を入力してください。

--thing-name の引数は AWS IoT Thing 登録時に設定したデバイスの名称です。 --principal の引数は証明書の登録時に戻ってきた certificateArn です。

[container ~]# aws iot attach-thing-principal \
--thing-name dev1 \
--principal "arn:aws:iot:ap-northeast-1:9**********3:cert/\
9e4********************80db********************e9e8********7ef1c"

AWS IoT エンドポイント情報 の取得

デバイスからの AWS IoT Core への接続先である デバイス用 AWS IoT エンドポイント情報を取得します。 本 howto では、「AWS IoT Core - データプレーンオペレーション」をエンドポイントとします。 これは、メッセージブローカー、Device Shadow、およびAWS IoTのルールエンジンのコンポーネント間のデータを送受信するためのものです。 ATS 署名が付与されています。

AWS IoT エンドポイント情報 は以下のように取得します。

[container ~]# aws iot describe-endpoint --endpoint-type iot:Data-ATS

出力結果

{
    "endpointAddress": "*********bm**p-ats.iot.ap-northeast-1.amazonaws.com"
}

AWS IoT Core に接続するために必要な情報

以下は AWS IoT Core に接続するために、これまでの作業で入手した情報の一覧です。 今後はこの情報を基にAWS IoT Core に接続するアプリケーションを設定して接続してください。

  • EdgeLock SE050 から取得した証明書
  • AWS IoT エンドポイント

以上で、プロビジョニング作業は終了です。

これ以降は AWS IoT Core へ接続するアプリケーションを動作させる方法について説明します。

デバイスアプリケーションを実行する

ここからは aws-iot-device-sdk-python-v2 を使って接続確認をしていきます。 aws-iot-device-sdk-python-v2 は AWS IoT Core に接続するための python 環境です。 ここでは接続確認のために SDK 内に含まれるサンプルアプリ pkcs11_connect.py を利用します。

EdgeLock SE050 Plug&Trust MW のビルド済みパッケージをインストールした Alpine Linux コンテナ上に構築していきます。

準備

SDK 関連ライブラリのビルドのために make など、SDK のインストールのために setuptools、Github からソースファイルを取得するために git をインストールします。

[container ~]# apk add make gcc g++ musl-dev file linux-headers openssl-dev cmake python3-dev \
git py3-setuptools

aws-iot-device-sdk-python のインストール

GitHub からリポジトリをクローンします。

[container ~]# git clone https://github.com/aws/aws-iot-device-sdk-python-v2.git

aws-iot-device-sdk-python-v2 をインストールします。

[container ~]# cd aws-iot-device-sdk-python-v2
[container ~/aws-iot-device-sdk-python-v2]# python3 setup.py install

デバイスアプリケーションの実行

以下のコマンドを実行してください。 本 howto では、Cloud connection key 0, RSA2048, Die Individual を利用しました。 証明書は 0xF0000111、鍵は 0xF0000110 になります。

[container ~/aws-iot-device-sdk-python-v2]# python3 samples/pkcs11_connect.py \
--endpoint "*********bm**p-ats.iot.ap-northeast-1.amazonaws.com" \
--ca_file AmazonRootCA1.pem \
--cert device_cert.pem \
--pkcs11_lib "/usr/lib/plug-and-trust/libsss_pkcs11.so" \
--key_label "sss:100100F0" \
--pin "" \
--verbosity "Info"
引数 内容
--endpoint 取得したAWS IoT エンドポイント を入力してください。
--ca_file ダウンロードした Amazon Root CA 1 の証明書ファイルのパスを入力してください。
--cert EdgeLock SE050 から取得した証明書のパスを入力してください。
--pkck11_lib pkcs11 ライブラリのパスを入力します。そのまま入力してください。
--key_label 利用する証明書と対になる鍵の ID を指定します。"sss:" を接頭辞に 4 バイトのリトルエンディアンで入力します。この場合は鍵は F0000110 です。
--pin パスワードはありません。空で入力してください。

以下は出力結果の例です。一部エラーが表示されますが実際に問題が発生したわけではないので無視しても問題ありません。

: (省略)
Connecting to *********bm**p-ats.iot.ap-northeast-1.amazonaws.com with client ID 'test-4**f4****2**1-4**5-b**d-67**********'...
[INFO] [2022-10-31T05:46:07Z] [0000ffff84687c48] [mqtt-client] - id=0xffff82cd6660: using ping timeout of 3000000000 ns
[ERROR] [2022-10-31T05:46:07Z] [0000ffff82ca7a70] [socket] - id=0xffff832914d0 fd=12: connect failed with error code 101.
[INFO] [2022-10-31T05:46:07Z] [0000ffff82ca7a70] [dns] - id=0xffff83ac86f0: recording failure for record 2400:6700:ff00::365f:36e9 for *********bm**p-ats.iot.ap-northeast-1.amazonaws.com,t
[ERROR] [2022-10-31T05:46:07Z] [0000ffff82ca7a70] [channel-bootstrap] - id=0xffff83ab1db0: failed to create socket with error 1049
[INFO] [2022-10-31T05:46:07Z] [0000ffff82ca7a70] [socket] - id=0xffff8329ee50 fd=12: connection success
Connected!
Disconnecting...
[INFO] [2022-10-31T05:46:08Z] [0000ffff82ca7a70] [mqtt-client] - id=0xffff82cd6660: sending disconnect message as part of graceful shutdown.
Disconnected!
[ERROR] [2022-10-31T05:46:08Z] [0000ffff84687c48] [mqtt-client] - id=0xffff82cd6660: Connection is not open, and may not be closed
--------------
ERROR ログが表示される件について
Connect failed, create socket failed.

コンテナを保存する

開発の区切りのいいところで作業したコンテナの保存をお勧めします。 「Armadillo-IoT ゲートウェイ G4 製品マニュアル」の howto を参考に保存してください。

Armadillo-IoT ゲートウェイ G4 製品マニュアル