I have a question with regards to MQTT broker security. I’ve set up my local broker to use TLS using a self-signed certificate.
How do clients receive messages securely if they don’t have their own certificates? Don’t both client and server have to exchange a private key to communicate etc?
Not necessarily. You can certainly set it up that way. But the way you have it set up now, the clients get an assurance that the are talking with the broker and not some imposter. The broker doesn’t care whether the clients are imposters or not, so all the encryption gets set up between the two using the server’s keys. Only if you need stronger authentication (i.e. the server needs more than just username and password to authenticate the clients) do the clients need their own certificates.
It’s just like going to an https web site. The sever doesn’t know or care who you are to set up the encryption between you and it. But you care that you are talking to your bank’s website instead of an imposter before you send it your username and password, which the server used to trust you are who you say you are.
The keys are really only used to negotiate a session key which is then used to encrypt the actual data and only the server’s keys are needed. Thus all the communication is encrypted and the clients have assurance they are talking to the correct broker but the broker has no assurance outside of username and password that they are talking with a known client.
If you are doing this on your lan, this is more than sufficient security. If you are exposing your broker to the internet, you might consider configuring it to require client certificates as well.
If you want added security, you can create client certificates and configure the broker to only accept connections with clients that present a trusted certificate.
I will be setting up Own Tracks soon for my automation and I intend to run the TLS through Nginx and have the broker running unencrypted within my home network. I plan to use client certs and Nginx has examples showing how to have the CN in the cert be required to match the clientID as another layer of security. I’m also going to use a separate broker for these outside connections than the one running most of my automation so that they are compartmentalized.
I hadn’t thought of it but perhaps some of this might be useful to the community. If any of it interests you, keep an eye out for me posting a guide in the next few weeks.
Using OwnTracks with MQTT to integrate with openHAB is considered deprecated. The preferred approach is through the REST API and using the GPSTracker Binding.
Is that as secure, given it uses basic auth only to authenticate through Nginx?
It’s hard to answer because “as secure” is kind of vague.
Assuming you have properly set up nginx the connection is being done using HTTPS. Thus one has presumably purchased or obtained a trusted certificate from LetsEncrypt or the like. That will give you the same encryption on the communication and the same assurances to the client (OwnTracks) that it’s talking with your actual server and not some impostor. So far we have the exact same security set up between MQTT and HTTPS.
Once the secure channel is established, the client authenticates with the server using username and password. Again, assuming that client certificates are not in use, we have the same security setup between MQTT and HTTPS.
In the nginx case we have a proxy between the client (OwnTracks) and the destination (openHAB). The same is true for the MQTT case (i.e. the broker). The communication between the proxy and openHAB may be secure (i.e. using port 8443 instead of 8080 for https, the internal TLS port on the broker) or may not be secure. Here too I see no fundamental difference between the two.
In either case, the security is pretty much identical and the only difference is the application layer protocol (i.e. HTTP versus MQTT). And if you think about all the websites you interact with on a day to day basis, it’s pretty much this same pattern. The client connects to a server. The server uses it’s certificates to negotiate a session key and set up a secure communication channel with the client. Then the client authenticates itself using username and password over that secure channel. Gmail, your back websites, Facebook, etc all use this same pattern.
And, in either case, if you want to have better authentication for the clients, you can configure the broker to only accept connections from clients that possess a trusted certificate, and so can nginx (I’m actually just presuming this, I know it’s possible with HAProxy and Apache). In that case, in addition to or instead of username and password, the server will present a challenge that the client needs to respond to using the client’s key pair to verify that it’s a trusted client.
Indeed it’s just the client authentication that would be different, and yes Nginx can do all of that. Sounds to me like it’s not worth the trouble since I’m only using basic auth on my openHAB front-end.
Thank you so much for that explanation
Good luck. I look forward to reading about your experience.
If you are looking for write-up about offloading MQTT TLS to Nginx it might be a while. I’m going the basic auth route for owntracks so I don’t have a need for MQTT outside my network at this time.