App functions sdk sample for MQTT with SSL

Hello.
I’d like to share the work I’ve done to enable SSL comunications inside the app-functions-sdk to send messages to MQTT. I’m a newbie to EdgeX and maybe this could help other newbies like me. My expected result was to send MQTT msgs from EdgeX to Mosquitto using SSL on the same machine running Ubuntu.

Before running Mosquitto I created self signed certificates with a nice script suite I’ve found on github. I had to modify one line of the script that was causing issues on Ubuntu, if you need it, my version is here: easy CA
My tree under /etc/mosquitto is
.
├── ca_certificates
│ ├── ca.crt
│ ├── ca.key
│ └── README
├── certs
│ ├── localhost.server.crt
│ ├── localhost.server.key
│ └── README
└── conf.d
├── default.conf
└── README

The default.conf contains these lines:

log_dest file /var/log/mosquitto/mosquitto.log
listener 8883
cafile /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/localhost.server.crt
keyfile /etc/mosquitto/certs/localhost.server.key
require_certificate true

I had to install the CA certificate used by Mosquitto on Ubuntu, otherwise I would get error “Unknown CA authority” when the client would try to connect to Mosquitto

I’ve cloned app functions sdk and modified the file simple-filter-xml-mqtt/main.go :

addressable := models.Addressable{
Address: “localhost”,
Port: 8883,
Protocol: “tcps”,
Publisher: “MyApp”,
User: “”,
Password: “”,
Topic: “test”,}

pair := transforms.KeyCertPair{
KeyFile: “user-localhost.client.key”,
CertFile: “user-localhost.client.crt”,
}

mqttSender := transforms.NewMQTTSender(edgexSdk.LoggingClient, addressable, &pair, mqttConfig, false)

I’ve also modified the file pkg/transforms/mqtt.go to NOT skip the certificate verification:

tlsConfig := &tls.Config{
ClientCAs: nil,
InsecureSkipVerify: false,
Certificates: []tls.Certificate{cert},
}

I’ve put the user certificate and key in the same folder where the source resides (this is bad but I still don’t know how to store and retreive credentials from the Vault)

My folder with the certificates looks like this:
simple-filter-xml-mqtt
│ ├── logs
│ │ └── simple-filter-xml-mqtt.log
│ ├── main.go
│ ├── res
│ │ └── configuration.toml
│ ├── simple-filter-xml-mqtt
│ ├── user-localhost.client.crt
│ └── user-localhost.client.key

After that I compiled and run simple-filter-xml-mqtt, run EdgeX, run the Device Virtual as explained here at point 5 (Run device virtual) and was able to see MQTT messages encrypted with Wireshark

Gianpaolo

It would be nice if you didn’t have to modify the functions in Go code in order to use MQTTS. Have you tried using https://github.com/edgexfoundry/app-service-configurable for this use case?

The example configuration.toml for that service has a section for the addressable for MQTT, but it doesn’t seem to expose TLS information like you needed to specify. See:

If the app-service-configurable could support your use case that would be ideal since others would be able to do this without writing any code or modifying the examples.

1 Like

hello Ian,
actually I didn’t know app-service-configurable. I had previously used cmd/export-distro/res/configuration.toml to add mqtt certificates. I will try now.

Gianpaolo

hello Ian,
it works and it’s very simple. The only point that i don’t know how to solve is this:
how to “tell” to pkg/transforms/mqtt.go to not skip certificate verification? Do you know if it is planned to add this field in the configuration too?

tlsConfig := &tls.Config{
ClientCAs: nil,
InsecureSkipVerify: false,
Certificates: []tls.Certificate{cert},
}

I have created an issue to add Skip Verify to mqttCofing settings and pipeline configuration for MQTT Send. This will allow it to be set from custom app service or from App Service Configurable Pipeline Configuration. Here is the issue:

1 Like

cool! :slight_smile:

Gianpaolo

AWESOME! Thx for doing this!

1 Like