Azure IoT Edge デバイスを接続して階層を作成する

適用対象:IoT Edge 1.4 チェックマーク IoT Edge 1.4

重要

IoT Edge 1.4 がサポートされているリリースです。 以前のリリースの場合は、「IoT Edge を更新する」を参照してください。

この記事では、IoT Edge ゲートウェイとダウンストリーム IoT Edge デバイス間の信頼関係接続を確立する手順について説明します。 この構成は、入れ子になったエッジとも呼ばれます。

ゲートウェイのシナリオでは、IoT Edge デバイスはゲートウェイとダウンストリーム デバイスの両方になることができます。 複数の IoT Edge ゲートウェイを階層化して、デバイスの階層を作成することができます。 ダウンストリーム (子) デバイスは、そのゲートウェイ (親) デバイスを介してメッセージの認証や送受信を行うことができます。

ゲートウェイ階層内の IoT Edge デバイスには 2 つの異なる構成があり、この記事ではその両方について説明します。 1 つ目は、最上位レイヤーの IoT Edge デバイスです。 複数の IoT Edge デバイスが互いを介して接続している場合、親デバイスがなく、IoT Hub に直接接続するデバイスは、最上位レイヤーにあると見なされます。 このデバイスは、その下にあるすべてのデバイスからの要求処理を担当します。 もう 1 つの構成は、階層の下位レイヤーにあるすべての IoT Edge デバイスに適用されます。 これらのデバイスは、他のダウンストリーム IoT や IoT Edge デバイスのゲートウェイになる場合もありますが、独自の親デバイスを介して通信をルーティングする必要もあります。

一部のネットワーク アーキテクチャでは、クラウドに接続できるのは、階層内の最上位の IoT Edge デバイスのみである必要があります。 この構成では、階層の下位レイヤーにあるすべての IoT Edge デバイスが通信できるのは、そのゲートウェイ (親) デバイスとダウンストリーム (子) デバイスのみになります。

この記事に記載されているすべての手順は、IoT Edge デバイスをダウンストリーム IoT デバイスのゲートウェイとして設定する、「透過的なゲートウェイとして機能するように IoT Edge デバイスを構成する」に基づいています。 同じ基本的手順がすべてのゲートウェイ シナリオに適用されます。

  • 認証: ゲートウェイ階層内のすべてのデバイスの IoT Hub ID を作成します。
  • 承認: IoT Hub で親子関係を設定して、ダウンストリーム デバイスが IoT Hub に接続する場合と同様に親デバイスに接続することを承認します。
  • ゲートウェイの検出: ダウンストリーム デバイスがローカル ネットワーク上の親デバイスを見つけられるようにします。
  • セキュリティで保護された接続: 同じチェーンの一部である信頼できる証明書を使用して、セキュリティで保護された接続を確立します。

前提条件

  • Free または Standard の IoT ハブ。
  • 少なくとも 2 つの IoT Edge デバイス。最上位レイヤーのデバイスが 1 つと、1 つ以上の下位レイヤーのデバイス。 IoT Edge デバイスが使用できない場合は、Ubuntu 仮想マシンで Azure IoT Edge を実行できます。
  • Azure CLI を使用してデバイスを作成および管理する場合は、Azure IoT 拡張機能をインストールします。

ヒント

この記事では、ご自身のシナリオに適したゲートウェイ階層を作成するための詳細な手順とオプションについて説明します。 ガイド付きチュートリアルについては、ゲートウェイを使用した IoT Edge デバイス階層の作成に関する記事を参照してください。

ゲートウェイ階層を作成する

このシナリオでは、IoT Edge デバイスの親子関係を定義することによって、IoT Edge ゲートウェイ階層を作成します。 新しいデバイス ID を作成するときに親デバイスを設定することも、既存のデバイス ID の親と子を管理することもできます。

親子関係を設定する手順では、ダウンストリーム デバイスが IoT Hub に接続する場合と同様に親デバイスに接続することを承認します。

親デバイスになれるのは IoT Edge デバイスのみですが、IoT Edge デバイスと IoT デバイスは両方とも子になることができます。 親は多数の子を持つことができますが、子は 1 つの親しか持つことができません。 ゲートウェイ階層は、あるデバイスの子が別のデバイスの親になるように親子セットを連結することで作成されます。

既定では、親は最大 100 の子を持つことができます。 この制限を変更するには、親デバイスの edgeHub モジュールで Maxconnectedclients 環境変数を設定します。

Azure portal では、新しいデバイス ID を作成するとき、または既存のデバイスを編集することで、親子関係を管理できます。

新しい IoT Edge デバイスを作成するときに、そのハブ内の既存の IoT Edge デバイスの一覧から親と子のデバイスを選択するオプションがあります。

  1. Azure Portal で、IoT ハブに移動します。
  2. [デバイス管理] メニューで、[デバイス] を選択します。
  3. [デバイスの追加] を選択し、[IoT Edge デバイス] のチェック ボックスをオンにします。
  4. デバイス ID と認証の設定を行うとともに、親デバイスを設定したり、子デバイスを選択したりすることができます。
  5. 親または子として使用するデバイスを 1 つまたは複数選択します。

また、既存のデバイスの親子関係を作成または管理することもできます。

  1. Azure Portal で、IoT ハブに移動します。
  2. [デバイス管理] メニューで、[デバイス] を選択します。
  3. 一覧から、管理する IoT Edge デバイスを選択します。
  4. [親デバイスの設定]歯車アイコンまたは [子デバイスの管理] を選択します。
  5. 任意の親または子デバイスを追加または削除します。

Note

プログラムで親子関係を確立する場合は、C#、Java、または Node.js の IoT Hub Service SDK を使用できます。

C# SDK を使用した子デバイスの割り当て例は、こちらです。 タスク RegistryManager_AddAndRemoveDeviceWithScope() は、プログラムで 3 層階層を作成する方法を示しています。 第 1 層にある IoT Edge デバイスは、親として機能します。 第 2 層にある別の IoT Edge デバイスは、子と親の両方として機能します。 最後の第 3 層にある IoT デバイスは、最下層の子デバイスとして機能します。

証明書の生成

