Generating a private certificate authority to use TLS with Mosquitto
So far, we have been working with a Mosquitto server with its default configuration that listens on port 1883 and uses TCP as the transport protocol. The data sent between each MQTT client and server isn't encrypted. There are no restrictions to subscribers or publishers. If we open the firewall ports and redirect the ports in the router, any MQTT client that has our IP can publish to any topic and can subscribe to any topic.
In our examples in the previous chapter, we didn't make any changes in our configurations to allow incoming connections to port 1883, and therefore, we didn't open our Mosquitto server to the Internet.
We want to use TLS with MQTT and Mosquitto. This way, we will make sure that we can trust the MQTT server because we have confidence that it is who it says; our data will be private because it will be encrypted, and it will have integrity because it won't be altered in the middle of the road. In case you have experience with the HTTP
protocol, we will make the same shift we do when we move from using HTTP
to HTTPS
.
Websites purchase certificates from major certificate authorities. In case we want to use a purchased certificate for the server, we don't need to generate our own certificates. In fact, it is the most convenient option when we have an MQTT server made public.
We will use the free OpenSSL utility to generate the necessary certificates for the server to enable TLS with Mosquitto. OpenSSL is already installed in macOS and most modern Linux distributions. In Windows, we already installed OpenSSL as one of the prerequisites for Mosquitto. The usage of the OpenSSL utility deserves an entire book, and therefore, we will just focus on generating the certificate we need with the most common options. In case you have any specific security needs, make sure that you dive deep into the necessary options to achieve the goals with OpenSSL.
Specifically, we will generate an X.509 digital certificate that uses the X.509 Public Key Infrastructure (PKI) standard. This digital certificate allows us to confirm that a specific public key belongs to the subject included within the certificate. There is an identity that issues the certificate and its details are also included in the certificate.
The digital certificate is valid only within a specific period, and therefore, we must take into account that a digital certificate will expire some day and we will have to provide a new certificate to replace the expired one. There are specific data requirements for the certificate based on the specific X.509 version that we use. According to the version and to the options we use to generate the certificates, we may need to provide specific data.
We will be running commands to generate different X.509 digital certificates and we will provide all the necessary details that will be included in the certificate. We will understand all the data that the certificate will have when we create them.
We will create our own private certificate authority, also known as CA. We will create a root certificate and then we will generate the server key.
Tip
Check the directory or folder in which you have installed OpenSSL. In macOS, OpenSSL is installed in /usr/bin/openssl
. However, it is an old version and it is necessary to install a newer version before running the commands. It is possible to install the new version with the homebrew
package manager. In Windows, the OpenSSL version we have installed as a prerequisite has the openssl.exe
executable file in the default C:OpenSSL-Win32bin
folder. Use the full path to OpenSSL in each of the next commands that start with openssl
.
Create a new directory named certificates
and change the necessary permissions for this directory to make sure that only you can access its contents.
Open the Terminal in macOS or Linux, or the Command Prompt in Windows, and go to the previously created directory, certificates
. Run the following command to create a 2,048-bit root key and save it in the ca.key
file:
openssl genrsa -out ca.key 2048
The following lines show a sample output generated by the previous command:
Generating RSA private key, 2048 bit long modulus ....................................................................................................................................................................+++ ......+++ e is 65537 (0x10001)
The previous command will generate the private root key in the ca.key
file. Make sure that you keep this file private because anybody who has this file will be able to generate certificates. It is also possible to password-protect this file by using other options with openssl
. However, as previously explained, we will follow the necessary steps to use TLS, and you can explore additional options related to OpenSSL and certificates.
Go to the Terminal in macOS or Linux, or the Command Prompt in Windows. Run the following command to self-sign the root certificate. The next command uses the previously created 2,048-bit private key saved in the ca.key
file and generates a ca.crt
file with the self-signed X.509 digital certificate. The command makes the self-signed certificate valid for 3,650 days. The value is specified after the -days
option:
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt
Tip
In this case, we specified the -sha256
option to use SHA-256 hash functions. If we want increased security, we can use the -sha512
instead of -sha256
in all the cases in which we are using -sha256
. This way, we will use SHA-512 hash functions. However, we must take into account that SHA-512 might not be appropriate for certain power-constrained IoT devices.
After you enter the previous command, OpenSSL asks information that will be incorporated in the certificate. You have to enter the information and press Enter. In case you don't want to enter specific information, just enter a dot (.
) and press Enter. It is possible to pass all the values as arguments for the openssl
command, but it makes it a bit difficult to understand what we are doing. In fact, it is also possible to use fewer calls to the openssl
command to perform the previous tasks. However, we will run a few more steps to understand what we are doing.
The following lines show the sample output and the questions with sample answers. Remember that we are generating our private certificate authority:
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]:US State or Province Name (full name) [Some-State]:CALIFORNIA Locality Name (eg, city) []:SAN FRANCISCO Organization Name (eg, company) [Internet Widgits Pty Ltd]:CERTIFICATE AUTHORITY Organizational Unit Name (eg, section) []:. Common Name (e.g. server FQDN or YOUR name) []:CERTIFICATE AUTHORITY Email Address []:certificate@example.com
Run the following command to display the data and details for the generated certificate authority certificate file:
openssl x509 -in ca.crt -noout -text
The following lines show the sample output, which displays details about the signature algorithm, the issuer, the validity, the subject, the extensions, and the constraints:
Certificate: Data: Version: 3 (0x2) Serial Number: ff:db:b4:d7:fa:30:00:bf Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, ST=CALIFORNIA, L=SAN FRANCISCO, O=CERTIFICATE AUTHORITY, CN=CERTIFICATE AUTHORITY/emailAddress=certificate@example.com Validity Not Before: Jan 17 22:10:24 2017 GMT Not After : Jan 15 22:10:24 2027 GMT Subject: C=US, ST=CALIFORNIA, L=SAN FRANCISCO, O=CERTIFICATE AUTHORITY, CN=CERTIFICATE AUTHORITY/emailAddress=certificate@example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): 00:db:92:26:c1:fc:60:83:f1:c1:01:5e:46:e8:27: a8:e1:6e:08:02:65:05:ac:3e:d9:ad:22:8e:73:88: 3e:bf:16:b7:56:d7:44:87:e6:59:95:91:63:40:6a: 7c:fc:4f:db:48:b2:eb:d0:ca:ef:2d:6a:16:b9:31: fc:8e:ce:e9:9b:e8:d7:1c:16:81:17:b8:93:c2:e2: 7c:14:0e:aa:4d:c4:75:38:4e:80:50:47:6d:fa:52: c6:0c:98:2f:93:af:da:36:67:60:34:79:80:7e:cd: 03:da:c8:23:3d:e0:74:96:37:3c:0f:1d:fd:eb:e9: b9:d2:4b:00:e8:a4:d9:f6:e1:d2:51:e7:e5:74:29: dc:3d:68:84:93:47:7a:cf:6e:92:e3:10:db:73:95: 7c:d4:c7:54:b0:10:bd:5c:0f:1e:0a:c1:bd:d9:25: d8:0d:d2:c2:30:92:90:6c:2d:4c:59:17:e0:d9:06: 7d:c2:2a:b7:80:b8:cf:09:7b:23:e9:ed:8e:75:78: b7:8f:9e:87:17:a6:17:2d:c0:68:86:0d:97:5e:ab: 5f:8d:d2:66:a7:11:0e:89:51:9c:9e:be:22:3f:f2: bd:ca:03:c5:da:5d:d0:09:20:9b:55:60:23:6b:3c: 67:de:99:8a:ef:0a:62:7f:92:8d:88:c9:01:70:b8: 3d:eb Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 60:E5:C6:17:15:F8:2B:54:B2:DA:33:25:61:D4:4B:E3:DC:D9:70:6B X509v3 Authority Key Identifier: keyid:60:E5:C6:17:15:F8:2B:54:B2:DA:33:25:61:D4:4B:E3:DC:D9:70:6B DirName:/C=US/ST=CALIFORNIA/L=SAN FRANCISCO/O=CERTIFICATE AUTHORITY/CN=CERTIFICATE AUTHORITY/emailAddress=certificate@example.com serial:FF:DB:B4:D7:FA:30:00:BF X509v3 Basic Constraints: CA:TRUE Signature Algorithm: sha256WithRSAEncryption b8:b5:dc:71:b4:7f:66:f4:c0:d2:8f:0a:87:63:4f:b3:74:b0: 37:dd:5a:20:10:01:1c:91:ba:fa:71:47:b7:ad:ec:37:69:c1: 31:79:58:70:89:f2:d4:67:b3:a6:64:e2:75:0d:48:d1:fc:df: 67:3d:e7:cc:fa:9c:6d:65:ef:39:b2:74:76:11:4b:b5:23:3f: b3:cb:af:7a:eb:33:d0:4c:da:ed:1e:40:4b:33:7b:ed:25:ba: 9a:5a:d9:45:36:54:b7:25:b2:96:37:32:be:b1:f5:fa:1b:0f: e4:29:7a:bd:c5:78:da:cc:ff:f0:3b:16:71:13:b0:ee:6c:04: 79:b0:33:56:c6:ac:28:d7:0b:7e:0e:ca:f0:7d:56:0f:59:e8: 5a:f9:49:66:1b:b8:7e:a1:31:07:ed:f6:0c:ec:9a:1e:82:73: 26:c5:2b:a9:c5:44:ef:b3:a4:7d:98:23:3e:f0:5b:ba:af:b6: bf:0c:c8:be:75:c9:a6:07:2e:4d:47:2d:71:80:fc:fd:42:e2: 18:0d:4d:65:7e:6f:27:42:65:79:83:f9:74:11:c6:70:32:6f: d9:98:5c:54:e5:eb:b6:68:7b:93:25:56:ef:11:d4:2f:61:d1: 43:4f:b9:69:1c:2d:d2:e0:99:e5:12:be:20:c1:54:fe:b8:ea: c9:f0:27:d9
After running the previous commands, we will have the following two files in the certificates
directory:
ca.key
: Certificate authority keyca.crt
: Certificate authority certificate file
Tip
The certificate authority certificate file is in a Privacy Enhanced Mail (PEM) format. We must remember this format because some MQTT utilities will require us to specify whether the certificate is in the PEM format or not. A wrong value in this option won't make the MQTT client establish a connection with an MQTT server that uses a certificate in PEM format.