Setting up ssl/tls with mosquitto - "A TLS error occurred" solution
-
After a comment in one of my other project threads, I decided to look into setting up a secure transport layer with my MQTT communication for IoT projects.
I ran into an initial problem that I wanted to post the solution so any others who may want to try this won't have to spend a lot of time like I did troubleshooting.
First I followed the guide on this link for setting up all the encrypted files.https://dzone.com/articles/mqtt-security-securing-a-mosquitto-server
If you follow all the commands you will have the required files.
I also have wireshark on my Mac so I also installed mqtt.fx so I could monitor the communication and look at the unencrypted verses encrypted communication.
So I added a password file to the mqtt broker then sent a connection request from mqtt.fx. Sure enough when you examine the packet, you can see the username, password, topic and message data in plain text.
So out of the box mqtt is fine for testing but not secure over the long haul, especially if you want to connect to your network from the outside.
Next I followed the guide and set up the mqtt broker to use ssl/tls on port 8883 as suggested.
Then I hit a wall, I got an error when trying to just pub/sub on the local host "A TLS error occurred" is the error I got when running both mosquitto_pub and mosquitto_sub to test the connection.
I was able to both pub/sub from mqtt.fx and see that the broker was working but it has to work locally or my micropython code won't work.
The solution was in an answer when setting up the .crt file, there are a bunch of quesitons that you answer and for one of them I should have used a known host in my host file, the CN or Common Name question requires a valid entry so I added the local IP address and a host name that I created for it. A TLS error occurred.
Below is what it looks like with one of the mosquitto commands.
mosquitto_pub -p 8883 --cafile ./certs/mosq-ca.crt -t data -m "this is a test" -u Thing01 -P Thing01 -d -h mos_brokerAs you can see from the entry above, I have a username, password and the host is listed in my /etc/hosts file. This was not explained in the example setup but when you look at his answers he uses a valid host name.
The answer I found in another link on how to set up ssl/tls and at the bottom the author explained what the error was.
This is the link to that one if you are interested.
https://openest.io/en/2020/01/03/mqtts-how-to-use-mqtt-with-tls/
-
@Carey-Capaldi So after getting mqtt.fx on the mac working with my onion omega broker running ssl/tls I ran into a slight snag. I can't find any good micropython examples on how to set up the MQTTClient() call properly. I am still looking and when I find it and get it to work, I will post to this thread.
-
So with some further testing I had to do the following. ( the conf info is from the setup link, I haven't played with those settings much but these worked)
The mosquitto conf :port 1883
allow_anonymous false
password_file /etc/mosquitto/passwords.txt
log_type informationlistener 8883
protocol mqtt
cafile /root/py/mqSecurity/certs/mosq-ca.crt
certfile /root/py/mqSecurity/certs/mosq-serv.crt
keyfile /root/py/mqSecurity/certs/mosq-serv.keyUsing Wireshark to capture the conversation, when we use port 8883 I cannot see the username and password in the message like I did when I used port 1883 so encryption seems to be working.
What I had to do in the micropython client is summarized below:
I set the following variables - remember the server name had to be in the hosts file when I created the ssl keys and certs.
SERVER = "mos_broker"
PORT=8883
USER = "Thing01"
PASSWORD = "Thing01"
SSL_PARAMS = {"ca_certs":"./certs/mosq-ca.crt"}
TOPIC = "data"For the client connection I used the following:
c = MQTTClient("OmegaDashD2E2", user=USER, password=PASSWORD, server=SERVER, ssl_params=SSL_PARAMS)(if anyone is interested in the full code, contact me and I can send it however I got it from the MQTT.simple example on the git page)
So this seems to work fine, and can handle the encrypted data sent/received from my mac however I found the following behavior.
NOTE:
I could not remove port 1883 from the config file and when a client sends an unencrypted post to port 1883, the subscriber also sees that and prints it. I see the same behavior in mqtt.fx subscriber so it may be mosquitto broker behavior.What his means is that any connection to that port (1883) may expose usernames, passwords and topics.
I couldn't force the micropython subscriber to use only port 8883, I keep getting errors about too many parameters being sent to the MQTTClient() back end code.
So for security, do not use port 1883 and your username/password along with the topic should be hidden from any general snooping.I will test out publishing from the Omega in the future.
-
@Carey-Capaldi
Just modified one of my scripts for publishing a button press on the OmegaDash. It works fine, just substitute the MQTTClient call using the same string as above.Have fun.