一貫した証明書チェーンを同じゲートウェイ階層内のデバイス間でインストールして、それら自体の間にセキュリティで保護された通信を確立する必要があります。 階層内のすべてのデバイスには、IoT Edge デバイスか IoT ダウンストリーム デバイスかにかかわらず、同じルート CA 証明書のコピーが必要です。 階層内の各 IoT Edge デバイスでは、そのルート CA 証明書が、そのデバイス CA 証明書のルートとして使用されます。

このセットアップでは、各ダウンストリーム IoT Edge デバイスは、接続先の edgeHub に、共有ルート CA 証明書によって署名されたサーバー証明書があることを確認することで、親の ID を検証できます。

ゲートウェイおよびダウンストリーム デバイス上のルート CA によって発行された証明書チェーンの図

IoT Edge 証明書の要件については、「Azure IoT Edge での証明書の使用方法について理解する」を参照してください。

  1. 次の証明書を作成または要求します。

    • ルート CA 証明書。これは、指定されたゲートウェイ階層内のすべてのデバイスにとって最上位の共有証明書です。 この証明書はすべてのデバイスにインストールされます。
    • ルート証明書チェーンに含める中間証明書
    • ルートおよび中間証明書によって生成されるデバイス CA 証明書とその秘密キー。 ゲートウェイ階層内の IoT Edge デバイスごとに、一意のデバイス CA 証明書が 1 つ必要です。

    自己署名証明機関を使用するか、Baltimore、Verisign、Digicert、GlobalSign などの信頼できる商用証明機関から購入することができます。

  2. テストに使用する独自の証明書がない場合は、ルート証明書と中間証明書のセットを 1 つ作成し、デバイスごとに IoT Edge デバイス CA 証明書を作成します。 この記事では、サンプルとチュートリアルのためのテスト用 CA 証明書に関する記事を使用して生成されたテスト証明書を使用します。 たとえば、次のコマンドでは、ルート CA 証明書、親デバイス証明書、および子デバイス証明書が作成されます。

    # !!! For test only - do not use in production !!!
    
    # Create the the root CA test certificate
    ./certGen.sh create_root_and_intermediate
    
    # Create the parent (gateway) device test certificate 
    # signed by the shared root CA certificate
    ./certGen.sh create_edge_device_ca_certificate "gateway"
    
    # Create the downstream device test certificate
    # signed by the shared root CA certificate
    ./certGen.sh create_edge_device_ca_certificate "downstream"
    

    警告

    テスト スクリプトによって作成された証明書を運用環境で使用しないでください。 これらにはハード コーディングされたパスワードが含まれており、既定で 30 日後に有効期限が切れます。 テスト CA 証明書は、CA 証明書を理解するのに役立つデモンストレーション用に提供されています。 運用環境での認定の作成と有効期間管理には、セキュリティに関する独自のベスト プラクティスを使用してください。

    テスト証明書の作成の詳細については、「IoT Edge デバイスの機能をテストするためのデモ用の証明書を作成する」を参照してください。

  3. 証明書とキーを各デバイスに転送する必要があります。 USB ドライブを使用したり、Azure Key Vault などのサービスを使用したり、セキュア ファイル コピーなどの機能を使用したりできます。 シナリオに最も適したいずれかの方法を選択してください。 証明書とキーの優先ディレクトリにファイルをコピーします。 証明書には /var/aziot/certs を、キーには /var/aziot/secrets を使用します。

デバイスへの証明書のインストールの詳細については、「IoT Edge デバイスで証明書を管理する」を参照してください。

親デバイスを構成する

親デバイスを構成するには、ローカルまたはリモートのコマンド シェルを開きます。

セキュリティで保護された接続を有効にするには、ゲートウェイ シナリオ内のすべての IoT Edge 親デバイスを、一意のデバイス CA 証明書と、ゲートウェイ階層内のすべてのデバイスで共有されるルート CA 証明書のコピーを使用して構成する必要があります。

  1. 証明書が形式の要件を満たしていることを確認します。

  2. ルート CA 証明書親デバイス CA 証明書、および親秘密キーを親デバイスに転送します。

  3. 証明書とキーを正しいディレクトリにコピーします。 デバイス証明書に推奨されるディレクトリは、証明書には /var/aziot/certs、キーには /var/aziot/secrets です。

    ### Copy device certificate ###
    
    # If the device certificate and keys directories don't exist, create, set ownership, and set permissions
    sudo mkdir -p /var/aziot/certs
    sudo chown aziotcs:aziotcs /var/aziot/certs
    sudo chmod 755 /var/aziot/certs
    
    sudo mkdir -p /var/aziot/secrets
    sudo chown aziotks:aziotks /var/aziot/secrets
    sudo chmod 700 /var/aziot/secrets
    
    # Copy full-chain device certificate and private key into the correct directory
    sudo cp iot-edge-device-ca-gateway-full-chain.cert.pem /var/aziot/certs
    sudo cp iot-edge-device-ca-gateway.key.pem /var/aziot/secrets
    
    ### Root certificate ###
    
    # Copy root certificate into the /certs directory
    sudo cp azure-iot-test-only.root.ca.cert.pem /var/aziot/certs
    
    # Copy root certificate into the CA certificate directory and add .crt extension.
    # The root certificate must be in the CA certificate directory to install it in the certificate store.
    # Use the appropriate copy command for your device OS or if using EFLOW.
    
    # For Ubuntu and Debian, use /usr/local/share/ca-certificates/
    sudo cp azure-iot-test-only.root.ca.cert.pem /usr/local/share/azure-iot-test-only.root.ca.cert.pem.crt
    # For EFLOW, use /etc/pki/ca-trust/source/anchors/
    sudo cp azure-iot-test-only.root.ca.cert.pem /etc/pki/ca-trust/source/anchors/azure-iot-test-only.root.ca.pem.crt
    
  4. 証明書とキーの所有権とアクセス許可を変更します。

    # Give aziotcs ownership to certificates
    # Read and write for aziotcs, read-only for others
    sudo chown -R aziotcs:aziotcs /var/aziot/certs
    sudo find /var/aziot/certs -type f -name "*.*" -exec chmod 644 {} \;
    
    # Give aziotks ownership to private keys
    # Read and write for aziotks, no permission for others
    sudo chown -R aziotks:aziotks /var/aziot/secrets
    sudo find /var/aziot/secrets -type f -name "*.*" -exec chmod 600 {} \;
    
    # Verify permissions of directories and files
    sudo ls -Rla /var/aziot
    

    正しい所有権とアクセス許可が含まれている一覧の出力は、次のようになります。

    azureUser@vm:/var/aziot$ sudo ls -Rla /var/aziot
    /var/aziot:
    total 16
    drwxr-xr-x  4 root    root    4096 Dec 14 00:16 .
    drwxr-xr-x 15 root    root    4096 Dec 14 00:15 ..
    drwxr-xr-x  2 aziotcs aziotcs 4096 Jan 14 00:31 certs
    drwx------  2 aziotks aziotks 4096 Jan 23 17:23 secrets
    
    /var/aziot/certs:
    total 20
    drwxr-xr-x 2 aziotcs aziotcs 4096 Jan 14 00:31 .
    drwxr-xr-x 4 root    root    4096 Dec 14 00:16 ..
    -rw-r--r-- 1 aziotcs aziotcs 1984 Jan 14 00:24 azure-iot-test-only.root.ca.cert.pem
    -rw-r--r-- 1 aziotcs aziotcs 5887 Jan 14 00:27 iot-edge-device-ca-gateway-full-chain.cert.pem
    
    /var/aziot/secrets:
    total 16
    drwx------ 2 aziotks aziotks 4096 Jan 23 17:23 .
    drwxr-xr-x 4 root    root    4096 Dec 14 00:16 ..
    -rw------- 1 aziotks aziotks 3243 Jan 14 00:28 iot-edge-device-ca-gateway.key.pem
    
  5. プラットフォーム固有のコマンドを使用してデバイス上の証明書ストアを更新することで、親 IoT Edge デバイスにルート CA 証明書をインストールします。

    # Update the certificate store
    
    # For Ubuntu or Debian - use update-ca-certificates
    sudo update-ca-certificates
    # For EFLOW or RHEL - use update-ca-trust
    sudo update-ca-trust
    

    update-ca-trust を使用する方法の詳細については、CBL-Mariner の SSL CA 証明書の管理に関するページを参照してください。

