MQTT Binding and SSL

did you fix your JKS?

In which stage/config file? Please be specific.

i was very specific :slight_smile: (I quoted your previous post where you reported that you were getting an error during the keytool import)… did you fix that step?

Yes. I fixed it. Otherwise, I couldn’t continue this tutorial.

edit… I can’t see something wrong

First, I did exactly what this said. And then I followed this tutorial.

It would be great, if you helped me fix this issue.

Here is an error to fix: “-keystore.jsk” is not a valid parameter, probably “-keystore keystore.jsk” should be used

Hello,

Maybe someone have example how to configure mqtt client with TLS?

From Command prompt i use this string:
mosquitto_sub -h eu.thethings.network -t ‘#’ -u ‘my_user’ -P ‘ttn-account-v2.mypassword’ -v --cafile mqtt-ca.pem -p 8883

Maybe i can get help how to configure .cfg file?

Ed

Is this still a thing with this binding in the current OpenHab2 release?

I have used this post and adapted where necessary to add the public and self-signed certificate of my Hue v2 bridge to be able to use http actions to control certain parts directly from rules.

How to retrieve Hue v2 certificates

One note regarding:

sudo keytool -import -alias myopenhab -file addtrustexternalroot.cert -storetype JKS -keystore.jsk

which should read

sudo keytool -import -alias myopenhab -file addtrustexternalroot.cert -storetype JKS -keystore truststore.jks

Furthermore, every certificate you add to the truststore should have its own alias. As my bridge apparently still has a self-signed certificate I added both the selfsigned one, as well as the certificate from the hue developer website.

Unfortunately, after adding the “-Dcom.ibm.ssl.=” items to setenv (in my case in an OH3 environment), and restarting openhab service, “systemctl status openhab” complains:

Dec 14 20:32:01 openhabpi karaf[1737]: /usr/share/openhab/runtime/bin/karaf: 116: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.keyManager=SunX509: not found
Dec 14 20:32:01 openhabpi karaf[1737]: /usr/share/openhab/runtime/bin/karaf: 117: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.contextProvider=SunJSSE: not found
Dec 14 20:32:01 openhabpi karaf[1750]: /usr/share/openhab/runtime/bin/karaf: 118: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.keyStore=/etc/keystore.jks: not found
Dec 14 20:32:01 openhabpi karaf[1737]: /usr/share/openhab/runtime/bin/karaf: 119: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.keyStorePassword=REDACTED: not found
Dec 14 20:32:01 openhabpi karaf[1737]: /usr/share/openhab/runtime/bin/karaf: 120: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.keyStoreType=JKS: not found
Dec 14 20:32:01 openhabpi karaf[1737]: /usr/share/openhab/runtime/bin/karaf: 121: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.keyStoreProvider=SUN: not found
Dec 14 20:32:01 openhabpi karaf[1751]: /usr/share/openhab/runtime/bin/karaf: 122: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.trustStore=/etc/truststore.jks: not found
Dec 14 20:32:01 openhabpi karaf[1737]: /usr/share/openhab/runtime/bin/karaf: 123: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.trustStorePassword=REDACTED: not found
Dec 14 20:32:01 openhabpi karaf[1737]: /usr/share/openhab/runtime/bin/karaf: 124: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.trustStoreType=JKS: not found
Dec 14 20:32:01 openhabpi karaf[1737]: /usr/share/openhab/runtime/bin/karaf: 125: /usr/share/openhab/runtime/bin/setenv: -Dcom.ibm.ssl.trustStoreProvider=SUN: not found

And my time has run out to troubleshoot any further before going to bed. So anyone who knows from the top of its head what should be the right way to add to setenv, feel free. Otherwise I will continue troubleshooting the issue (and searching the forum) at a later time and report back here. :slight_smile:

the existing list is enclosed between double quotes on both ends. Die you add the addtional items to the list by adding them between the double quotes ( which should be ok ) or did you add 'em after the existing last entry ( which I believe you did ) ?

I found that out yesterday when troubleshooting a bit more, but this did not work for me either (yes it got me a step further but still can’t connect). Now added them to the java cacerts keystore and that helps, eccept I apparently need to add a “san” as the bridge has no hostname, only an ip.

