Need working example for openHAB MQTT over TLS

I thought the keystore defined in the subfolder of hopenhab would have taken care of that. Maybe I’m wrong

-Dcom.ibm.ssl.trustManager=SunX509
-Dcom.ibm.ssl.keyManager=SunX509
-Dcom.ibm.ssl.contextProvider=SunJSSE
-Dcom.ibm.ssl.keyStore=/etc/keystore.jks
-Dcom.ibm.ssl.keyStorePassword=keystore_password
-Dcom.ibm.ssl.keyStoreType=JKS
-Dcom.ibm.ssl.keyStoreProvider=SUN
-Dcom.ibm.ssl.trustStore=/etc/truststore.jks
-Dcom.ibm.ssl.trustStorePassword=truststore_password
-Dcom.ibm.ssl.trustStoreType=JKS
-Dcom.ibm.ssl.trustStoreProvider=SUN

Next step would be looking at the certificate and public key fields I mentioned above in the text config of the broker. Need to see if I can extract the key and the cert and push it there as a string

Mh actually a good point. Iremember creating the keystore but not importing anything. I-ll have a look at that

Yes, you need to import your self-signed x509 keys into the java keystore in /etc/keystore.jks. I haven’t been able to successfully do this yet.

In paperUI, the Certificate Hash and Public Key Hash are not user writable fields, they are related to these:

It is a security mechanism to try to prevent MitM attacks. You get a hash from the broker the first time you connect and any changes to this hash would signal the broker you are trying to connect to has changed.

OK, so I just did a test here to try to prove out if you can connect to an MQTT broker with only username/passwd credentials.

So, first I changed my mosquitto config to remove the

require_certificate true

and add a pointer to the password file

 password_file /etc/mosquitto/passwd

so my conf now looks like this:

per_listener_settings true
  
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
log_type error
log_type notice
log_type information
log_type debug

listener 8883
#ssl settings
cafile /etc/mosquitto/ca_certificates/ca.crt
keyfile /etc/mosquitto/certs/server.key
certfile /etc/mosquitto/certs/server.crt
#client certifcate settings
#require_certificate true
password_file /etc/mosquitto/passwd
use_identity_as_username true

So, I attempted to connect with a uname/passwd but to port 8883 and saw the following:

mosquitto_pub -h 192.168.1.200 -p 8883 -i "test" -u uname -P "passwd'" -d -t "test/testing" -m 'foobar'

I got the following in my mosquitto log:

1609639233: Client connection from 192.168.1.50 failed: error:1408F10B:SSL routines:ssl3_get_record:wrong version number.

Googling for this error, I found this:

To get mosquitto_pub to attempt to start a SSL connection you need to provide either --cafile or --capath that points to the location of the CA certificates to verify the broker.

Without these options neither mosquitto_pub or mosquitto_sub will not attempt to start a SSL session and instead try and connect with a normal unencrypted MQTT connection

From here: openssl - mosquitto_pub gives the following error: 1408F10B: SSL routines: ssl3_get_record: wrong version number - Stack Overflow

So, since there is no global repo for self signed certs, the only way to communicate with the broker is to have a CA cert that was sued to sign the server’s cert. Makes sense.

OK, so then I tried only supplying the CA cert but still using name/passwd for authentication:

 mosquitto_pub -h 192.168.1.200 -p 8883 -i "test" --cafile /home/tom/ssl/ca.crt -u uname -P "passwd'" -d -t "test/testing" -m 'foobar'

Now I get the same error you are seeing in openHAB in my mosquitto log:

1609639323: OpenSSL Error: error:1417C0C7:SSL routines:tls_process_client_certificate:peer did not return a certificate.

Googling around, I don’t see much information about logging into TLS MQTT broker with a username/passwd, so I think my hypothesis was incorrect. Even if this was correct, you would still need to import at least the CA cert into the java keystore. So seems like we are back at the same step. We need to import rhe CA cert, the client cert and key into the java keystore in order to get openHAB to connect to a mosquitto broker over TLS.

just a quickie.
I can follow your steps and also I cannot get mosquitto_pub to work.

pi@raspi00:~ $ mosquitto_pub -h 192.168.1.220 -p 8883 -i “test” -u edolis --capath /home/pi/newSSL -P ****-d -t “test/testing” -m ‘foobar’
Client test sending CONNECT
OpenSSL Error[0]: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
Error: A TLS error occurred.

but this to me seems a problem of mosquitto_pub. If I use a windows client things work for me:



and also OH fares good

So it looks like it’s a problem of mosquitto_pub. Frankly, not even sure I’ll spend time to try to understand why…
here is my mosquitto.conf

#listener 1883
#allow_anonymous false
log_type all
log_type error
log_type warning
#log_type notice
#log_type information
if set to true, client connection and disconnection messages will be included
#in the log.
connection_messages true
log_timestamp true
allow_anonymous false
password_file /etc/mosquitto/passwd
ssl certificates
listener 1883
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
cafile /home/pi/ca.crt
client certifcate settings
#require_certificate false
#use_identity_as_username true