このコマンドでは、1 つの証明書が /etc/ssl/certs に追加されたことが報告されます。

Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.

親構成ファイルを更新する

IoT Edge は自分のデバイスに既にインストールされている必要があります。 されていない場合は、手順に従って、1 つの Linux IoT Edge デバイスを手動でプロビジョニングします。

  1. /etc/aziot/config.toml 構成ファイルが親デバイスに存在するかどうかを確認します。

    デバイスに構成ファイルが存在しない場合は、次のコマンドを使用し、テンプレート ファイルに基づいてそれを作成します。

    sudo cp /etc/aziot/config.toml.edge.template /etc/aziot/config.toml
    

    このテンプレート ファイルを、このセクションの構成パラメーターを追加するための参照として使用することもできます。

  2. エディターを使用して IoT Edge 構成ファイルを開きます。 たとえば、nano エディターを使用して /etc/aziot/config.toml ファイルを開きます。

    sudo nano /etc/aziot/config.toml
    
  3. hostname パラメーターを見つけるか、構成ファイルの先頭に追加します。 IoT Edge 親デバイスの完全修飾ドメイン名 (FQDN) または IP アドレスになるように、値を更新します。 次に例を示します。

    hostname = "10.0.0.4"
    

    ゲートウェイの検出を有効にするには、すべての IoT Edge ゲートウェイ (親) デバイスで、その子デバイスがローカル ネットワーク上でそれを見つけるために用いる hostname パラメーターを指定する必要があります。 すべてのダウンストリーム IoT Edge デバイスでは、その親を識別するために parent_hostname パラメーターを指定する必要があります。 1 つの IoT Edge デバイスが親と子デバイスの両方である階層シナリオの場合は、両方のパラメーターが必要です。

    hostname および trust_bundle_cert パラメータは、構成ファイルの先頭に、またどのセクションよりも前にある必要があります。 定義されたセクションの前にパラメーターを追加すると、正しく適用されます。

    64 文字未満のホスト名を使用します。これは、サーバー証明書共通名の文字数制限です。

    ゲートウェイ階層全体のホスト名パターンとの一貫性を確保します。 FQDN または IP アドレスのいずれか (両方ではない) を使用します。 ダウンストリーム デバイスを接続するには FQDN または IP アドレスが必要です。

    edgeHub コンテナーが作成される前にホスト名を設定します。 edgeHub が実行されている場合、構成ファイル内のホスト名を変更しても、コンテナーが再作成されるまで有効になりません。 ホスト名が適用されていることを確認する方法の詳細については、 「親構成を確認する」セクションを参照してください。

  4. 信頼バンドル証明書パラメーターを見つけるか、構成ファイルの先頭に追加します。

    ファイルの URI を使用して、trust_bundle_cert パラメーターをデバイスのルート CA 証明書に更新します。 次に例を示します。

    trust_bundle_cert = "file:///var/aziot/certs/azure-iot-test-only.root.ca.cert.pem"
    
  5. 構成ファイルで、Edge CA 証明書セクションを見つけるか追加します。 証明書 cert と秘密キー pk のパラメーターを、親の IoT Edge デバイス上のフルチェーン証明書とキー ファイルのファイル URI パスで更新します。 IoT Edge では、証明書と秘密キーをテキストベースの PEM (Privacy Enhanced Mail) 形式にする必要があります。 次に例を示します。

    [edge_ca]
    cert = "file:///var/aziot/certs/iot-edge-device-ca-gateway-full-chain.cert.pem"
    pk = "file:///var/aziot/secrets/iot-edge-device-ca-gateway.key.pem"
    
  6. IoT Edge デバイスで、起動時に正しいバージョンの IoT Edge エージェントが使用されることを確認します。 「既定の Edge エージェント」セクションを見つけて、IoT Edge のイメージの値をバージョン 1.4 に設定します。 次に例を示します。

    [agent.config]
    image = "mcr.microsoft.com/azureiotedge-agent:1.4"
    
  7. 親構成ファイルの先頭は、次の例のようになります。

    hostname = "10.0.0.4"
    trust_bundle_cert = "file:///var/aziot/certs/azure-iot-test-only.root.ca.cert.pem"
    
    [edge_ca]
    cert = "file:///var/aziot/certs/iot-edge-device-ca-gateway-full-chain.cert.pem"
    pk = "file:///var/aziot/secrets/iot-edge-device-ca-gateway.key.pem"
    
  8. config.toml 構成ファイルを保存して閉じます。 たとえば、nano エディターを使用している場合は、Ctrl + O - (Write Out)EnterCtrl + X - (Exit) を選択します。

  9. 以前に IoT Edge に他の証明書を使用していた場合は、次の 2 つのディレクトリ内のファイルを削除して、新しい証明書が適用されるようにします。

    • /var/lib/aziot/certd/certs
    • /var/lib/aziot/keyd/keys
  10. 変更を [適用] します。

    sudo iotedge config apply
    
  11. 構成にエラーがあるかどうかを確認します。

    sudo iotedge check --verbose
    

    Note

    新しくプロビジョニングされたデバイスでは、IoT Edge ハブに関連するエラーが表示される場合があります。

    × 運用環境の準備: Edge ハブのストレージ ディレクトリがホスト ファイル システムに保持されています - エラー

    edgeHub コンテナーの現在の状態を確認できませんでした

    このエラーは、IoT Edge ハブ モジュールが実行されていないために、新しくプロビジョニングされたデバイスで発生します。 このエラーを解決するには、IoT Hub でデバイスのモジュールを設定し、デプロイを作成します。 デバイスのデプロイを作成することで、IoT Edge ハブ モジュールを含むモジュールがデバイス上で開始されます。

