Amazon Web Services ブログ

フリートプロビジョニングを用いて、IoTデバイスとAWS IoT Coreの初期セットアップを自動化する方法

お客様は AWS IoT を使用してIoTデバイスによって生成されたデータを分析し、ビジネスに関する有意義な洞察をすばやく得ることができます。これにより、製造プロセスに必要な改善点の特定、デバイス障害の予測、デバイス問題の迅速な診断とトラブルシューティングなど、さまざまな問題を解決するのに役立ちます。ただし、 IoT デバイスがクラウドに接続して有用な作業を行う前に、デバイスをプロビジョニングする必要があります。 IoT デバイスのプロビジョニングとは、 AWS IoT およびその他のクラウドベースのアプリケーションをセキュアに接続するために、デバイスのユニークな ID ( X.509 証明書や秘密鍵など)を作成し、これらの ID を AWS IoT エンドポイントに登録し、必要なアクセス許可( IoT ポリシーなど)を関連付けるプロセスを指します。

今日、多くのお客様は、Just-In-Time-Registration( JITR )Just-In-Time-Provisioning( JITP )などの AWS IoT Core 機能を使用して、デバイスアイデンティティをAWSクラウドに登録し、必要な権限を関連付けるプロセスを自動化し、かつスケーリングしています。ただし、一意の ID を安全に生成してデバイスに書き込むことは、依然としてお客様の責任です。多くの方にとって、特に多数のデバイスを製造している OEM ベンダーにとって、このプロセスは依然として手作業で時間のかかる作業です。

新たに追加された AWS IoT Core のフリートプロビジョニングの機能を使用すると、エンドツーエンドのデバイスオンボードのプロセスを安全に自動化できます。さらに、キー属性をデバイスから送信し、 AWS Lambda 関数で検証して整合性を高めることができます。 フリートプロビジョニングは、一意のデジタル ID を各デバイスに安全に配信し、 Lambda 関数を介してデバイスのペイロードを検証し、 ID を顧客の AWS アカウントに登録し、必要なすべてのアクセス許可とレジストリメタデータ(モノ、モノのグループなど)をデバイスに設定します。これはすべて、デバイスが AWS IoT Core に最初に接続したとき、またはデバイスが新しい認証情報または更新の必要があるときに自動的に行われるため、エンジニアの貴重な時間とリソースの節約にも繋がります。

フリートプロビジョニングでは、大きく分けて2つのプロビジョニング方法があります。

  1. クレームによるプロビジョニング – ブートストラップ証明書を用いたアプローチと呼ばれることがあります。
  2. 信頼できるユーザー(モバイル/ Web アプリユーザーなど)によるプロビジョニング – このプロセスは、クレームによるプロビジョニングとよく似ています。

このブログでは、クレームによるプロビジョニングの方法を詳しく示し、このアプローチを使用する必要がある場合について説明します。この投稿の最後で、信頼できるユーザーによるプロビジョニングのアプローチを使用する場合の違いについて説明します。それでは、始めましょう。

クレームによるプロビジョニングを使用する場合の流れ

クレームによるプロビジョニングは、全デバイスが共有ブートストラップ証明書を使用して製造されるシナリオを想定して設計されています。これらのブートストラップ証明書には、デバイスに次のことのみを許可します。

  1. AWS IoT Core との最初の接続を確立する
  2. アイデンティティの証明をする
  3. デバイスが以降の通信で使用する、必要な権限が付与された ID をリクエストする

この全デバイス共通のブートストラップ証明書は、工場などで初期ソフトウェアをデバイスに書き込むときにデバイスに配置されます。デバイスにすでに独自の秘密鍵が搭載されている場合、 AWS IoT Core によって署名されるブートストラップ証明書とともに証明書署名リクエスト( CSR )を送信できます。

フリートプロビジョニングは、デバイスによって提示されたブートストラップ証明書の検証に加えて、関連するデバイスの属性が適切であるかを検証するための、 Lambda ベースのプロビジョニングフックも提供します。デバイス属性の例には、シリアル番号、 MAC ID 、デバイスの場所などが含まれます。このプロセス中に送信されたカスタム属性に基づいて特定のデバイスのプロビジョニングステータスの承認または拒否を自動化するには、プロビジョニングトランザクションで Lambda 関数の利用を検討してください。

クレームによるプロビジョニングの概要(ブートストラップ証明書利用時)

image

