How to connect X.509 authenticated downstream device using azure python sdk version 2 to azure edge enabled gateway - azure-iot-hub

With the now deprecated azure-iot-python-skd version 1 it was possible to connect a downstream device using X.509 authentication to a transparent iotedge enabled gateway by setting the connection string like this:
HostName=<edge device hostname>;DeviceId=<device_id>;x509=true
And then set the certificates by using set_option("TrustedCerts" ...), set_option("x509certificate", ...) and set_option("x509privatekey", ...)
How can this be done with the new version 2 sdk?
I could not figure out how to do it using create_from_x509_certificate(...) or create_from_connection_string(...).

please try the following where you pass in your root_ca_cert as a string:
Create instance of the device client using the connection string:
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string=YOUR CONNECTION STRING,server_verification_cert=YOUR ROOT CA AS STRING)
await device_client.connect()

create_from_connection_string will not work in this case. You need to use create_from_x509_certificate as below:-
self.device_client = IoTHubDeviceClient.create_from_x509_certificate(
x509=x509,
hostname=hostname,
device_id=device_id,
server_verification_cert=root_ca_cert,
gateway_hostname=gatewayHostname
)
Refer this ticket which is the bug fix done by MS team

Related

401002 CA certificate not found - SDK - Microsoft.Azure.Devices.Provisioning.Client

OS - Windows 10
.net Environment - .net core 2.1
SDK - Microsoft.Azure.Devices.Client - 1.21.0
Microsoft.Azure.Devices.Provisioning.Client - 1.4.0
Microsoft.Azure.Devices.Provisioning.Transport.Amqp - 1.1.9
Microsoft.Azure.Devices.Provisioning.Transport.Http - 1.1.6
Microsoft.Azure.Devices.Provisioning.Transport.Mqtt - 1.1.8
Description of the issue
I'm trying to connect a simulated device (.net core console app) to IOT hub via azure Device Provisioning Service. This is based on x.509 cetificates (root+ intermediate certificate).
I created the enrolment group ok, then uploaded the root certificate and completed verification.
After that generated the device certificate from root certificate and tried to connect to IOT hub using sample code from below link:
https://github.com/Azure-Samples/azure-iot-samples-csharp/tree/master/provisioning/Samples/device/X509Sample
After having all setup when I tried to connect to IOT bub I'm getting below error, tried all protocol - Amqp,Http,Mqtt...
Microsoft.Azure.Devices.Provisioning.Client.ProvisioningTransportException
HResult=0x80131500
Message={"errorCode":401002,"trackingId":"408d5ad7-aa7c-45a1-b19a-e4af41ccf54b","message":"CA certificate not found.","timestampUtc":"2019-08-23T09:17:53.762099Z"}
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
Below is the input to device client along with certificate:
private static string s_idScope = "0ne00074417";
private const string GlobalDeviceEndpoint = "global.azure-devices-provisioning.net";
private static string s_certificateFileName = "simulateddevicecert.pfx";
Is there anything missing in the setup that is causing this error? Also is there any REST API exposed by azure DPS to register device? (instead of using Azure Devices/Client SDK)
As shown here,
please include the intermediate certificate as well in the certificate chain presented by the device.
The REST API docs for registering a device to DPS can be found here.
In my case error 401002 was caused by mismatched deviceId and CN field in certificate which device used to authenticate.
In my case, I used the wrong connection string.
I used the device connection string instead of the service connection string when trying to call a direct invoke method.
I'm posting this here, because this is among the first search results for the 401002 error, and there's no info on this check on the Azure doc websites.

Registering new devices to Azure IOT hub

