Let's configure the mosquitto MQTT broker to use TLS security. There are a few steps needed for self-signed CA and certificates: - Generate a certificate authority certificate and private key. - Generate a server private key and certificate signed by the CA. - Distribute the CA certificate to the server and start mosquitto with the CA certificate and server private key and certificate. - Distribute the CA certificate to the client for server verification. - Start the client with the CA certificate. If client certificates are required, then: - Generate a client private key and certificate signed by the CA. - Start the client with the CA certificate and client private key and certificate. Assuming we are going to allow both server and client to verify each other, so we need to generate certificate and private key for both server and clients, below is the details: 1. Generate a certificate authority certificate and key. ``` # openssl req -new -x509 -days 1000 -keyout ca.key -out ca.crt Generating a 1024 bit RSA private key .....................................++++++ ..................++++++ writing new private key to 'ca.key' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:SE State or Province Name (full name) [Some-State]:GOT Locality Name (eg, city) []:GOT Organization Name (eg, company) [Internet Widgits Pty Ltd]:ATQTA Organizational Unit Name (eg, section) []:R&D Common Name (e.g. server FQDN or YOUR name) []:CA Email Address []: ``` 2. Generate a server key without encryption. (If you intend to use the key together with a server certificate, it might be convenient to avoid protecting it with a password, since that would mean someone would have to type in the password every time the server needs to access the key.) ``` # openssl genrsa -out server.key 2048 Generating RSA private key, 2048 bit long modulus .......................................................................+++ .................+++ e is 65537 (0x10001) ``` 3. Generate a certificate signing request to send to the CA. ``` # openssl req -out server.csr -key server.key -new You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:SE State or Province Name (full name) [Some-State]:GOT Locality Name (eg, city) []:GOT Organization Name (eg, company) [Internet Widgits Pty Ltd]:ATQTA Organizational Unit Name (eg, section) []:R&D Common Name (e.g. server FQDN or YOUR name) []:server Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: ``` the **Common Name** is importance here, it should be the domain name or IP address at least, since it will be verified during connection handshakes. 4. Send the server CSR to the CA, or sign it with your CA key: (requre the password for your CA key which you input when generate it) ``` # openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 1000 Signature ok subject=/C=SE/ST=GOT/L=GOT/O=ATQTA/OU=R&D/CN=server Getting CA Private Key Enter pass phrase for ca.key: ``` 5. Now we are done with the server key and let's generate a client key. ``` # openssl genrsa -out client.key 2048 Generating RSA private key, 2048 bit long modulus ..........................+++ .......+++ e is 65537 (0x10001) ``` 6. Generate a certificate signing request to send to the CA. ``` # openssl req -out client.csr -key client.key -new You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:SE State or Province Name (full name) [Some-State]:GOT Locality Name (eg, city) []:GOT Organization Name (eg, company) [Internet Widgits Pty Ltd]:ATQTA Organizational Unit Name (eg, section) []:R&D Common Name (e.g. server FQDN or YOUR name) []:client Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: ``` 7. Send the CSR to the CA, or sign it with your CA key: ``` # openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 1000 Signature ok subject=/C=SE/ST=GOT/L=GOT/O=ATQTA/OU=R&R/CN=client Getting CA Private Key Enter pass phrase for ca.key: ``` After all these steps above, you will get all the certificate files needed. Server side needs to provide ca.crt, server.crt and server.key for client to verify, and client side needs to attach ca.crt, client.crt and client.key when connect. ## Broker configuration The mosquitto broker config file (let's name it *mqtt.conf*) basically looks like: ``` user mosquitto listener 1883 protocol mqtt listener 8883 protocol mqtt cafile /home/mosquitto/certs/ca.crt certfile /home/mosquitto/certs/server.crt keyfile /home/mosquitto/certs/server.key listener 8884 protocol mqtt cafile /home/mosquitto/certs/ca.crt certfile /home/mosquitto/certs/server.crt keyfile /home/mosquitto/certs/server.key require_certificate true listener 8080 protocol websockets listener 8081 protocol websockets cafile /home/mosquitto/certs/ca.crt certfile /home/mosquitto/certs/server.crt keyfile /home/mosquitto/certs/server.key ``` **Note:** Make sure the folder containing the certificates and keys have the right permission and ownership. From the configuration, we have enabled unencrypted MQTT via 1883, encrypted MQTT via 8883, encrypted MQTT and require client certificates via 8884, unencrypted WebSockets via 8080, encrypted WebSockets via 8081. To start mosquitto broker with the customized config file: mosquitto -c mqtt.conf ### Clients with certificates Using command line mosquitto client: mosquitto_sub -h BROKER_IP -p 8884 -t +/# --cafile YOUR_PATH/ca.crt --cert YOUR_PATH/client.crt --key YOUR_PATH/client.key mosquitto_pub -h BROKER_IP -p 8884 -t dummy/test -m "basic" -r --cafile YOUR_PATH/ca.crt --cert YOUR_PATH/client.crt --key YOUR_PATH/client.key If using python client, set certs before connect: mqttc.tls_set(CA_CERTS, CERTFILE, KEYFILE) mqttc.connect(YOUR_BROKER_IP, PORT) If the client never need write access to the server, it is also fine to skip the client side certificates, then only ca certificate is needed: mosquitto_sub -h BROKER_IP -p 8883 -t +/# --cafile YOUR_PATH/ca.crt mosquitto_pub -h BROKER_IP -p 8883 -t dummy/test -m "basic" -r --cafile YOUR_PATH/ca.crt