Was thinking of making a little guide as a new topic, when everything works out as I intend :slight_smile:

Hello,
very interesting thread that I am trying to use to get my openhab 3.4.0 (running on an odroid C4, a Raspberry Pi alternative I was able to buy) talking to an mqtt-server running somewhere else (a server outside my home running many things, including a mosquitto and owntracks).

I configured this external mqtt server to require TLS and use certificates (see below for the configs). From my odroid machine, where OH runs, I can connect to this mosquitto:

mosquitto_sub -h server.X.Y -t \# -d -p 8883 --cafile mosquitto_ca.crt --cert openhab.crt --key openhab.key

I then followed the steps outlined in the walkthrough and seem to get very far, but in the end, when in the website UI I enter the information for connecting (again, see below) I get a Java unhandled exception:
“javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure”

I am pretty sure the reason is that only the ca is passed, and not the client key and certificate that I use to authenticate clients (since I added only the ca certificate to the truststore).

In 2018 in the thread it mentions:

However, like I said before, I don’t think openHAB supports client certificates so I’m pretty sure that openHAB can’t connect to a listener that has require_certificate true. It can only check whether the server’s cert is trusted based on the CA being in the trust store.

So: is this still the case ? Is there no way to pass my client key/certificate ?
Does this mean only user/password is supported for security ?

My configs:

Mosquitto server:

conf.d/owntracks.conf

per_listener_settings true

listener 1883 localhost
allow_anonymous false
password_file /etc/mosquitto/passwordfile

listener 8883
tls_version tlsv1.2
require_certificate true
use_identity_as_username true
cafile /etc/mosquitto/certs/mosquitto_ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key

OH server:

Generated the stores as follows, importing the ca file from my mosquitto server:

# keystore:
sudo keytool -genkeypair -alias odroid -keyalg RSA -keystore /etc/ohkeystore.jks -storetype PKCS12 
# truststore:
sudo keytool -import -alias owntracksca -file /etc/mosquitto_ca.crt -storetype PKCS12 -keystore /etc/ohtruststore.jks

/usr/share/openhab/runtime/bin/setenv

export JAVA_OPTS="${JAVA_OPTS}
  -Dopenhab.home=${OPENHAB_HOME}
  -Dopenhab.conf=${OPENHAB_CONF}
  -Dopenhab.runtime=${OPENHAB_RUNTIME}
  -Dopenhab.userdata=${OPENHAB_USERDATA}
  -Dopenhab.logdir=${OPENHAB_LOGDIR}
  -Dfelix.cm.dir=${OPENHAB_USERDATA}/config
  -Djava.library.path=${OPENHAB_USERDATA}/tmp/lib
  -Djetty.host=${HTTP_ADDRESS}
  -Djetty.http.compliance=RFC2616
  -Dnashorn.args=--no-deprecation-warning
  -Dorg.apache.cxf.osgi.http.transport.disable=true
  -Dorg.ops4j.pax.web.listening.addresses=${HTTP_ADDRESS}
  -Dorg.osgi.service.http.port=${HTTP_PORT}
  -Dorg.osgi.service.http.port.secure=${HTTPS_PORT}
  -Dcom.ibm.ssl.trustManager=SunX509
  -Dcom.ibm.ssl.keyManager=SunX509
  -Dcom.ibm.ssl.contextProvider=SunJSSE
  -Dcom.ibm.ssl.keyStore=/etc/ohkeystore.jks
  -Dcom.ibm.ssl.keyStorePassword=ReplaceWithYourOwnPassword
  -Dcom.ibm.ssl.keyStoreType=PKCS12
  -Dcom.ibm.ssl.keyStoreProvider=SUN
  -Dcom.ibm.ssl.trustStore=/etc/ohtruststore.jks
  -Dcom.ibm.ssl.trustStorePassword=ReplaceWithYourOwnPassword
  -Dcom.ibm.ssl.trustStoreType=PKCS12
  -Dcom.ibm.ssl.trustStoreProvider=SUN"

Hello,

Following up on my previous post for completion, since I got things to working but without requiring client certificates. Adding this config for completeness in case somebody would wonder later on.

