How to protect ConnectionStrings in Azure IoT Edge module code? - azure-iot-edge

Typing the connection string in the configuration file (as shown in the official example: https://github.com/Azure-Samples/iot-edge-samples/blob/master/js/simple/gw.cloud.config.json#L38) doesn't seem right.
Environment variables may be provided to the modules by the Edge Runtime (https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/iot-edge/iot-edge-runtime.md) but as far as I can see there is no way to modify its behaviour.

In the first document(https://github.com/Azure-Samples/iot-edge-samples/blob/master/js/simple/gw.cloud.config.json#L38), it shows how to customize the IoT Edge runtime (gw.[local|cloud].config.json). You can update gw.cloud.config.json by replacing <IoT Hub device connection string> with your actual IoT Hub device connection string to establish connection between IoT Edge application and Azure IoT Hub.
In the next document(https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/iot-edge/iot-edge-runtime.md), you can also configure the IoT Edge runtime by executing the following command.You will find the connection string setting in C:\ProgramData\azure-iot-edge\config\config.json.
iotedgectl setup --connection-string "{device connection string}" --nopass

Related

Error in Azure IoT Edge runtime - A module runtime error occurred

iotedge list command error
Hi,
On running the iotedge list command it is throwing - A module runtime error occurred. Is there something missed. It was working fine till yesterday.
If you are still blocked, you can check the below information.
There could be multiple reasons for the module runtime error on IoT Edge.
Was it working earlier and stopped suddenly? As Matthijs mentioned in
the comments, collect complete logs to know more about the issue.
Refer Gather debug information with 'support-bundle' command
Also, check Azure IoT Edge security manager logs. The IoT Edge
security manager is responsible for operations like initializing the
IoT Edge system at startup and provisioning devices. If IoT Edge
isn't starting, the security manager logs may provide useful
information.
Make sure that the module is properly configured and all
required environment variables are set.
If the issue still persists, you can try restarting the module or the
entire IoT Edge device to see if that resolves the issue.
You can also check Solutions to common issues for Azure IoT Edge for most common errors and solutions.

How to set up SSL certificates for containerized EventHubs message processors?

I've been writing an EventHubs message processor that just connects to EventHubs and processes messages on the EventHub. I've been developing in Visual Studio on Windows using .NET 6. Things work as expected on Windows; I can:
Connect to EventHubs
Receive messages
Do the message processing I want
Great. I then wanted to scale my message processor horizontally and decided that I would Dockerize it, and since .NET 6 runs on Linux, I would cross-compile it for Linux and eventually deploy multiple instances of my message processor on Docker Desktop as a next step. I eventually want to stick it on Kubernetes to scale up by an order of magnitude or two.
It was easy to Dockerize my Project in Visual Studio. I simply right-clicked the Project and selected Add -> Docker Support. Visual Studio detected I had Docker Desktop installed and generated all the config files I needed, and added an appropriate build configuration so that I could compile a binary, build a Docker image with it, and automatically deploy it to my local Docker Desktop instance.
.NET 6 also compiled without errors, which was great. However, when my container spins up, I get hit with the following runtime error:
System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: PartialChain
and there is a stack trace (omitted here for brevity) stemming from something in the EventHubs processor library:
<...many layers...> at Azure.Messaging.EventHubs.Primitives.EventProcessor-1.RunProcessingAsync(CancellationToken cancellationToken)
I am correctly passing my EventHubs connection string to my container, but what I surmise is that my container is missing an SSL certificate or has a misconfigured SSL certificate. I suppose Visual Studio has helpfully silently gone ahead and installed a development certificate when I developed my message processor on Windows so that EventHubs connections "just work" in my development environment, but that SSL certificate is not available to my container, since it isn't part of the build output.
I know I probably should be using Azure key vault or whatever secret management service they provide, but how else can I resolve this SSL certificate issue as quickly or painlessly as possible? It would be nice if I can just keep my connection string in my appsettings.json (It's fine. Toy project, only using Azure free credits anyway.)
The easiest way forward would be to register a handler that participates in certificate validation and can, if desired, override normal handling and force acceptance. This, of course, comes with the warning that you're bypassing standard security checks and may be putting your network and host in danger.
You don't mention which client you're using, but each takes a set of options in their constructor. The options for each type have a member named ConnectionOptions which returns an EventHubsConnectionOptions instance that allows you to register a CertificateValidationCallback.
The Event Hubs Influencing SSL certificate validation sample demonstrates how to use it. More information is also available in the .NET documentation for RemoteCertificateValidationCallback.

Do modules deployed via Azure IoT Edge runtime require an Azure IoT SDK client?

I have a service that's already Dockerized. The service listens on some ports and makes some outbound network calls. At the moment, updating the service requires someone to access the console remotely and manually replace the old container with the latest version.
After reading through the Azure IoT Edge documentation and the SDKs, it's not clear to me if an Azure IoT module MUST include an Azure IoT SDK. I know the Azure IoT SDK is necessary for passing messages, accessing the module twin, and probably more, but I don't need any of that at the moment for this specific use-case.
Can I reuse my existing Docker containers with Azure IoT Edge or would I need to add the Azure IoT SDK (because there's a health check or other internal requirement for the SDK)?
As you mentioned, Azure IoT SDK is the recommended way to do messaging, access twin etc. But it is optional.
If you just want the IoT Edge runtime to launch a Docker container that listens on local ports and performs outbound network calls, you can certainly do that. Nothing will get in your way.

Failing to setup Azure IoT Edge runtime: Invalid hostname

I have Standard D2s v3 (2 vcpus, 8 GB memory) running on Azure with Python, Docker and iotedgectl installed.
When I run
iotedgectl setup --connection-string "HostName=***.azure-devices.net;DeviceId=***;SharedAccessKey=***" --auto-cert-gen-force-no-passwords
I get following error
ERROR: Error parsing user input data: Invalid hostname. Hostname cannot be empty or greater than 64 characters: ****.nwq4jyrgm4zejiseat2enywp0h.fx.internal.cloudapp.net.
ERROR: Please fix any input values and re-run 'iotedgectl setup'
ERROR: Errors were observed. Return Code: 1
any ideas?
The IoT Edge runtime requires a hostname to generate a TLS server certificate for the Edge Hub. This enables verifiable TLS connections between modules and leaf devices (for gateway scenarios). Per RFC3280, the maximum length of the Common Name for an SSL certificate is 64 chars. (search for ub-common-name-length).
This error is indicating that the hostname exceeds this limit. By default, the iotedgectl tool detects and uses the hostname of the host machine. Unfortunately, Azure Windows VMs have very long hostnames.
To remedy this, you can set the hostname and bypass the auto detection like so:
iotedgectl setup --connection-string "<conn string>" --auto-cert-gen-force-no-passwords --edge-hostname <a shorter hostname>
If you are interested in using IoT Edge as a gateway, there is more information here: https://learn.microsoft.com/en-us/azure/iot-edge/how-to-create-transparent-gateway

To connect with AWS IoT broker in iOS

We are developing an application which needs to consume AWS IoT service based on a MQTT protocol deviation. We are currently facing issues to get connected with MQTT broker provided by AWS IoT cloud server.
Following is the environment:
iOS Version: 8.0 / 9.0
Programming language: Swift
Library for MQTT: Moscapsule
Steps followed:
Set initial config clientid, host, port
Set client certificate with private key, providing .pem file path (e.g. cert.pem, privateKey.pem)
Set server certificate which is root certificate .pem file path (e.g. rootCA.pem)
Set tls opts with tsl_insecure: false, cert_reqs: SSL_VERIFY_PEER, tls version: tlsv1.2, ciphers: nil
Problems faced:
When trying to connect to server/broker gives error “unable to create TLS_Context”.
With setting tls cert_reqs: SSL_VERIFY_NONE, gives connection status success with subcribe and publish sucess, but doesn’t reflect on server or broker.
Any help in this context is highly appreciable.
The AWS SDK for iOS already supports connecting to AWS IoT over MQTT. You can see an example Swift program which transfers data to and from AWS IoT over MQTT using certificate-based authentication here. If you'd like to use a different MQTT client and just need to know how to set it up, you might start with the AWS SDK for iOS, and then have a look at the code involved in setting up the TLS connection.
Thanks for using AWS IoT.

Resources