Azure / iotedge

The IoT Edge OSS project
MIT License
1.46k stars 459 forks source link

UnauthorizedException for connection strings with GatewayHostName #6830

Closed ArneJoris closed 1 year ago

ArneJoris commented 1 year ago

Expected Behavior

IoT Edge modules making IoT hub connections using connection strings with GatewayHostName should work.

Current Behavior

Authentication using a connection string with GatewayHostName throws an UnauthorizedException in edgeHub. This exception is not propagated in the SDK (i.e. connect() succeeds) but presents an entirely empty device (no twin properties,....)

Steps to Reproduce

Device twin for device 00E04CFFFE360D7B:

{
    "etag": "AAAAAAAAAAQ=",
    "deviceId": "00E04CFFFE360D7B",
    "deviceEtag": "NDQ2NzI0Njc0",
    "version": 8,
    "properties": {
        "desired": { 
            "$version": 4,
            "routerConfig": [ ... ]
        },
        "reported": { 
            "$version": 2,     
        }
     },                    
    "capabilities": {
        "iotEdge": false
    },
    "deviceScope": "ms-azure-iot-edge://LoRaWAN-network-server2-638079482881198023",
    "parentScopes": [
        "ms-azure-iot-edge://LoRaWAN-network-server2-638079482881198023",
        "ms-azure-iot-edge://LoRaWAN-network-server2-638079482881198023"
    ],
    "status": "enabled",
    "statusUpdateTime": "2022-12-30T18:20:54.9569076Z",
    "lastActivityTime": "0001-01-01T00:00:00.0000000Z",
    "connectionState": "Disconnected",
    "cloudToDeviceMessageCount": 0,
    "authenticationType": "sas"
}
python3
Python 3.8.10 (default, Nov 14 2022, 12:59:47)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information
>>> from azure.iot.device import IoTHubDeviceClient
>>> # Connect to device through gateway
>>> CONNECTION_STRING="HostName=iot-hub-strongbox-dev.azure-devices.net;GatewayHostName=LoRaWAN-network-server-dev-02;DeviceId=00E04CFFFE360D7B;SharedAccessKey=AKey="
>>> with open("/var/lib/aziot/certd/certs/aziotedgedca-86f154be7ff14480027f0d00c59c223db6d9e4ab0b559fc523cca36a7c973d6d.cer") as caFile:
...    CA_CONTENT=caFile.read()
...
>>> client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING, server_verification_cert=CA_CONTENT)
>>> client.connect()
>>> client.get_twin()
{'desired': {}, 'reported': {}}
>>> client.disconnect()

edgeHub log:

<7> 2022-12-30 19:58:56.016 +00:00 [DBG] [Microsoft.Azure.Devices.Edge.Hub.Core.Routing.RoutingEdgeHub] - GetTwin call received from 00E04CFFFE360D7B
<7> 2022-12-30 19:58:56.017 +00:00 [DBG] [Microsoft.Azure.Devices.Edge.Hub.Core.Twin.StoringTwinManager] - Getting twin for 00E04CFFFE360D7B
<7> 2022-12-30 19:58:56.017 +00:00 [DBG] [Microsoft.Azure.Devices.Edge.Hub.Core.IDeviceScopeIdentitiesCache] - Getting service identity for 00E04CFFFE360D7B
<7> 2022-12-30 19:58:56.017 +00:00 [DBG] [Microsoft.Azure.Devices.Edge.Hub.CloudProxy.CloudConnection] - Creating cloud connection for client 00E04CFFFE360D7B using EdgeHub credentials
<6> 2022-12-30 19:58:56.017 +00:00 [INF] [Microsoft.Azure.Devices.Edge.Hub.CloudProxy.CloudConnection] - Attempting to connect to IoT Hub for client 00E04CFFFE360D7B via MQTT...
<7> 2022-12-30 19:58:56.032 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18] HANDLER_ADDED"
<7> 2022-12-30 19:58:56.032 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18] REGISTERED"
<7> 2022-12-30 19:58:56.032 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18] CONNECT: 20.241.88.173:8883"
<7> 2022-12-30 19:58:56.035 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] ACTIVE"
<7> 2022-12-30 19:58:56.035 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] WRITE: ConnectPacket[Type=CONNECT, QualityOfService=AtMostOnce, Duplicate=False, Retain=False]"
<7> 2022-12-30 19:58:56.035 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] FLUSH"
<7> 2022-12-30 19:58:56.036 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] READ"
<7> 2022-12-30 19:58:56.040 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] RECEIVED_COMPLETE"
<7> 2022-12-30 19:58:56.040 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] READ"
<7> 2022-12-30 19:58:56.040 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] READ"
<7> 2022-12-30 19:58:56.041 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] RECEIVED_COMPLETE"
<7> 2022-12-30 19:58:56.041 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] READ"
<7> 2022-12-30 19:58:56.041 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] READ"
<7> 2022-12-30 19:58:56.046 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] USER_EVENT: TlsHandshakeCompletionEvent(SUCCESS)"
<7> 2022-12-30 19:58:56.046 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] READ"
<7> 2022-12-30 19:58:56.046 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] RECEIVED_COMPLETE"                                                         
<7> 2022-12-30 19:58:56.046 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] READ"
<7> 2022-12-30 19:58:56.046 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] READ"
<7> 2022-12-30 19:58:56.052 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] RECEIVED: ConnAckPacket[Type=CONNACK, QualityOfService=AtMostOnce, Duplicate=False, Retain=False]"
<7> 2022-12-30 19:58:56.052 +00:00 [DBG] [Microsoft.Azure.Devices.Edge.Hub.CloudProxy.ConnectivityAwareClient] - Received connection status changed callback with connection status Disconnected and reason Bad_Credential for 00E04CFFFE360D7B 
<7> 2022-12-30 19:58:56.053 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 => [::ffff:20.241.88.173]:8883] CLOSE"
<7> 2022-12-30 19:58:56.054 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 :> [::ffff:20.241.88.173]:8883] RECEIVED_COMPLETE"
<7> 2022-12-30 19:58:56.054 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 :> [::ffff:20.241.88.173]:8883] READ"
<7> 2022-12-30 19:58:56.054 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 :> [::ffff:20.241.88.173]:8883] READ"                                                                      
<7> 2022-12-30 19:58:56.054 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 :> [::ffff:20.241.88.173]:8883] INACTIVE"                                                                  
<7> 2022-12-30 19:58:56.054 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 :> [::ffff:20.241.88.173]:8883] UNREGISTERED"
<7> 2022-12-30 19:58:56.054 +00:00 [DBG] [DotNetty.Handlers.Logging.LoggingHandler] - "[id: 0x242a5d18, [::ffff:172.18.0.3]:57692 :> [::ffff:20.241.88.173]:8883] HANDLER_REMOVED"                                                           
<7> 2022-12-30 19:58:56.053 +00:00 [DBG] [Microsoft.Azure.Devices.Edge.Hub.CloudProxy.ConnectivityAwareClient] - Operation OpenAsync failed for 00E04CFFFE360D7B                                                                             
Microsoft.Azure.Devices.Client.Exceptions.UnauthorizedException: CONNECT failed: RefusedNotAuthorized
   at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttTransportHandler.OpenInternalAsync(CancellationToken cancellationToken)                                                                                                                 
at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttTransportHandler.OpenAsync(CancellationToken cancellationToken)
   at Microsoft.Azure.Devices.Client.Transport.ProtocolRoutingDelegatingHandler.OpenAsync(CancellationToken cancellationToken)                                                                                                                  