親構成を確認する

hostname は修飾ドメイン名 (FQDN) または IoT Edge デバイスの IP アドレスである必要があります。これは IoT Edge ではダウンストリーム デバイスが接続するときにサーバー証明書でこの値が使用されるためです。 値が一致する必要があります。そうでなければ、"IP アドレスの不一致" エラーが発生します。

hostname を確認するには、edgeHub コンテナーの環境変数を調べる必要があります。

  1. 実行中の IoT Edge コンテナーを一覧表示します。

    iotedge list
    

    edgeAgentedgeHub コンテナーが実行されていることを確認します。 コマンド出力は次の例のようになります。

    NAME                        STATUS           DESCRIPTION      CONFIG
    SimulatedTemperatureSensor  running          Up 5 seconds     mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0
    edgeAgent                   running          Up 17 seconds    mcr.microsoft.com/azureiotedge-agent:1.4
    edgeHub                     running          Up 6 seconds     mcr.microsoft.com/azureiotedge-hub:1.4
    
  2. edgeHub コンテナーを調べます。

    sudo docker inspect edgeHub
    
  3. 出力の Env セクションから EdgeDeviceHostName パラメーターを見つけます。

    "EdgeDeviceHostName=10.0.0.4"
    
  4. EdgeDeviceHostName パラメーターの値が config.tomlhostname の設定と一致するかどうかを確認します。 一致しない場合は、構成を変更して適用したときに edgeHub コンテナーが実行されていました。 EdgeDeviceHostName を更新するには、edgeAgent コンテナーを削除します。

    sudo docker rm -f edgeAgent
    

    edgeAgentedgeHub コンテナーは数分以内に再作成され、開始されます。 edgeHub コンテナーが実行されたら、コンテナーを調べ、EdgeDeviceHostName パラメーターが構成ファイルと一致するかどうかを確認します。

ダウンストリーム デバイスを構成する

ダウンストリーム デバイスを構成するには、ローカルまたはリモートのコマンド シェルを開きます。

セキュリティで保護された接続を有効にするには、ゲートウェイ シナリオ内のすべての IoT Edge ダウンストリーム デバイスを、一意のデバイス CA 証明書と、ゲートウェイ階層内のすべてのデバイスで共有されるルート CA 証明書のコピーを使用して構成する必要があります。

  1. 証明書が形式の要件を満たしていることを確認します。

  2. ルート CA 証明書子デバイス CA 証明書、および子秘密キーをダウンストリーム デバイスに転送します。

  3. 証明書とキーを正しいディレクトリにコピーします。 デバイス証明書に推奨されるディレクトリは、証明書には /var/aziot/certs、キーには /var/aziot/secrets です。

    ### Copy device certificate ###
    
    # If the device certificate and keys directories don't exist, create, set ownership, and set permissions
    sudo mkdir -p /var/aziot/certs
    sudo chown aziotcs:aziotcs /var/aziot/certs
    sudo chmod 755 /var/aziot/certs
    
    sudo mkdir -p /var/aziot/secrets
    sudo chown aziotks:aziotks /var/aziot/secrets
    sudo chmod 700 /var/aziot/secrets
    
    # Copy device full-chain certificate and private key into the correct directory
    sudo cp iot-device-downstream-full-chain.cert.pem /var/aziot/certs
    sudo cp iot-device-downstream.key.pem /var/aziot/secrets
    
    ### Root certificate ###
    
    # Copy root certificate into the /certs directory
    sudo cp azure-iot-test-only.root.ca.cert.pem /var/aziot/certs
    
    # Copy root certificate into the CA certificate directory and add .crt extension.
    # The root certificate must be in the CA certificate directory to install it in the certificate store.
    # Use the appropriate copy command for your device OS or if using EFLOW.
    
    # For Ubuntu and Debian, use /usr/local/share/ca-certificates/
    sudo cp azure-iot-test-only.root.ca.cert.pem /usr/local/share/azure-iot-test-only.root.ca.cert.pem.crt
    # For EFLOW, use /etc/pki/ca-trust/source/anchors/
    sudo cp azure-iot-test-only.root.ca.cert.pem /etc/pki/ca-trust/source/anchors/azure-iot-test-only.root.ca.pem.crt
    
  4. 証明書とキーの所有権とアクセス許可を変更します。

    # Give aziotcs ownership to certificates
    # Read and write for aziotcs, read-only for others
    sudo chown -R aziotcs:aziotcs /var/aziot/certs
    sudo find /var/aziot/certs -type f -name "*.*" -exec chmod 644 {} \;
    
    # Give aziotks ownership to private keys
    # Read and write for aziotks, no permission for others
    sudo chown -R aziotks:aziotks /var/aziot/secrets
    sudo find /var/aziot/secrets -type f -name "*.*" -exec chmod 600 {} \;
    
  5. プラットフォーム固有のコマンドを使用してデバイス上の証明書ストアを更新することで、ダウンストリーム IoT Edge デバイスにルート CA 証明書をインストールします。

    # Update the certificate store
    
    # For Ubuntu or Debian - use update-ca-certificates
    sudo update-ca-certificates
    # For EFLOW or RHEL - use update-ca-trust
    sudo update-ca-trust
    

    update-ca-trust を使用する方法の詳細については、CBL-Mariner の SSL CA 証明書の管理に関するページを参照してください。

