cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - If community subscription notifications are filling up your inbox you can set up a daily digest and get all your notifications in a single email. X

Securing the Mosquitto MQTT Broker

No ratings
  1. Get MQTT (like mosquitto) operating with SSL - use http://rockingdlabs.dunmire.org/exercises-experiments/ssl-client-certs-to-secure-mqtt as your primary guide to building out your self-signed CA cert and your server cert and key. Simply follow their directions with the one caveat of setting IPLIST and HOSTLIST environment variables prior to executing the generate-CA.sh script. This will be necessary for hosted environments like AWS where the actual IP address of the system cannot be used to access the server from the internet. Put the external facing IP address in IPLIST and the external facing fully qualified domain name (FQDN) into HOSTLIST. If you have multiple usable ip addresses or hostname aliases, enclose them in quotes and separate them with spaces  (export IPLIST="1.2.3.4 5.6.7.8")
  2. Complete steps 1-3 in the instructions above. This is sufficient to get the MQTT traffic encrypted and use it with Thingworx. Do not proceed until you can make a mosquitto_pub and mosquitto_sub pass data using the --cafile option and get an error if you do not supply the --cafile option. Make sure you have a copy of the ca.crt file generated by the script above to reference in the commands. Note that it may be necessary to use the ip address rather than the FQDN.
    1. mosquitto_sub --cafile path/to/ca.crt -h ipaddr -t topic
    2. mosquitto_pub --cafile path/to/ca.crt -h ipaddr -t topic -m message
  3. Create an MQTT Thing in Thingworx based on the MQTT ThingTemplate.
  4. Create a property in the new thing for sending messages to the MQTT broker.
  5. In the configuration page for the new MQTT Thing, set the serverName, serverPort and check the useSSL checkbox.
  6. In the Property to MQTT topic mappings, create a publish entry that points to the property you created in the thing and set the topic to the mqtt topic on which you want to publish .
  7. The ca.crt file created in the above script is the certificate for a new Certificate Authority (self-signed, so not really official). Clients may have to import this certificate into their trusted CA Root store in order to make the encryption work.
  8. Add the ca.crt file from the mqtt broker system to a keystore file that will become tomcat's truststore (the list of CAs trusted by the server). See the Tomcat documentation if you need to configure https on tomcat as well. Create a new keystore if one does not already exist as a truststore.
    1. keytool -import -trustcacerts -file /path/to/ca/ca.crt -alias CA_ALIAS -keystore path/to/TrustStore -storepass mypassword).

Replace the CA_ALIAS with some identifying string like MyPrivateCertificateAuthority. It did not appear to care about the CA_ALIAS value used.

Replace path/to/truststore to point to the file that already exists or you want to create.

  1. Add the following to the CATALINA_OPTS for starting tomcat
    1. -Djavax.net.ssl.trustStore=path/to/TrustStore" 
    2. -Djavax.net.ssl.trustStorePassword=xxxx

Replace path/to/TrustStore with the pathname of the file you created / updated with keytool above.

Replace xxxx with whatever password you used in the keytool command above

  1. Restart tomcat.
  2. Check the mqtt Thing for its isConnected property. It should now be true. If it is not, then check the log files for mosquitto and for tomcat looking for SSL issues.
  3. Change the property value and see it appear in the output of a (properly constructed) mosquitto_sub --cafile path/to/TrustStore -t test somewhere.
Comments

Hi, I am able to perform steps till 7th point, I didn't find any key store where I can put the ca_cert file path. So where can I find Keystore in ThingWorx's Dashboard?

Sanket, you will have to create a keystore using the Java's keytool (Java 😎 as a trust store as mentioned

Sushant, I am doing all steps on web portal of ThingWorx, so please tell how can I use Java's keytool for that.

Thanks

If your Thingworx Tomcat instance is secured, look at the conf/server.xml file to see where it gets its cert or keystore files from. If they are text files, then you can reference those files from the exact same locations. If they are binary files, you have to use keytool and/or`     `      openssl commands to extract the cert and key files from that binary (see appsec - How can I export my private key from a Java Keytool keystore? - Information Security Stack Exchange). Put the extracted files anywhere you'd like that is not visible to any web server and reference them from there. I see no problem with leaving the extracted key and cert files in the same directory with the keystore files.

I haven't installed Foundation Server on my local machine, I am using the ThingWorx server provided on the web portal. So should I need to install ThingWorx's Foundation Server locally or on the cloud to make above changes (from step no 8)?

Hi I followed the steps suggested by you, even though I am unable to connect to the Broker. I see following logs in the broker log file,

1480508847: OpenSSL Error: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown

1480508847: OpenSSL Error: error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure

1480508847: Socket error on client <unknown>, disconnecting.

Did you change your connection string from mqtt://system:port or tcp://system:port to ssl://system:port? If you don't do that, you're not using the right protocol to establish the secure connection. The errors you got are basically the same as you'd see if you connect to an https server using http protocol.

Wher can I change this string? Please give me the file name.

It's not a file - it's how your client code references the MQTT server. You  have to be specifying something like mqtt://server:port or tcp://server:port and with a secure server, you have to specify the connection as ssl://server:port.

So find your connection string in your client code or config file and update it appropriately.

Version history
Last update:
‎Sep 15, 2016 09:26 AM
Updated by:
Labels (1)