EDIT:
I have investigated a little why mosquitto_sub fails

pi@raspi00:~ $ mosquitto_sub -h 192.168.1.220 -p 8883 -u edolis -P *** -t test --cafile /home/pi/newSSL/ca.crt
Error: A TLS error occurred.

in the log I read

1609669023: New connection from 192.168.1.220 on port 8883.
1609669023: OpenSSL Error[0]: error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error
1609669023: Socket error on client , disconnecting.

so it’s a tlsv1 related error. Interesting

well, I did that using dpkg-reconfigure ca-certificates pi 3 - Entrusted Certificates installation - Raspberry Pi Stack Exchange
as for the keystore, I followed this Import an SSL certificate and private key
So for me it was

pi@raspi00:/etc $ sudo openssl pkcs12 -export -in edolis.client.crt -inkey edolis.client.key -name openHabClient -out edolis.client-PKCS-12.p12
Enter pass phrase for edolis.client.key:
Enter Export Password:
Verifying - Enter Export Password:
pi@raspi00:/etc $ sudo keytool -importkeystore -deststorepass xxxxx -destkeystore edolis.keystore.jks -srckeystore edolis.client-PKCS-12.p12 -srcstoretype PKCS12
Importing keystore edolis.client-PKCS-12.p12 to edolis.keystore.jks…
Enter source keystore password:
Entry for alias openhabclient successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled

but still no joy

1609671308: OpenSSL Error[0]: error:1417C0C7:SSL routines:tls_process_client_certificate:peer did not return a certificate
1609671308: Socket error on client , disconnecting.

Now, thinking out of the box, I tried using the win client MQTT explorer, where I can manually load ca.crt, client.crt and client.key. So I can be sure certificates are loaded in the client properly.
Trying to connect I get, client side:


mosquitto side I get absolutely nothing, as if it did not get through something or the certificates have issues. and need to figure out what.
And if I cannot make a client external to mosquitto work TSL with certificates only, I think there is little point banging owns head against openhab.

looks like also the core example from Creating and Using Client Certificates with MQTT and Mosquitto does not work on raspberry for me, so I asked Steve who’s an authority on mosquitto and let’s see what he says

update for anyone interested
a) if your TSL certificate-only set-up does not seem to work, verify the DN of the server certificate (running Mosquitto) is matching the hostname of the server.
b) I think probably TSL certificate-only cannot be run on OH3 because there is no way to specify the protocol (ssl instead of http/https). Posted a bug/feature request for this
c) a workaround to make compatible the use of TSL certificate based MQTT server and OH3 with no TSL implemented could be opening a new listener on a specific port and using ACL to restrict access only to the user of the openHAB instance. And make the username/password arcane enough to reduce the risk to acceptable level. Need to try this.

I’m confused about this. According to Wikipedia, MQTT is a protocol that runs over TCP/IP, which can use TLS as an encryption layer if desired. I don’t see anything here about MQTT over http/https.

It also lists both MQTT and HTTP/HTTPS both as application layer protocols, so it seems there would be no such thing as MQTT over HTTP/HTTPS.

A quick google search for “mqtt over http” shows a lot of MQTT vs HTTP hits, but I don’t see anything about MQTT using HTTP. Maybe I’m misunderstanding. Can you explain a bit more?

Another work around is to have two MQTT brokers - one is your main broker and the other is on the machine running OH3 that cannot connect to the main broker over MQTT/TLS. Make the OH3 instance connect to its localhost MQTT broker and set up a bridge between the two brokers that uses TLS. I haven’t dont it yet, but I’ve read about this bridging concept a few places. Essentially the two brokers keep each over in sync on all topics.

Honestly, not quite. I have not looked into it. I’m not going tofight the theoretical side too - I just see that the OH2 implementation had a “black box” ssl stamp which made it work, that’s enough for me. If in the underlying implementation they use really that ssl or any other protocol replaced during the coding chain, I don’t really mind (even if it’s messy) . Too many variables for me- coding, Java, openSSL.

I considered that, using bridging. I already use bridging to a MQTT server over the internet.
But two brokers running on the same host? Seems a sure way to get a complicated life to me.
Unless you have two machines, which I haven’t got - as you seem t suggest. In any case, the broker communicating with OH has exactly the same exposure.
Yes, would be a safer approach for DOS attacks: the broker exposed to OH just dies, the other keeps going.
But as you know, you can restrict access to a specific listener to localhost. So having a OH connection with arcane username/encripted pwd secured with SSL using a CA certificate and accepted only from client localhost is safer than a sterile room to me. If your localhost is compromised, everything is lost.

Sorry - yes - this thread is about using TLS to encrypt MQTT communication over ethernet between two servers. There is little to no reason to use TLS to connect to a broker from a client on the same machine (localhost). You can easily configure your broker to accept connection from localhost with no / or password authentication, but require TLS for anything coming from outside of localhost.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.