at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.<>c__DisplayClass27_0.<<ExecuteWithErrorHandlingAsync>b__0>d.MoveNext()                                                                                                
--- End of stack trace from previous location ---                                                                                                                                                                                               
at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.ExecuteWithErrorHandlingAsync[T](Func`1 asyncOperation)                                                                                                                   
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.<>c__DisplayClass38_0.<<OpenInternalAsync>b__0>d.MoveNext()                                                                                                            
--- End of stack trace from previous location ---                                                                                                                                                                                               
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.EnsureOpenedAsync(CancellationToken cancellationToken)                                                                                                                    
at Microsoft.Azure.Devices.Client.InternalClient.OpenAsync()                                                                                                                                                                                 
at Microsoft.Azure.Devices.Edge.Util.TaskEx.TimeoutAfter(Task task, TimeSpan timeout, Action action) in /mnt/vss/_work/1/s/edge-util/src/Microsoft.Azure.Devices.Edge.Util/TaskEx.cs:line 160                                                
at Microsoft.Azure.Devices.Edge.Hub.CloudProxy.DeviceClientWrapper.OpenAsync() in /mnt/vss/_work/1/s/edge-hub/core/src/Microsoft.Azure.Devices.Edge.Hub.CloudProxy/DeviceClientWrapper.cs:line 53
   at Microsoft.Azure.Devices.Edge.Hub.CloudProxy.ConnectivityAwareClient.<>c__DisplayClass30_0.<<InvokeFunc>b__0>d.MoveNext() in /mnt/vss/_work/1/s/edge-hub/core/src/Microsoft.Azure.Devices.Edge.Hub.CloudProxy/ConnectivityAwareClient.cs:line 196     

Using a connection string without GatewayHostName works fine:

python3
Python 3.8.10 (default, Nov 14 2022, 12:59:47)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information
>>> from azure.iot.device import IoTHubDeviceClient
>>> 
>>> # Connect to device directly
>>> CONNECTION_STRING="HostName=iot-hub-strongbox-dev.azure-devices.net;DeviceId=00E04CFFFE360D7B;SharedAccessKey=AKey="
>>> client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
>>> client.connect()
>>> client.get_twin()
{'desired': {'$version': 4, 'routerConfig': {'DRs': [[10, 125, 0], [9, 125, 0], [8, 125, 0], [7, 125, 0], [8, 500, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [12, 500, 1], [11, 500, 1], [10, 500, 1], [9, 500, 1], [8, 500, 1], [7, 500, 1]], 'JoinEui': [['0000000000000000', 'FFFFFFFFFFFFFFFF']], 'NetID': [1], 'freq_range': [902000000, 928000000], 'hwspec': 'sx1301/1', 'nocca': True, 'nodc': True, 'nodwell': True, 'region': 'US902', 'sx1301_conf': [{'chan_FSK': {'enable': True, 'if': 300000, 'radio': 1}, 'chan_Lora_std': {'bandwidth': 500000, 'enable': True, 'if': 300000, 'radio': 0, 'spread_factor': 8}, 'chan_multiSF_0': {'enable': True, 'if': -400000, 'radio': 0}, 'chan_multiSF_1': {'enable': True, 'if': -200000, 'radio': 0}, 'chan_multiSF_2': {'enable': True, 'if': 0, 'radio': 0}, 'chan_multiSF_3': {'enable': True, 'if': 200000, 'radio': 0}, 'chan_multiSF_4': {'enable': True, 'if': -300000, 'radio': 1}, 'chan_multiSF_5': {'enable': True, 'if': -100000, 'radio': 1}, 'chan_multiSF_6': {'enable': True, 'if': 100000, 'radio': 1}, 'chan_multiSF_7': {'enable': True, 'if': 300000, 'radio': 1}, 'radio_0': {'enable': True, 'freq': 909100000}, 'radio_1': {'enable': True, 'freq': 909800000}}]}}, 'reported': {'$version': 2, 'Package': 'foo'}}
>>> client.disconnect()

Context (Environment)

LoRaWAN Network server (from https://azure.github.io/iotedge-lorawan-starterkit/dev/) uses GatewayHostName connection strings to connect.

Output of iotedge check

Click here ``` Configuration checks (aziot-identity-service) --------------------------------------------- √ keyd configuration is well-formed - OK √ certd configuration is well-formed - OK √ tpmd configuration is well-formed - OK √ identityd configuration is well-formed - OK √ daemon configurations up-to-date with config.toml - OK √ identityd config toml file specifies a valid hostname - OK √ aziot-identity-service package is up-to-date - OK √ host time is close to reference time - OK √ preloaded certificates are valid - OK √ keyd is running - OK √ certd is running - OK √ identityd is running - OK √ read all preloaded certificates from the Certificates Service - OK √ read all preloaded key pairs from the Keys Service - OK √ check all EST server URLs utilize HTTPS - OK √ ensure all preloaded certificates match preloaded private keys with the same ID - OK Connectivity checks (aziot-identity-service) -------------------------------------------- √ host can connect to and perform TLS handshake with iothub AMQP port - OK √ host can connect to and perform TLS handshake with iothub HTTPS / WebSockets port - OK √ host can connect to and perform TLS handshake with iothub MQTT port - OK Configuration checks -------------------- √ aziot-edged configuration is well-formed - OK √ configuration up-to-date with config.toml - OK √ container engine is installed and functional - OK √ configuration has correct URIs for daemon mgmt endpoint - OK √ aziot-edge package is up-to-date - OK √ container time is close to host time - OK ‼ DNS server - Warning Container engine is not configured with DNS server setting, which may impact connectivity to IoT Hub. Please see https://aka.ms/iotedge-prod-checklist-dns for best practices. You can ignore this warning if you are setting DNS server per module in the Edge deployment. ‼ production readiness: logs policy - Warning Container engine is not configured to rotate module logs which may cause it run out of disk space. Please see https://aka.ms/iotedge-prod-checklist-logs for best practices. You can ignore this warning if you are setting log policy per module in the Edge deployment. ‼ production readiness: Edge Agent's storage directory is persisted on the host filesystem - Warning The edgeAgent module is not configured to persist its /tmp/edgeAgent directory on the host filesystem. Data might be lost if the module is deleted or updated. Please see https://aka.ms/iotedge-storage-host for best practices. ‼ production readiness: Edge Hub's storage directory is persisted on the host filesystem - Warning The edgeHub module is not configured to persist its /tmp/edgeHub directory on the host filesystem. Data might be lost if the module is deleted or updated. Please see https://aka.ms/iotedge-storage-host for best practices. √ Agent image is valid and can be pulled from upstream - OK √ proxy settings are consistent in aziot-edged, aziot-identityd, moby daemon and config.toml - OK Connectivity checks ------------------- √ container on the default network can connect to upstream MQTT port - OK √ container on the IoT Edge module network can connect to upstream MQTT port - OK 29 check(s) succeeded. 4 check(s) raised warnings. Re-run with --verbose for more details. 4 check(s) were skipped due to errors from other checks. Re-run with --verbose for more details. ```

Device Information

Runtime Versions

Server: Docker Engine - Community Engine: Version: 20.10.22 API version: 1.41 (minimum version 1.12) Go version: go1.18.9 Git commit: 42c8b31 Built: Thu Dec 15 22:25:58 2022 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.14 GitCommit: 9ba4b250366a5ddde94bb7c9d1def331423aa323 runc: Version: 1.1.4 GitCommit: v1.1.4-0-g5fd4c4d docker-init: Version: 0.19.0 GitCommit: de40ad0

gordonwang0 commented 1 year ago

In your device twin:

"capabilities": {
        "iotEdge": false
    }

You will not be able to connect as an Edge device when the device in Hub is not an IoT Edge device. Please recreate this device as an IoT Edge device.

ArneJoris commented 1 year ago

@gordonwang0 : device 00E04CFFFE360D7B is a downstream device that is not an IoT Edge device. I am trying to connect to it as an IoTHub device through IoTHubDeviceClient via gateway device LoRaWAN-network-server-dev-02 that is an Edge device,

I am trying to follow the iotedge - how to authenticate downstream device guide.

gordonwang0 commented 1 year ago

Apologies, I misread your post the first time.

Have you configured the parent-child relationship between LoRaWAN-network-server-dev-02 (parent) and 00E04CFFFE360D7B (child) in Hub?

What happens if you directly use the parent's hostname as HostName and omit GatewayHostName?

HostName=LoRaWAN-network-server-dev-02;DeviceId=00E04CFFFE360D7B;SharedAccessKey=AKey=

ArneJoris commented 1 year ago

@gordonwang0 : yes, changing HostName in the connection string to be the gateway works:

python3
>>> from azure.iot.device import IoTHubDeviceClient  
>>> CONNECTION_STRING="HostName=LoRaWAN-network-server-dev-02;DeviceId=00E04CFFFE360D7B;SharedAccessKey=AKey="
>>> with open("/var/lib/aziot/certd/certs/aziotedgedca-86f154be7ff14480027f0d00c59c223db6d9e4ab0b559fc523cca36a7c973d6d.cer") as caFile:
...    CA_CONTENT=caFile.read()
...
>>> client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING,  server_verification_cert=CA_CONTENT)
>>> client.connect()
>>> client.get_twin()
{'desired': {'routerConfig': {'NetID': [1], 'DRs': [[10, 125, 0], [9, 125, 0], [8, 125, 0], [7, 125, 0], [8, 500, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [12, 500, 1], [11, 500, 1], [10, 500, 1], [9, 500, 1], [8, 500, 1], [7, 500, 1]], 'JoinEui': [['0000000000000000', 'FFFFFFFFFFFFFFFF']], 'region': 'US902', 'freq_range': [902000000, 928000000], 'nocca': True, 'nodc': True, 'sx1301_conf': [{'chan_multiSF_1': {'enable': True, 'radio': 0, 'if': -200000}, 'chan_multiSF_4': {'enable': True, 'radio': 1, 'if': -300000}, 'chan_multiSF_0': {'enable': True, 'radio': 0, 'if': -400000}, 'chan_multiSF_5': {'enable': True, 'radio': 1, 'if': -100000}, 'radio_0': {'enable': True, 'freq': 909100000}, 'radio_1': {'enable': True, 'freq': 909800000}, 'chan_multiSF_7': {'enable': True, 'radio': 1, 'if': 300000}, 'chan_multiSF_6': {'enable': True, 'radio': 1, 'if': 100000}, 'chan_multiSF_3': {'enable': True, 'radio': 0, 'if': 200000}, 'chan_FSK': {'enable': True, 'radio': 1, 'if': 300000}, 'chan_Lora_std': {'spread_factor': 8, 'bandwidth': 500000, 'enable': True, 'radio': 0, 'if': 300000}, 'chan_multiSF_2': {'enable': True, 'radio': 0, 'if': 0}}], 'hwspec': 'sx1301/1', 'nodwell': True}, '$version': 4}, 'reported': {'Package': 'foo', '$version': 2}}
gordonwang0 commented 1 year ago

Upon looking at your devices in Hub, we see the exception: Microsoft.Azure.Devices.Common.Core.Exceptions.IotHubException: Edge device (id=00E04CFFFE360D7B) is not linked with edge device (id=LoRaWAN-network-server2).

Since the device twin of child seems to have the parentScopes and deviceScope set to the edge device, the reason could be that the generation id was changed for the Edge device. Please provide the twin for edge device so we can check deviceScope value.

ArneJoris commented 1 year ago

The device twin for IoT edge device "LoRaWAN-network-server2" :

{
    "deviceId": "LoRaWAN-network-server2",
    "etag": "AAAAAAAAAAE=",
    "deviceEtag": "NjIyMTc5OTY5",
    "status": "enabled",
    "statusUpdateTime": "0001-01-01T00:00:00Z",
    "connectionState": "Disconnected",
    "lastActivityTime": "0001-01-01T00:00:00Z",
    "cloudToDeviceMessageCount": 0,
    "authenticationType": "sas",
    "x509Thumbprint": {
        "primaryThumbprint": null,
        "secondaryThumbprint": null
    },
    "modelId": "",
    "version": 2,
    "properties": {
        "desired": {
            "$metadata": {
                "$lastUpdated": "2022-12-29T22:04:48.1198023Z"
            },
            "$version": 1
        },
        "reported": {
            "$metadata": {
                "$lastUpdated": "2022-12-29T22:04:48.1198023Z"
            },
            "$version": 1
        }
    },
    "capabilities": {
        "iotEdge": true
    },
    "deviceScope": "ms-azure-iot-edge://LoRaWAN-network-server2-638079482881198023"
}
gordonwang0 commented 1 year ago

The device twin for the parent looks OK, I don't notice any issues there.

In the child's device twin, I see that parentScopes lists the same device twice. AFAIK, this is not allowed. Could you edit the twin so that the parent is only listed once, then see if the connection string works?

Otherwise, if the connection string with HostName as the parent works, I recommend just using that.

gordonwang0 commented 1 year ago

Could you also try the original connection string (with GatewayHostName) again and confirm that it still does not work?

gordonwang0 commented 1 year ago

Please let us know if you need any more help with this. Closing issue.