Azure IoTHub Python SDK: Connection failed with Error unathorized using IoTHubModuleClient

FBaigo 96 Reputation points
2021-11-05T20:03:04.253+00:00

Hello everyone, this is my first post here in Microsoft's Q&A!
Lately I've been developing IoT Edge modules for our devices and I'm stuck with an issue with Azure's python SDK. I've already got an IoT Edge device provisioned in our IoT Hub with DPS + certificates and some modules running in it. We've created our certificates based on:
https://learn.microsoft.com/en-us/azure/iot-hub/tutorial-x509-scripts

So I'm working on a new module and I'm trying to instance a new module client with the following method.

azure_module_client = IoTHubModuleClient.create_from_x509_certificate(  
                _x509, iothub_hostname, device_id, module_id, websockets=True)  

I can't share the actual code or any related data. Here's how I set the variables above:

iothub_hostname = os.getenv("IOTEDGE_IOTHUBHOSTNAME")  

content: **.azure-devices.net

device_id = os.getenv('IOTEDGE_DEVICEID')  

content: "deviceID" as stated in

module_id = os.getenv("IOTEDGE_MODULEID")  

content: "moduleID" (This is NOT deviceId/moduleID, just moduleID)

_x509 = X509(  
    cert_file=cert_path,  
    key_file=key_path  
)  

I'm using my DPS key and cert .pem files in order to create the X509 object. And here's the result after trying to instance the client:
147001-unathorized-error.png

I've tried the following with the same error result:

  • Using the certs and key used by the iotedge daemon for connecting to our IoT Hub / DPS.
  • Creating a new device certificate (based on Azure's certificate generator) with Subject Name "deviceID/moduleID"
  • Creating a new device certificate (based on Azure's certificate generator) with Subject Name "moduleID"
  • Creating a new device intermediate certificate (based on Azure's certificate generator) with Subject Name "deviceID/moduleID"

Question

  1. Can I use the same production certificates (DPS) in order to instance a new module client? I've tested this with the following snippet and it works. azure_device_client = IoTHubDeviceClient.create_from_x509_certificate(
    x509, iothub_hostname, device_id, websockets=True)
  2. If not, do I need to create a new set of certificates, root CA, etc for my module?
  3. Which is the correct common name pattern I should use for my device certificate? deviceID/moduleID or deviceID\ moduleID See the following sites which state different CN:
    https://github.com/Azure/azure-iot-sdk-python-preview/wiki/X509_Chain
    https://github.com/Azure/azure-iot-sdk-python/blob/f960a123d9afe806aa8113a7b4add5d8b128e880/azure-iot-device/samples/sync-samples/send_message_via_module_x509.py

I list some of the azure packages I've already got installed and could be related, please let me know if I missed any.

azure-common 1.1.27
azure-core 1.14.0
azure-identity 1.6.0
azure-iot-device 2.6.0
azure-iot-hub 2.4.0
azure-mgmt 4.0.0
azure-mgmt-authorization 0.50.0
azure-mgmt-core 1.2.2
azure-mgmt-eventhub 2.6.0
azure-mgmt-iotcentral 0.1.0
azure-mgmt-iothub 0.5.0

Azure IoT Edge
Azure IoT Edge
An Azure service that is used to deploy cloud workloads to run on internet of things (IoT) edge devices via standard containers.
598 questions
Azure IoT SDK
Azure IoT SDK
An Azure software development kit that facilitates building applications that connect to Azure IoT services.
228 questions
0 comments No comments
{count} votes

Accepted answer
  1. FBaigo 96 Reputation points
    2021-11-08T13:00:21.46+00:00

    Hi @Sander van de Velde | MVP thanks for your reply!

    Azure IoT Edge Modules are not aware of the way the Edge device is connected to the IoT Hub. These can deployed on any device running the Azure IoT Edge runtime. They only care about connection the EdgeHub module.
    The security between Azure IoT Edge runtime and IoT Hub (even when using the DPS) connection, is controlled by the IoT Edge runtime itself.

    Ok, it makes sense. Let me explain a bit more, if required I'll create a new thread.

    I started testing the IoTHubModuleClient.create_from_x509_certificate method because we actually use the create_from_edge_environment method and faced some issues. With the "from_edge_environment" method we had no problems connecting to our IoT Hub within the module but after 30 days or so have passed we have to remotely restart (or power-off) our devices in order to regain a "new self-signed certificate" (I'm not entirely sure about this, but I can assure you that if we don't restart our device then the module's cannot connect to the IoT Hub)

    From Azure's module troubleshouting logs:
    147422-image.png

    And if we run the iotedge runtime's check option (iotedge check).
    147376-image.png

    The samples you refer to are for logic running on 'direct internet connected devices', not edge devices.

    Ok, this clarifies a lot!

    I see in your attached snapshot the create_from_edge_environment method. Is this method supposed to be used for instancing a new IoTHubModule client? (instead of the create_from_x509)

    Once again, thanks a lot for your aid! I'll be reading the articles you shared above and return if I still have issues.


1 additional answer

Sort by: Most helpful
  1. Sander van de Velde | MVP 36,761 Reputation points MVP Volunteer Moderator
    2021-11-06T14:18:17.687+00:00

    Hello @FBaigo ,

    Azure IoT Edge Modules are not aware of the way the Edge device is connected to the IoT Hub. These can deployed on any device running the Azure IoT Edge runtime. They only care about connection the EdgeHub module.

    The security between Azure IoT Edge runtime and IoT Hub (even when using the DPS) connection, is controlled by the IoT Edge runtime itself.

    The samples you refer to are for logic running on 'direct internet connected devices', not edge devices.

    Please base your Azure IoT Edge module on the right template:

    146958-image.png

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.