Works like a charm now, and I was able to have presence detection up-and-working (cellphones running owntracks, pushing to the mqtt server, openhab connecting to that server and capturing the ‘enter’ and ‘leave’ events to my home). Works more reliable than the icloud binding that did something similar (since that only checks every 5 minutes).

This is the updated mosquitto config file on the external server:

per_listener_settings true

# local connections without TLS (for eg owntracks)
listener 1883 localhost
allow_anonymous false
password_file /etc/mosquitto/passwordfile

# external connections use TLS + username/passwords
# using own generated certificates and not letsecrypt
# so they do not expire and need to be reinstalled ...
listener 8883
allow_anonymous false
password_file /etc/mosquitto/passwordfile
tls_version tlsv1.2
log_dest syslog
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
#certfile /etc/letsencrypt/live/your.own.server/cert.pem
#cafile /etc/letsencrypt/live/your.own.server/chain.pem
#keyfile /etc/letsencrypt/live/your.own.server/privkey.pem

Apart from filling in the username and passwords in the PaperUI for the MQTT broker thing no other changes were necessary compared to previous post.

Interesting, can you confirm that the communication is actually happening with TLS? I’m not entirely sure that simply telling mosquito what version of TLS to use would actually force it to use TLS. Also, what is the purpose of setting the three certs if you are not using them?

I wondered about that myself, and I am not sure whether the actual connection is now secured or not, and do not quite know how to check.

This is what I tried, maybe somebody knowledgeable can shed more light (and I am willing to do any more experiments):

The following works, passing the username/password and certificate:

$ mosquitto_sub -h <my.nifty.server> -t /# -d -p 8883 --cafile ca.crt -u <user> -P "<niftyPassword>"
Client mosq-sDSXbSmsNoG8QufXcu sending CONNECT
Client mosq-sDSXbSmsNoG8QufXcu received CONNACK (0)
Client mosq-sDSXbSmsNoG8QufXcu sending SUBSCRIBE (Mid: 1, Topic: /#, QoS: 0, Options: 0x00)
Client mosq-sDSXbSmsNoG8QufXcu received SUBACK
Subscribed (mid: 1): 0
[connected]

Only giving username/password, without certificate, fails:

$ mosquitto_sub -h <my.nifty.server> -t /# -d -p 8883 -u <user> -P "<niftyPassword>"
Client mosq-ubw0DEAdP3GQi2zNBn sending CONNECT
Client mosq-ubw0DEAdP3GQi2zNBn sending CONNECT
Client mosq-ubw0DEAdP3GQi2zNBn sending CONNECT
[repeats but never connects]

For completeness, but as expected, only passing certificates without user/passwords also fails in this configuration (this is what I had before, requiring certificates for TLS and also using them for authentication):

$ mosquitto_sub -h <my.nifty.server> -t /# -d -p 8883 --cafile ca.crt --cert openhab.crt --key openhab.
key
Client mosq-0xpaQtzvQYSeGfrjs8 sending CONNECT
Client mosq-0xpaQtzvQYSeGfrjs8 received CONNACK (5)
Connection error: Connection Refused: not authorised.
Client mosq-0xpaQtzvQYSeGfrjs8 sending DISCONNECT
$

So, in summary, the authentication is done with user/password and the certificate is needed but I have no idea if it is used, and at what moment the connection is done over TLS.

A long story to tell you that I do not quite know :wink:

use a network sniffer like wireshark to listen on MQTT traffic. If the complete communication is visible in clear text it is not encrypted. If it is encryted you only will be able to observe the handshake and certificate exchange everything else should be encrypted then.

1 Like

@ikke42

I agree with @Wolfgang_S - the only way you are ever going to know for sure if to use wireshark. A quick ddg search for wireshark MQTT gave a bunch of examples to do this. I liked this one, while it doesn’t go through the nuts/bolts of using wireshark, it shows you what you need to look for:

1 Like

Hah, long time since I used Wireshark :wink:

I can confirm that the data sent is indeed encrypted (also the username/password, as well as all other subsequent data).

So it seems to be working: openhab connects to external mqtt server over TLS with username/password authentication.

2 Likes