このコマンドでは、1 つの証明書が /etc/ssl/certs に追加されたことが報告されます。

Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.

ダウンストリーム構成ファイルを更新する

IoT Edge は自分のデバイスに既にインストールされている必要があります。 されていない場合は、手順に従って、1 つの Linux IoT Edge デバイスを手動でプロビジョニングします。

  1. /etc/aziot/config.toml 構成ファイルがダウンストリーム デバイスに存在するかどうかを確認します。

    デバイスに構成ファイルが存在しない場合は、次のコマンドを使用し、テンプレート ファイルに基づいてそれを作成します。

    sudo cp /etc/aziot/config.toml.edge.template /etc/aziot/config.toml
    

    このテンプレート ファイルを、このセクションの構成パラメーターを追加するための参照として使用することもできます。

  2. エディターを使用して IoT Edge 構成ファイルを開きます。 たとえば、nano エディターを使用して /etc/aziot/config.toml ファイルを開きます。

    sudo nano /etc/aziot/config.toml
    
  3. parent_hostname パラメーターを見つけるか、構成ファイルの先頭に追加します。すべてのダウンストリーム IoT Edge デバイスでは、その親を識別するために parent_hostname パラメーターを指定する必要があります。 parent_hostname パラメーターが、親デバイスの FQDN または IP アドレスになるように更新します (親デバイスの構成ファイルでホスト名として指定されたものと一致させます)。 次に例を示します。

    parent_hostname = "10.0.0.4"
    
  4. 信頼バンドル証明書パラメーターを見つけるか、構成ファイルの先頭に追加します。

    ファイルの URI を使用して、trust_bundle_cert パラメーターをデバイスのルート CA 証明書に更新します。 次に例を示します。

    trust_bundle_cert = "file:///var/aziot/certs/azure-iot-test-only.root.ca.cert.pem"
    
  5. 構成ファイルで、Edge CA 証明書セクションを見つけるか追加します。 証明書 cert と秘密キー pk のパラメーターを、IoT Edge ダウンストリーム デバイス上のフルチェーン証明書とキー ファイルのファイル URI パスで更新します。 IoT Edge では、証明書と秘密キーをテキストベースの PEM (Privacy Enhanced Mail) 形式にする必要があります。 次に例を示します。

    [edge_ca]
    cert = "file:///var/aziot/certs/iot-device-downstream-full-chain.cert.pem"
    pk = "file:///var/aziot/secrets/iot-device-downstream.key.pem"
    
  6. IoT Edge デバイスで、起動時に正しいバージョンの IoT Edge エージェントが使用されることを確認します。 「既定の Edge エージェント」セクションを見つけて、IoT Edge のイメージの値をバージョン 1.4 に設定します。 次に例を示します。

    [agent.config]
    image: "mcr.microsoft.com/azureiotedge-agent:1.4"
    
  7. ダウンストリーム構成ファイルの先頭は、次の例のようになります。

    parent_hostname = "10.0.0.4"
    trust_bundle_cert = "file:///var/aziot/certs/azure-iot-test-only.root.ca.cert.pem"
    
    [edge_ca]
    cert = "file:///var/aziot/certs/iot-device-downstream-full-chain.cert.pem"
    pk = "file:///var/aziot/secrets/iot-device-downstream.key.pem"
    
  8. config.toml 構成ファイルを保存して閉じます。 たとえば、nano エディターを使用している場合は、Ctrl + O - (Write Out)EnterCtrl + X - (Exit) を選択します。

  9. 以前に IoT Edge に他の証明書を使用していた場合は、次の 2 つのディレクトリ内のファイルを削除して、新しい証明書が適用されるようにします。

    • /var/lib/aziot/certd/certs
    • /var/lib/aziot/keyd/keys
  10. 変更を [適用] します。

    sudo iotedge config apply
    
  11. 構成にエラーがあるかどうかを確認します。

    sudo iotedge check --verbose
    

    ヒント

    IoT Edge チェック ツールでは、コンテナーを使用していくつかの診断チェックが実行されます。 ダウンストリーム IoT Edge デバイスでこのツールを使用する場合は、それが mcr.microsoft.com/azureiotedge-diagnostics:latest にアクセスできることを確認するか、コンテナー イメージをプライベート コンテナー レジストリ内に入れてください。

    Note

    新しくプロビジョニングされたデバイスでは、IoT Edge ハブに関連するエラーが表示される場合があります。

    × 運用環境の準備: Edge ハブのストレージ ディレクトリがホスト ファイル システムに保持されています - エラー

    edgeHub コンテナーの現在の状態を確認できませんでした

    このエラーは、IoT Edge ハブ モジュールが実行されていないために、新しくプロビジョニングされたデバイスで発生します。 このエラーを解決するには、IoT Hub でデバイスのモジュールを設定し、デプロイを作成します。 デバイスのデプロイを作成することで、IoT Edge ハブ モジュールを含むモジュールがデバイス上で開始されます。

ネットワークでダウンストリーム デバイスを分離する

この記事のこれまでの手順では、IoT Edge デバイスをゲートウェイまたはダウンストリーム デバイスとして設定し、それらの間に信頼関係接続を作成しています。 ゲートウェイ デバイスでは、ダウンストリーム デバイスと IoT Hub 間の相互作用 (認証とメッセージ ルーティングなど) が処理されます。 ダウンストリーム IoT Edge デバイスにデプロイされたモジュールでも、クラウド サービスへの独自の接続を作成できます。

ISA-95 標準に準拠するものなど、一部のネットワーク アーキテクチャでは、インターネット接続数を最小限にすることが模索されています。 このようなシナリオでは、直接のインターネット接続なしでダウンストリーム IoT Edge デバイスを構成することができます。 ゲートウェイ デバイス経由で IoT Hub 通信をルーティングするだけでなく、ダウンストリーム IoT Edge デバイスは、すべてのクラウド接続についてゲートウェイ デバイスに依存できます。