Just simple question:
I have created a new Service bus, Event hub and some shared access tokens with all rights, but registering a new device with iothub-explorer fails to 'unauthorized' message in Azure.
[tuomas#raspberry ~]$ iothub-explorer login "HostName=mynew-iot.servicebus.windows.net;SharedAccessKeyName=mynewdevice-1;SharedAccessKey=NptRRzI9mhiXO2QKuhZq47iY24A7cbtxRpUDSQO5aSI=" --connection-string
Session started, expires Tue Apr 12 2016 20:02:13 GMT+0300 (EEST)
[tuomas#raspberry ~]$ iothub-explorer "HostName=mynew-iot.servicebus.windows.net;SharedAccessKeyName=device-1;SharedAccessKey=NptRRzI9mhiXO2QKuhZq47iY24A7cbtxRpUDSQO5aSI=" create dummydev
Error Unauthorized
Any toughts?
With Thanks,
~T
I don't know if it's on purpose or not but the connection string in the second command doesn't match the one in the first one: the SharedAccessKeyName is different. Maybe it's just that.
If it's not just that, due to the way it's named I'm under the impression that you are using a device connection string when you should be using the service connection string (with a policy name in the SharedAccessKeyName field, such as the iothubowner). Whatever the policy is it should have the permissions to read and write to the registry. Unless you named such a policy "mynewdevice-1" ? One simple way to debug this is to use the iothubowner policy and associated key since it has full permissions.
Last thing, if you're using the "login" command, you don't need to specify the connectionstring again in subsequent commands (except to receive messages sent by devices, since this is done on the event hubs endpoint).
Thanks, I have really messed these old and new portals.
After creating a new Service bus and event hub in new portal I can register my devices. The rest .... new question perhaps...
With thanks.

SignalR cannot connect to Azure Redis on SSL

I am currently hosting my redis cache server on Azure, and have signalR relying on it as the backbone using the following...
GlobalHost.DependencyResolver.UseRedis("Server",port,"password","eventKey");
This works find on port 6379 (non-SSL) but my chat app breaks when I try to connect to the SSL port (6380) of my Azure Redis server, and the hub is never started. What could be the cause of this issue? Or am I doing something wrong?
This is the error that appears on /signalr/connect in my browser
net::ERR_CONNECTION_RESET
You can try this:
GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration(connectionString, "YourServer"));
And connection string something like:
connectionString="yourNameHere.cache.windows.net,ssl=true,password=YourPasswordKey"
Make sure you are using SignalR built with StackExchange.Redis (latest is gratest ;)
I upgraded the signalr core library to version 2.2.3.0 and used the below syntax, works like a charm.
var redisServer = ConfigurationManager.AppSettings[Constants.RedisServer].ToString();
var redisServerPassword = ConfigurationManager.AppSettings[Constants.RedisServerPassword].ToString();
var connectionString = $"{redisServer},password={redisServerPassword},ssl=True,abortConnect=False";
GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration(connectionString, "APIIdentifierString"));
In case anyone else hits the issue, it seems that the default connection string provided by the Azure portal contains abortConnect=False.
Once I've removed that part, things started working for me.

3cx make call url for version 12

I am using 3cx version 11 on my machine. On version 11 they provide the api for making up the calls from your client machine to destination. There is no need to configure the devices, we just need to use the following URLto generate the calls:
http://:5000/ivr/PbxAPI.aspx?func=make_call&from=&to=&pin=
where pbx is the ip of the machine which got the 3cx.
Click here! for more info about the api.
As you can see it is mention on their website that this api is not available on version 12.
I need to ask that is there any alternative to generate the calls if some one is using version 12? Because most of the users now are using version 12, and as an admin I need to figure it out that how can I provide this facility to my clients who have installed version 12.
Zain,
Look into this alternative API from VoIPToys.
http://www.voiptoys.com/3cx-http-api-by-voiptoys
It will have similar syntax in a browser:
http://localhost:5505/MakeCall.aspx?ext=100&pin=1234&to=101
Or like this in C#
String url = "http://localhost:5505/MakeCall.aspx?ext=100&pin=1234&to=101";
// Call the API and receive result
using (WebClient client = new WebClient()) {
String result = Encoding.UTF8.GetString(client.DownloadData(url));
}

Worklight 6.0 application using SSL

Worklight 6.0.0, targeting iPad.
I have a simple demonstration application, no authentication at present. I am demonstrating use of reverse proxy. So I am building my application using the Build for Remote Server workaround and can see in xcode the correct server specification. I have some adapter calls, but for a particular demo scenario I also want to make an explicit call to
WL.Client.connect( ... );
If I use an http connection I see a request like this:
http://192.168.0.19/MyApp/apps/services/api/Work01/ipad/init
and it works just fine. If instead I use an SSL connection, as expected I see this
https://192.168.0.19:443/Infrabel01/apps/services/api/Work01/ipad/init
And I get the following error.
> [ERROR ] FWLSE0059E: Login into realm 'NullLoginModule' failed. The
> environment 'ipad' supports multiple versions, therefore you must
> request it with a version parameter.. [project Infrabel01] The
> environment 'ipad' supports multiple versions, therefore you must
> request it with a version parameter. [ERROR ]
> FWLSE0117E: Error code: 4, error description: AUTHENTICATION_ERROR,
> error message: An Error occurred while performing authentication using loginModule
> NullLoginModule, User Identity Not available. [project Infrabel01]
> [project Infrabel01]
That "request it with a version parameter" is intriguing. Is there some extra parameter I need to pass? Or is the overall implication that connecting over SSL requires authentication?
I had the same problem.
I have solved it by using the real IP address of the server in the WL app instead of using localhost:
When the emulator is running your app, press the Menu button.
Select to change your server URL
Remove "localhost" and use the IP address.
Accept and try again.
This fixed my problem.
Please make sure your Worklight server or proxy server is enabled SSL with certificate which signed by a trust public CA like Verisign. Worklight not support private CA certificate.