上図では、クレームによるプロビジョニングのワークフローが示されています。デバイスの電源がオンになっていて、ネットワークにアクセスできる場合、次のことが行われます。

  1. デバイスは、ブートストラップされた証明書を使用して、安全な TLS 1.2 接続を介して AWS IoT Core に接続します。デバイスに CSR がある場合、それはブートストラップ証明書とともに提示されます。
  2. 証明書には非常に制限の厳しいポリシーが関連付けられており、フリートプロビジョニングプロセスに関連付けられた IoT トピックへのアクセスのみを提供します。
  3. Fleet Provisioning サービスは、トランザクションを安全に分離するための「所有権の証明」をするトークンと、正規の証明書/秘密鍵ペイロードを返します。このトークンは、後続の呼び出しで証明書をアクティブにするために使用されます。 CSR が提示された場合、証明書はその CSR から生成されます。
  4. デバイスは AWS IoT Core に MQTT リクエストを送信し、所有権トークン、アカウント所有者によって作成されたフリートプロビジョニングテンプレートの名前、および(オプションで)プロビジョニング検証用のデバイス属性を提示します。 Lambda ベースのプロビジョニングフックを利用して、事前に承認されたリストに対するデバイスのシリアル番号や MAC ID の検証など、追加の検証を有効にすることをお勧めします。
  5. フリートプロビジョニングテンプレートが実行され、プロビジョニングトランザクションが実行され、結果が返されます。一般的には、 Lambda でのデバイス属性を検証、証明書のアクティブ化、プロダクションポリシーのアタッチ、モノ/グループの作成などをします(オプション)。
  6. プロビジョニングトランザクションの結果に基づいて、新しい証明書のステータスが返されます。成功した場合、ブートストラップ証明書は「本番」証明書に対して非推奨/ローテーションされます。トランザクションが拒否された場合、「アクセス拒否」エラーがデバイスに返されます。

クレームによるプロビジョニングの設定の流れ

次のセクションでは、前のセクションで説明したクレームによるプロビジョニングのワークフローを設定するために必要な手順について説明します。手順は AWS マネジメントコンソールで行われます。 3 つのステップで構成されます。

  • ステップ 1:プロビジョニングテンプレートを作成する
  • ステップ 2:プロビジョニングクレーム(別名ブートストラップ証明書)を定義する
  • ステップ 3:デバイス側のクライアントソフトウェアを設定する
    このワークフローが設定されると、デバイスの電源がオンになり、ネットワークアクセスが提供されるたびに、デバイスのオンボーディングが自動的に行われます。

ステップ 1 – プロビジョニングテンプレートを作成する

プロビジョニングテンプレートは、デバイスをプロビジョニングするときに実行する必要がある指示の詳細を示します。プロビジョニングテンプレートには、特定の証明書に関連付けるポリシー、デバイスレジストリのモノの名前、関連付けられた証明書をアクティブにするかどうかなどを含めることができます。詳細については、フリートプロビジョニングテンプレートのドキュメントをご覧ください。

プロビジョニングテンプレートの作成

  • AWS マネジメントコンソールを開く
  • ナビゲーションペインの AWS IoT Core で、オンボード を選択し、フリートのプロビジョニングテンプレートを選択します。
    • 注:初回アクセス時には、イントロダクションが表示されるかもしれません。その場合は、多数のデバイスをオンボード/テンプレートを作成 を選択します。
  • 開始方法 を選択します。

  • テンプレートの名前を入力します(テンプレート名はデバイス側から呼び出すときに参照されます)。
  • プロビジョニングロールを選択/作成します。
    • 注:このロールは、 AWS IoT Core に代わって AWS IoT アカウントでリソースを作成/更新する権限を付与します。
  • [推奨] Lambda 関数を選択して、プロビジョニングトランザクションにフックします。
    • 概要で述べたように、デバイスからのパラメーターペイロードを処理する Lambda 関数を定義できます。 そのペイロードを取得して、ブラック/ホワイトリストや内部の登録データベース、その他の内部リソースを使用して分析を行い、プロビジョニング要求を承認または拒否できます。
    • デバイスから送信された “provisioning-templates” に関する属性は、 Lambda のイベントの [“parameters”] タグから取得できます。
    • Lambda は、プロビジョニング処理を行うためには、少なくともブール値の “allowProvisioning” ( True / False )を返す必要があります。

以下は、基本的なプロビジョニングフック Lambda 関数の例です。

import json

provision_response = {'allowProvisioning': False}

def isBlacklisted(serial_number):
    #check serial against database of blacklisted serials
    ...
    
def lambda_handler(event, context):
    
    # DISPLAY ALL ATTRIBUTES SENT FROM DEVICE
    print("Received event: " + json.dumps(event, indent=2))
    
    # Assume Device has sent a device_serial attribute
    device_serial = event["parameters"]["device_serial"]
    
    # Check serial against an isBlacklisted() function
    if not isBlacklisted(device_serial):
        provision_response["allowProvisioning"] = True
        
    return provision_response