このネットワーク構成では、ゲートウェイ階層の最上位レイヤーにある IoT Edge デバイスだけがクラウドに直接接続できる必要があります。 下位レイヤーの IoT Edge デバイスは、その親デバイスまたは子デバイスとのみ通信できます。 ゲートウェイ デバイス上の特別なモジュールを使用すると、このシナリオが可能になります。次のものを含みます。

  • API プロキシ モジュールは、下に別の IoT Edge デバイスがあるすべての IoT Edge ゲートウェイで必要です。 つまり、最下位レイヤーを除く、ゲートウェイ階層の "すべてのレイヤー" にある必要があります。 このモジュールでは、nginx リバース プロキシを使用して、1 つのポートでネットワーク レイヤーを介して HTTP データがルーティングされます。 これは、モジュール ツインと環境変数を使用して高度に構成可能であるため、ご自身のゲートウェイ シナリオの要件に合うように調整できます。

  • Docker レジストリ モジュールは、ゲートウェイ階層の "最上位レイヤー" にある IoT Edge ゲートウェイにデプロイできます。 このモジュールは、下位レイヤーにあるすべての IoT Edge デバイスに代わってコンテナー イメージを取得してキャッシュする役割を担います。 このモジュールを最上位レイヤーにデプロイする代わりに、ローカル レジストリを使用したり、コンテナー イメージを手動でデバイスに読み込んで、モジュールのプル ポリシーを never に設定したりすることもできます。

  • IoT Edge 上の Azure Blob Storage は、ゲートウェイ階層の "最上位レイヤー" にある IoT Edge ゲートウェイにデプロイできます。 このモジュールは、下位レイヤーにあるすべての IoT Edge デバイスに代わって BLOB をアップロードする役割を担います。 また、BLOB をアップロードする機能により、モジュール ログのアップロードやサポート バンドルのアップロードなど、下位レイヤーの IoT Edge デバイスに対する便利なトラブルシューティング機能が使用できるようになります。

ネットワーク構成

ネットワーク オペレーターは、最上位レイヤーの各ゲートウェイ デバイスに対して次のことを行う必要があります。

  • 静的 IP アドレスまたは完全修飾ドメイン名 (FQDN) を指定します。

  • ポート 443 (HTTPS) と 5671 (AMQP) 経由での、この IP アドレスから Azure IoT Hub ホスト名への送信方向の通信を承認します。

  • ポート 443 (HTTPS) 経由での、この IP アドレスから Azure Container Registry ホスト名への送信方向の通信を承認します。

    API プロキシ モジュールでは、一度に 1 つのコンテナー レジストリへの接続のみを処理できます。 Microsoft Container Registry (mcr.microsoft.com) によって提供される公開イメージを含むすべてのコンテナー イメージをプライベート・コンテナー・レジストリに格納することをお勧めします。

ネットワーク オペレーターは、下位レイヤーの各ゲートウェイ デバイスに対して次のことを行う必要があります。

  • 静的 IP アドレスを指定します。
  • ポート 443 (HTTPS) と 5671 (AMQP) 経由での、この IP アドレスから親ゲートウェイの IP アドレスへの送信方向の通信を承認します。

モジュールを最上位レイヤーのデバイスにデプロイする

ゲートウェイ階層の最上位レイヤーの IoT Edge デバイスには、デバイスで実行する可能性があるワークロード モジュールに加えて、デプロイする必要がある一連の必須モジュールがあります。

