When I started to experiment with MQTT it was pretty easy to find information on using SSL/TLS Certificates to encrypt communications with the broker. The OwnTracks project even provides a script to setup a certificate authority (CA) and sign the certificates. However the certificates are for the broker (server) and not the client.
I was less successful in finding easy to follow instructions for creating and using SSL certificates to authenticate MQTT clients. This exercise attempts to remedy that lack of instructions.Requirements
$ sudo apt-get install mosquitto ProcedureNOTE: This procedure assumes all the steps will be performed on the same system. 1. Setup a protected workspaceWarning: the keys for the certificates are not protected with a password. This is not the best practice, but it does make it easier to use them with daemons and embedded devices. It is important that you keep them secret. For this exercise we'll create and use a directory that does not grant access to other users. $ mkdir myCA 2. Setup a CA and generate the server certificatesDownload and run the NOTE: Before using this procedure in a production environment, you should probably customize the $ wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh . $ bash ./generate-CA.sh
Three of them get copied to the $ sudo cp ca.crt /etc/mosquitto/ca_certificates/ $ sudo cp myhost.crt myhost.key /etc/mosquitto/certs/ They are referenced in the # mosquitto.conf pid_file /var/run/mosquitto.pid persistence true persistence_location /var/lib/mosquitto/ log_dest file /var/log/mosquitto/mosquitto.log cafile /etc/mosquitto/ca_certificates/ca.crt certfile /etc/mosquitto/certs/myhost.crt keyfile /etc/mosquitto/certs/myhost.key After copying the files and modifying the mosquitto.conf file, restart the server:$ sudo service mosquitto restart You can verify the work to this point by using mosquitto_sub client:$ mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile ca.crt $SYS/broker/bytes/received 65 $SYS/broker/bytes/sent 67 $SYS/broker/bytes/received 130 $SYS/broker/bytes/sent 196 ^C $ The topics are updated every 10 seconds. If debugging is needed you can add the -d flag to mosquitto_sub and/or look at /var/logs/mosquitto/mosquitto.log .At this point you could try what I did and use $ openssl genrsa -out client.key 2048 $ openssl req -new -out client.csr \ -key client.key -subj "/CN=client/O=example.com" $ openssl x509 -req -in client.csr -CA ca.crt \ -CAkey ca.key -CAserial ./ca.srl -out client.crt \ -days 3650 -addtrust clientAuth The important argument is That's simple enough, but you will probably want to have a number of different client certificates. One per client is not unreasonable. So the attached script is a complement to $ bash ./generate-client.sh client2 5. ReconfigureChange themosquitto configuration to require client certificates by adding the require_certificate line to the end of the /etc/mosquitto/mosquitto.conf file so that it looks like this:# mosquitto.conf pid_file /var/run/mosquitto.pid persistence true persistence_location /var/lib/mosquitto/ log_dest file /var/log/mosquitto/mosquitto.log cafile /etc/mosquitto/ca_certificates/ca.crt certfile /etc/mosquitto/certs/SVE14A1HFXB.crt keyfile /etc/mosquitto/certs/SVE14A1HFXB.key require_certificate true Restart the server: $ sudo service mosquitto restart 6. TestThe $ mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile ca.crt Error: Protocol error Error: A TLS error occurred .Adding the $ mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile ca.crt --cert client.crt --key client.key $SYS/broker/bytes/received 65 $SYS/broker/bytes/sent 67 $SYS/broker/bytes/received 130 $SYS/broker/bytes/sent 136 ^C $ The second client certificates work too: $ mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile ca.crt --cert client2.crt --key client2.key $SYS/broker/bytes/received 130 $SYS/broker/bytes/sent 198 $SYS/broker/bytes/received 195 $SYS/broker/bytes/sent 269 ^C $ ConclusionUsing client certificates, when you can, provides another layer of security to your MQTT system. Now in addition to having an encrypted communications channel, the server will only accept connections with a properly signed certificates. There is still a lot of room for improving the security of your MQTT system, but encrypted communications is a good start. Follow-upContact me about this exercise by commenting on my Google+ post. |