オプション設定をおこない、テンプレート作成を完了させます。

  • プロビジョニングされたデバイスをAWS IoTレジストリに配置したり、追加のキー/値属性に含めたりする場合は、チェックボックスをオンにします。
  • 次へを選択します。

次に、完全にプロビジョニングされたデバイスに関連付けられるポリシーを選択します。 ポリシーは、接続や特定のトピックのサブスクライブ、受信など、デバイスが AWS IoT Core エンドポイントとのやりとりで必要となるアクセスを管理します。 ポリシーの作成方法の詳細については、 AWS IoT ポリシーのドキュメントをご覧ください。

AWS IoT ポリシーを定義する

  • デバイスが完全にプロビジョニングされる資格を得た後に、そのデバイスに関連付ける IoT ポリシーを作成または選択します。
    • たとえば、次のポリシーは、モノの名前と一致するクライアントIDを使用して AWS IoT Core に接続し、my/topicトピックのメッセージをサブスクライブして受信するアクセス許可をデバイスに付与します。
{"Version": "2012-10-17",
    "Statement": [
        {"Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": ["arn:aws:iot:REGION:123456789012:client/${iot:Connection.Thing.ThingName}"]
        },
        {"Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:REGION:123456789012:topicfilter/my/topic"
            ]
        },
        {"Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:REGION:123456789012:topic/my/topic"
            ]
        }
    ]
}
  • 次へを選択します。
    これで、テンプレートによってレジストリに作成される「モノ」の追加の管理情報を定義することができます。

AWS IoT レジストリ設定を定義する

  • レジストリで作成されたすべてのものにプレフィックスを設定します。
    • オプションだが推奨:このテンプレートにモノのタイプを適用します。
    • オプション:テンプレートを使用してプロビジョニングされたすべてのものを配置するグループを選択します。
    • オプション:レジストリに含める必要がある属性を追加します。
  • 次へを選択します。

プロビジョニングされたデバイスに構成情報を送信するオプションを選択した場合は、

  • 属性とデフォルト値を追加します(オプション)。
  • テンプレートを作成 を選択します。

ステップ 2 –プロビジョニング要求(別名ブートストラップ証明書)を定義する