API プロキシ モジュールは、ほとんどの一般的なゲートウェイ シナリオを処理するためにカスタマイズするように設計されています。 この記事では、基本的構成でそれらのモジュールを設定する例を示します。 詳細情報と例については、ゲートウェイ階層シナリオ用の API プロキシ モジュールの構成に関する記事を参照してください。

  1. Azure Portal で、IoT ハブに移動します。

  2. [デバイス管理] メニューで、[デバイス] を選択します。

  3. 一覧から、構成する上位レイヤーの IoT Edge デバイスを選択します。

  4. [Set modules](モジュールの設定) を選びます。

  5. [IoT Edge モジュール] セクションで [追加] を選択し、次に [Marketplace モジュール] を選択します。

  6. [IoT Edge API プロキシ] モジュールを検索して選択します。

  7. デプロイされているモジュールの一覧から API プロキシ モジュールの名前を選択し、次のモジュール設定を更新します。

    1. [環境変数] タブで、NGINX_DEFAULT_PORT の値を 443 に更新します。

    2. [コンテナーの作成オプション] タブで、ポートのバインドを、ポート 443 を参照するように更新します。

      {
        "HostConfig": {
          "PortBindings": {
            "443/tcp": [
              {
                "HostPort": "443"
              }
            ]
          }
        }
      }
      

    これらの変更により、ポート 443 でリッスンするように API プロキシ モジュールが構成されます。 ポートのバインドが競合しないようにするには、ポート 443 でリッスンしないように edgeHub モジュールを構成する必要があります。 代わりに、API プロキシ モジュールは、すべての edgeHub トラフィックをポート 443 でルーティングします。

  8. [ランタイム設定] を選択し、edgeHub モジュールの作成オプションを見つけます。 ポート 443 のポート バインドを削除し、ポート 5671 と 8883 のバインドはそのままにします。

    {
      "HostConfig": {
        "PortBindings": {
          "5671/tcp": [
            {
              "HostPort": "5671"
            }
          ],
          "8883/tcp": [
            {
              "HostPort": "8883"
            }
          ]
        }
      }
    }
    
  9. [保存] を選択して、ランタイム設定の変更を保存します。

  10. もう一度 [追加] を選択してから、[IoT Edge モジュール] を選択します。

  11. 次の値を指定して、Docker レジストリ モジュールをご自身のデプロイに追加します。

    1. IoT Edge モジュールの名前: registry

    2. [モジュール設定] タブで、Image URI: registry:latest

    3. [環境変数] タブで、次の環境変数を追加します。

      • 名前: REGISTRY_PROXY_REMOTEURL: このレジストリ モジュールのマップ先となるコンテナー レジストリの URL。 たとえば、https://myregistry.azurecr のようにします。

        レジストリモジュールは 1 つのコンテナー レジストリにしかマップできないため、すべてのコンテナー イメージを 1 つのプライベート コンテナー レジストリに入れることをお勧めします。

      • 名前: REGISTRY_PROXY_USERNAME: コンテナー レジストリに対して認証するユーザー名。

      • 名前: REGISTRY_PROXY_PASSWORD: コンテナー レジストリに対して認証するパスワード。

    4. [コンテナーの作成オプション] タブで、次のものを貼り付けます。

      {
          "HostConfig": {
              "PortBindings": {
                  "5000/tcp": [
                      {
                          "HostPort": "5000"
                      }
                  ]
              }
          }
      }
      
  12. [追加] を選択して、モジュールをデプロイに追加します。

  13. [次へ: ルート] を選択して、次の手順に進みます。

  14. ダウンストリーム デバイスからの device-to-cloud メッセージが IoT Hub に到達できるようにするには、すべてのメッセージを IoT Hub に渡すルートを含めます。 次に例を示します。

    1. 名前: Route
    2. : FROM /messages/* INTO $upstream
  15. [確認と作成] を選択して、最終手順に進みます。

  16. [作成] を選択して、ご自身のデバイスにデプロイします。

下位レイヤーのデバイスにモジュールをデプロイする

ゲートウェイ階層の下位レイヤーにある IoT Edge デバイスには、デバイスで実行する可能性があるワークロード モジュールに加えて、デプロイする必要がある 1 つの必須モジュールがあります。

コンテナー イメージ プルをルーティングする

ゲートウェイ階層内の IoT Edge デバイスに必要なプロキシ モジュールについて説明する前に、下位レイヤーのIoT Edge デバイスでのモジュール イメージの取得方法を理解することが重要です。

下位レイヤーのデバイスがクラウドに接続できなくても、通常どおりにモジュール イメージをプルできるようにする必要がある場合は、これらの要求を処理するようにゲートウェイ階層の最上位レイヤーのデバイスを構成する必要があります。 最上位レイヤーのデバイスは、コンテナー レジストリにマップされている Docker レジストリ モジュールを実行する必要があります。 そこで、コンテナー要求がルーティングされるように API プロキシ モジュールを構成します。 これらの詳細については、この記事の前のセクションで説明しています。 この構成では、下位レイヤーのデバイスは、クラウド コンテナー レジストリではなく、最上位レイヤーで実行されているレジストリを指している必要があります。

たとえば、下位レイヤーのデバイスは、mcr.microsoft.com/azureiotedge-api-proxy:1.1 を呼び出すのではなく、$upstream:443/azureiotedge-api-proxy:1.1 を呼び出す必要があります。

$upstream パラメーターは、下位レイヤー デバイスの親を指しています。したがって、要求は、コンテナー要求をレジストリ モジュールにルーティングするプロキシ環境がある最上位レイヤーに到達するまで、すべてのレイヤーを経由してルーティングされます。 この例の :443 ポートは、親デバイスの API プロキシ モジュールがリッスンしているポートに置き換える必要があります。

API プロキシ モジュールは、1 つのレジストリ モジュールにのみルーティングでき、各レジストリ モジュールは 1 つのコンテナー レジストリにのみマップできます。 したがって、下位レイヤー デバイスでプルする必要があるイメージはすべて、単一のコンテナー レジストリに格納されている必要があります。

下位レイヤー デバイスに、ゲートウェイ階層経由でモジュールのプル要求を行わせたくない場合は、ローカル レジストリ ソリューションを管理するという選択肢もあります。 または、デプロイを作成する前にモジュール イメージをデバイスにプッシュしてから、imagePullPolicynever に設定します。

IoT Edge エージェントをブートストラップする

IoT Edge エージェントは、すべての IoT Edge デバイス上で起動する最初のランタイム コンポーネントです。 ダウンストリームの IoT Edge デバイスが起動時に edgeAgent モジュール イメージにアクセスし、その後、デプロイにアクセスして残りのモジュール イメージを開始できるようにする必要があります。

IoT Edge デバイス上の構成ファイルにアクセスして認証情報、証明書、および親ホスト名を指定するときに、edgeAgent コンテナーイメージも更新します。

コンテナー イメージ要求を処理するように最上位レベルのゲートウェイ デバイスが構成されている場合は、mcr.microsoft.com を親ホスト名と API プロキシのリスニング ポートに置き換えます。 配置マニフェストで $upstream をショートカットとして使用できますが、そのためには、ルーティングを処理するために edgeHub モジュールが必要であり、この時点ではそのモジュールは開始されていません。 次に例を示します。

[agent]
name = "edgeAgent"
type = "docker"

[agent.config]
image: "{Parent FQDN or IP}:443/azureiotedge-agent:1.4"

ローカル コンテナー レジストリを使用している場合、またはデバイスでコンテナー イメージを手動で提供している場合は、それに応じて構成ファイルを更新してください。

ランタイムを構成してプロキシ モジュールをデプロイする

API プロキシ モジュールは、クラウドとダウンストリーム IoT Edge デバイス間のすべての通信をルーティングするために必要です。 ダウンストリーム IoT Edge デバイスがない、階層の最下位レイヤーにある IoT Edge デバイスには、このモジュールは必要ありません。

API プロキシ モジュールは、ほとんどの一般的なゲートウェイ シナリオを処理するためにカスタマイズするように設計されています。 この記事では、基本的構成でモジュールを設定する手順について簡単に説明します。 詳細情報と例については、ゲートウェイ階層シナリオ用の API プロキシ モジュールの構成に関する記事を参照してください。

  1. Azure Portal で、IoT ハブに移動します。

  2. [デバイス管理] メニューで、[デバイス] を選択します。

  3. 一覧から、構成する下位レイヤーの IoT Edge デバイスを選択します。

  4. [Set modules](モジュールの設定) を選びます。

  5. [IoT Edge モジュール] セクションで [追加] を選択し、次に [Marketplace モジュール] を選択します。

  6. [IoT Edge API プロキシ] モジュールを検索して選択します。

  7. デプロイされているモジュールの一覧から API プロキシ モジュールの名前を選択し、次のモジュール設定を更新します。

    1. [モジュール設定] タブで、[イメージ URI] の値を更新します。 mcr.microsoft.com$upstream:443に置き換えます。

    2. [環境変数] タブで、NGINX_DEFAULT_PORT の値を 443 に更新します。

    3. [コンテナーの作成オプション] タブで、ポートのバインドを、ポート 443 を参照するように更新します。

      {
        "HostConfig": {
          "PortBindings": {
            "443/tcp": [
              {
                "HostPort": "443"
              }
            ]
          }
        }
      }
      

    これらの変更により、ポート 443 でリッスンするように API プロキシ モジュールが構成されます。 ポートのバインドが競合しないようにするには、ポート 443 でリッスンしないように edgeHub モジュールを構成する必要があります。 代わりに、API プロキシ モジュールは、すべての edgeHub トラフィックをポート 443 でルーティングします。

  8. [ランタイムの設定] を選択します。

  9. edgeHub モジュールの設定を更新します。

    1. [イメージ] フィールドで、mcr.microsoft.com$upstream:443 に置き換えます。
    2. [作成オプション] フィールドで、ポート 443 のポート バインドを削除し、ポート 5671 と 8883 のバインドはそのままにします。
    {
      "HostConfig": {
        "PortBindings": {
          "5671/tcp": [
            {
              "HostPort": "5671"
            }
          ],
          "8883/tcp": [
            {
              "HostPort": "8883"
            }
          ]
        }
      }
    }
    
  10. edgeAgent モジュールの設定を更新します。

    1. [イメージ] フィールドで、mcr.microsoft.com$upstream:443 に置き換えます。
  11. [保存] を選択して、ランタイム設定の変更を保存します。

  12. [次へ: ルート] を選択して、次の手順に進みます。

  13. ダウンストリーム デバイスからの device-to-cloud メッセージが IoT Hub に到達できるようにするには、すべてのメッセージを $upstream に渡すルートを含めます。 下位レイヤーのデバイスの場合、アップストリーム パラメーターは親デバイスを指します。 次に例を示します。

    1. 名前: Route
    2. : FROM /messages/* INTO $upstream
  14. [確認と作成] を選択して、最終手順に進みます。

  15. [作成] を選択して、ご自身のデバイスにデプロイします。

子から親への接続を確認する

  1. ダウンストリーム デバイスで次の openssl コマンドを実行して、子から親への TLS/SSL 接続を確認します。 <parent hostname> を親の FQDN または IP アドレスに置き換えます。

    openssl s_client -connect <parent hostname>:8883 </dev/null 2>&1 >/dev/null
    

    コマンドは、次の例のように、親証明書チェーンの検証に成功したことをアサートする必要があります。

    azureUser@child-vm:~$ openssl s_client -connect <parent hostname>:8883 </dev/null 2>&1 >/dev/null
    Can't use SSL_get_servername
    depth=3 CN = Azure_IoT_Hub_CA_Cert_Test_Only
    verify return:1
    depth=2 CN = Azure_IoT_Hub_Intermediate_Cert_Test_Only
    verify return:1
    depth=1 CN = gateway.ca
    verify return:1
    depth=0 CN = <parent hostname>
    verify return:1
    DONE
    

    "SSL_get_servername を使用できません" というメッセージは無視できます。

    depth=0 CN = 値は、親の config.toml 構成ファイルで指定された hostname パラメーターと一致する必要があります。

    コマンドがタイムアウトすると、子デバイスと親デバイスの間でポートがブロックされている可能性があります。 デバイスのネットワーク構成と設定を確認します。

    警告

    ゲートウェイの [edge_ca] セクションでフルチェーン証明書を使用しない場合は、ダウンストリーム デバイスで証明書検証エラーが発生します。 たとえば、上記の openssl s_client ... コマンドを実行すると、次のように出力されます。

    Can't use SSL_get_servername
    depth=1 CN = gateway.ca
    verify error:num=20:unable to get local issuer certificate
    verify return:1
    depth=0 CN = <parent hostname>
    verify return:1
    DONE
    

    フルチェーン デバイス証明書がダウンストリーム IoT Edge デバイス上で使用および構成されていない場合、そのダウンストリーム デバイスに接続する TLS 対応デバイスでも同じ問題が発生します。

Microsoft Defender for IoT と IoT Edge ゲートウェイの統合

ダウンストリーム デバイスを使用すると、ダウンストリーム デバイス プロキシを使用して、Microsoft Defender for IoT のマイクロ エージェントを IoT Edge ゲートウェイと統合できます。

Defender for IoT マイクロ エージェント」を学習します。

ダウンストリーム デバイス プロキシを使用して Microsoft Defender for IoT を IoT Edge と統合するには:

  1. Azure portal にサインインします。

  2. IoT Hub に移動します>Your Hub>デバイス管理>デバイス

  3. デバイスを選択します。

    選択のためにデバイスが配置されている場所を示すスクリーンショット

  4. これらの手順から作成した DefenderIotMicroAgent モジュール ツインを選択します。

    DefenderIotMicroAgent の場所を示すスクリーンショット

  5. ボタンを選択して接続文字列 (主キー) をコピーします。

  6. [接続文字列] をテキスト編集アプリケーションに貼り付け、GatewayHostName を文字列に追加します。 たとえば、HostName=nested11.azure-devices.net;DeviceId=downstream1;ModuleId=module1;SharedAccessKey=xxx;GatewayHostName=10.16.7.4 のようにします。

  7. ダウンストリーム デバイスでターミナルを開きます。

  8. 次のコマンドを使用して、Defender for Cloud エージェント ディレクトリの utf-8 でエンコードされた接続文字列を次のパスの ファイル connection_string.txt に配置します: /etc/defender_iot_micro_agent/connection_string.txt

    sudo bash -c 'echo "<connection string>" > /etc/defender_iot_micro_agent/connection_string.txt'
    

    これで、connection_string.txt は、/etc/defender_iot_micro_agent/connection_string.txt というパスの場所にあるはずです。

  9. このコマンドを使用して、サービスを再起動します。

    sudo systemctl restart defender-iot-micro-agent.service 
    
  10. デバイスに戻ります。

    デバイスに戻る方法を示すスクリーンショット

  11. IoT Hub への接続を有効にし、歯車アイコンを選択します。

    親デバイスを設定するために何を選択するかを示すスクリーンショット

  12. 表示された一覧から親デバイスを選択します。

  13. ダウンストリーム デバイスと IoT Edge デバイス間のポート 8883 (MQTT) が開いているのを確認します。

次のステップ

IoT Edge デバイスをゲートウェイとして使用する方法

ゲートウェイ階層シナリオ用に API プロキシ モジュールを構成する