このセクションでは、共通のブートストラップ証明書として使用される証明書を指定/作成します。

  • プロビジョニングクレームを定義するには
    • AWS IoT Core によって以前に作成された証明書を選択するか、独自の認証局( CA )によって署名された証明書を使用します。
      • 証明書をまだ作成していない場合は、Shift キーを押しながら「証明書の生成」をクリックして、次の証明書作成ワークフローを実行します。
      • 作成 を選択してウィザードを開始し、 証明書の作成 を選択して証明書を生成します。
      • 公開鍵と秘密鍵、およびルート CA を含む証明書ペイロードをダウンロードします。
      • 完了 を選択します(ポリシーのアクティブ化やアタッチの必要はありません。
      • 新しく開いたウィンドウを閉じ、ページを更新して利用可能な証明書を一覧表示します。
        目的の証明書を選択したら、 ポリシーのアタッチ を選択して、制限付きポリシーを証明書にアタッチします。前に説明したように、この制限付きポリシーでは、ブートストラップ証明書を持つデバイスのみが AWS IoT Core との最初の接続を確立し、 ID を証明し、必要な IoT アクセス許可で完全に機能する ID をリクエストします。
        テンプレートを有効にする を選択し、 閉じる を選択します。

ステップ 3 –デバイス側のクライアントソフトウェアの構成

最後の手順では、デバイスやクライアント側のソフトウェアを構成する方法について説明します。 ステップ 2ブートストラップ証明書を生成した場合は、証明書、ルートCA証明書、および秘密鍵が AWS IoT Console からダウンロードされ、デバイスの安全な場所に保存されていることを確認します。

ブートストラップ認証情報がボードに安全に保存されていることを確認したら、デバイスは AWS IoT Core への初期接続を行う必要があります。 また、プロビジョニングサービスからの応答を取得するためのコールバックも定義する必要があります。

次の例は、デバイスをAWS IoT Coreに接続する方法を示しています。 他の AWS IoT SDK がサポートされていますが、以下のサンプルは AWS IoT Python SDK のものです。 Python リファレンスクライアントは、aws-iot-fleet-provisioningにあります。

// Don't forget to define a callback method to capture return data.
// Note: In this example, on_message_callback must also be defined
// as a method in the class near the top.
self.primary_MQTTClient.onMessage = self.on_message_callback

def on_message_callback(self, message):
    # inspect message.payload

// Example standard python IoT Core connect configuration.
self.primary_MQTTClient.configureEndpoint(self.iot_endpoint, 8883)
self.primary_MQTTClient.configureCredentials("{}/{}".format(self.secure_cert_path,
       self.root_cert), "{}/{}".format(self.secure_cert_path, self.secure_key),
       "{}/{}".format(self.secure_cert_path, self.claim_cert))
 self.primary_MQTTClient.configureOfflinePublishQueueing(-1)  
 self.primary_MQTTClient.configureDrainingFrequency(2)  
 self.primary_MQTTClient.configureConnectDisconnectTimeout(10)  
 self.primary_MQTTClient.configureMQTTOperationTimeout(3)      
 self.logger.info('##### CONNECTING WITH PROVISIONING CLAIM CERT #####')
        
 self.primary_MQTTClient.connect()

デバイスが AWS IoT Core に正常に接続されたら、認証ペイロードを生成するために、予約済みの AWS IoT プロビジョニングトピックにパブリッシュします。

最初のパブリッシュで証明書のペイロードを取得するためには

# Make a publish call to topic to get official certs
self.primary_MQTTClient.publish("$aws/certificates/create/json", "{}", 0)

応答は、証明書、秘密鍵、および所有権トークンを返し、コールバック関数を呼び出します。 証明書とキーはセキュアに保存される必要があります。 追加の所有権トークンは、次のコード例に示すように、目的のプロビジョニングテンプレートの名前、および(オプションで)必要なデバイスパラメーターと共に、2番目のプロビジョニングトピックにパブリッシュする必要があります。

//Pack up the token, and any relevant device attributes.
register_template = {"certificateOwnershipToken": token,
    "parameters": {"serialNumber": serial, "customAttribute": someAttribute}}

#Publish payload to second provisioning topic and include desired template name.
self.primary_MQTTClient.publish(
     "$aws/provisioning-templates/{TEMPLATE_NAME}/provision/json", json.dumps(register_template), 0)  

IoT Core は、プロビジョニングテンプレートで定義されたアクションの結果に基づいて応答します。

デバイスによっては、安全なハードウェアベースのソリューションを使用してキーペアを生成することが可能です。 この場合、 AWS IoT Core に接続するには、キーペアから証明書を生成する必要があります。 これには、 CSR を生成し、その CSR を AWS IoT Core によって署名されるように送信することで実現できます。 証明書を取得するための AWS IoT Core への最初のパブリッシュは、以下のスニペットに示すように変更されます。

self.primary_MQTTClient.publish("$aws/certificates/create-from-csr/json", 
      "{ "certificateSigningRequest": "CSR_TEXT_HERE"}", 0)

CSR から証明書を作成する方法の詳細については、 AWS IoT API リファレンスドキュメントをご覧ください。

これで、「クレームによるプロビジョニング」ワークフローを設定するために必要な手順は終了です。次に、「信頼できるユーザー」の方法を使用してAWS IoT Core フリートプロビジョニングを設定する場合の違いについて説明します。

「信頼できるユーザー」を介したフリートプロビジョニングの設定

フリート管理のもう一つの追加機能として、「信頼されたユーザー」がデバイスに代わってプロビジョニングできるようにする機能があります。これは、モバイルアプリユーザーを介してデバイスをプロビジョニングするときの一般的な使用例です。例えば、エンドユーザーがデバイス設定用のスマートフォンアプリを用いてWi-Fi経由でデバイスの設定をする場合などです。フローは、ユーザーが信頼できる仲介者(モバイルアプリなど)から AWS IoT Core への最初の呼び出しを実行してブートストラップ証明書を取得することを除いて、ブートストラップ証明書を使用したプロビジョニングと非常に似ています。次に、この証明書はモバイルデバイスに渡され、ブートストラップデバイスのステップ 1 〜 3 と同じフローになります。詳細については、 AWS IoT Fleet Provisioning with a Trusted User のドキュメントをご覧ください。

まとめ

この記事では、消費者向けデバイスから産業用機器まで、大量の製造されたデバイスを AWS IoT Core に簡単に接続できるように設計された、フリートプロビジョニングという新機能についてご紹介しました。クレームによるプロビジョニングの方法でフリートプロビジョニングを使用するために必要な手順を紹介し、また、信頼できるユーザーによるプロビジョニングの方式を使用するために必要な手順を説明しました。現在、 Python のリファレンスクライアントが利用可能となっており、プロビジョニングクレーム(ブートストラップ証明書)を使用する場合のプロビジョニングフロー全体を試す際に使用できます。

フリートプロビジョニングの詳細については、機能のドキュメントまたはFleet Provisioningフォーラムにアクセスしてください。また、GitHubでフリートプロビジョニングのデモも利用可能です。この投稿がAWS IoT Core Fleet Provisioningの使用を簡単に開始するのに役立つことを願っています。

原文はこちら。 翻訳はソリューションアーキテクト 飯田が担当しました。