Mosquitto MQTT Broker SSL Configuration using openssl
In this tutorial, I will test how to encrypt the communication between mosquitto MQTT Broker and the client and use a Python example.
We will use openssl for certificate and key generation.
In the certificate creation task I referred to the mosquitto-tls man page.
OpenSSL Process
Generate a certificate authority certificate and key.
There is one thing to note. In Common Name, be sure to enter the host name where MQTT Broker is running. In my case the hostname is rocky.
[root@rocky ssl]# openssl req -new -x509 -days 73000 -extensions v3_ca -keyout ca.key -out ca.crt Enter PEM pass phrase:bluebaypem Country Name (2 letter code) [XX]:kr State or Province Name (full name) []:Seoul Locality Name (eg, city) [Default City]: Organization Name (eg, company) [Default Company Ltd]:BluebayNetworks Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:rocky Email Address []:spypiggy@mymail.com
[root@rocky ssl]# ls -al
total 16
drwxr-xr-x. 2 root root 52 Apr 2 18:21 .
dr-xr-x---. 3 root root 4096 Apr 2 17:37 ..
-rw-r--r--. 1 root root 1415 Apr 2 18:20 ca.crt
-rw-------. 1 root root 1854 Apr 2 18:19 ca.key
Generate a server key without password.
[root@rocky ssl]# openssl genrsa -aes256 -out server.key 2048 Generating RSA private key, 2048 bit long modulus (2 primes) .......+++++ .................+++++ e is 65537 (0x010001) Enter pass phrase for server.key:bluebayserver Verifying - Enter pass phrase for server.key:bluebayserver [root@rocky ssl]# ls -al total 16 drwxr-xr-x. 2 root root 52 Apr 2 18:21 . dr-xr-x---. 3 root root 4096 Apr 2 17:37 .. -rw-r--r--. 1 root root 1415 Apr 2 18:20 ca.crt -rw-------. 1 root root 1854 Apr 2 18:19 ca.key -rw-------. 1 root root 1766 Apr 2 18:21 server.key
Generate a certificate signing request to send to the CA
[root@rocky ssl]# 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) [XX]:kr State or Province Name (full name) []:Seoul Locality Name (eg, city) [Default City]: Organization Name (eg, company) [Default Company Ltd]:BluebayNetworks Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:rocky Email Address []:spypiggy@mymail.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:Hellobluebay An optional company name []:
Send the CSR to the CA, or sign it with your CA key
[root@rocky ssl]# openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 73000 Signature ok subject=C = kr, ST = Seoul, L = Default City, O = BluebayNetworks.co.kr, CN = spypiggy, emailAddress = spypiggy@email.com Getting CA Private Key Enter pass phrase for ca.key:bluebaypem [root@rocky ssl]# ls -al total 28 drwxr-xr-x. 2 root root 102 Apr 2 18:24 . dr-xr-x---. 3 root root 4096 Apr 2 17:37 .. -rw-r--r--. 1 root root 1415 Apr 2 18:20 ca.crt -rw-------. 1 root root 1854 Apr 2 18:19 ca.key -rw-r--r--. 1 root root 41 Apr 2 18:24 ca.srl -rw-r--r--. 1 root root 1294 Apr 2 18:24 server.crt -rw-r--r--. 1 root root 1078 Apr 2 18:23 server.csr -rw-------. 1 root root 1675 Apr 2 18:22 server.key
You do not have to create a certificate and key for the client. TLS communication is possible with only the server certificate and key. However, let's try to make it according to the contents introduced on the homepage.
Generate a client key without password(Optional)
[root@rocky ssl]# openssl genrsa -out client.key 2048 Generating RSA private key, 2048 bit long modulus (2 primes) .........................+++++ ...........+++++ e is 65537 (0x010001)
[root@rocky ssl]# ls -al total 32 drwxr-xr-x. 2 root root 120 Apr 2 19:32 . dr-xr-x---. 3 root root 4096 Apr 2 17:37 .. -rw-r--r--. 1 root root 1415 Apr 2 18:20 ca.crt -rw-------. 1 root root 1854 Apr 2 18:19 ca.key -rw-r--r--. 1 root root 41 Apr 2 19:23 ca.srl -rw-------. 1 root root 1675 Apr 2 19:32 client.key -rw-r--r--. 1 root root 1294 Apr 2 19:23 server.crt -rw-r--r--. 1 root root 1082 Apr 2 19:22 server.csr -rw-------. 1 root root 1679 Apr 2 19:21 server.key
Generate a certificate signing request to send to the CA(Optional)
[root@rocky ssl]# openssl req -out client.csr -key client.key -new Enter pass phrase for client.key:bluebayclient 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) [XX]:kr State or Province Name (full name) []:Seoul Locality Name (eg, city) [Default City]: Organization Name (eg, company) [Default Company Ltd]:BluebayNetworks Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:spypiggy Email Address []:spypiggy@mymail.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:blueclient An optional company name []:blueclient[root@rocky ssl]# ls -al total 36 drwxr-xr-x. 2 root root 138 Apr 2 19:34 . dr-xr-x---. 3 root root 4096 Apr 2 17:37 .. -rw-r--r--. 1 root root 1415 Apr 2 18:20 ca.crt -rw-------. 1 root root 1854 Apr 2 18:19 ca.key -rw-r--r--. 1 root root 41 Apr 2 19:23 ca.srl -rw-r--r--. 1 root root 1078 Apr 2 19:34 client.csr -rw-------. 1 root root 1675 Apr 2 19:32 client.key -rw-r--r--. 1 root root 1294 Apr 2 19:23 server.crt -rw-r--r--. 1 root root 1082 Apr 2 19:22 server.csr -rw-------. 1 root root 1679 Apr 2 19:21 server.key
Send the CSR to the CA, or sign it with your CA key(Optional)
[root@rocky ssl]# openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 73000 Signature ok subject=C = kr, ST = Seoul, L = Default City, O = BluebayNetworks, CN = rocky, emailAddress = spypiggy@mymail.com Getting CA Private Key Enter pass phrase for ca.key: [root@rocky ssl]# ls -al total 40 drwxr-xr-x. 2 root root 156 Apr 2 19:38 . dr-xr-x---. 3 root root 4096 Apr 2 17:37 .. -rw-r--r--. 1 root root 1415 Apr 2 18:20 ca.crt -rw-------. 1 root root 1854 Apr 2 18:19 ca.key -rw-r--r--. 1 root root 41 Apr 2 19:38 ca.srl -rw-r--r--. 1 root root 1294 Apr 2 19:38 client.crt -rw-r--r--. 1 root root 1078 Apr 2 19:34 client.csr -rw-------. 1 root root 1675 Apr 2 19:32 client.key -rw-r--r--. 1 root root 1294 Apr 2 19:23 server.crt -rw-r--r--. 1 root root 1082 Apr 2 19:22 server.csr -rw-------. 1 root root 1679 Apr 2 19:21 server.key
Mosquitto Configuration
Add certificate and key file path
cafile /root/ssl/ca.crt certfile /root/ssl/server.crt keyfile /root/ssl/server.key
Change service port
The service default port for MQTT is 1883. It is generally recommended to use a different value for TLS.
# ================================================================= # Extra listeners # ================================================================= # Listen on a port/ip address combination. By using this variable # multiple times, mosquitto can listen on more than one port. If # this variable is used and neither bind_address nor port given, # then the default listener will not be started. # The port number to listen on must be given. Optionally, an ip # address or host name may be supplied as a second argument. In # this case, mosquitto will attempt to bind the listener to that # address and so restrict access to the associated network and # interface. By default, mosquitto will listen on all interfaces. # Note that for a websockets listener it is not possible to bind to a host # name. # listener port-number [ip address/host name] listener 8883
Restart Mosquitto Service
[root@rocky ssl]# systemctl restart mosquitto [root@rocky ssl]# netstat -nltp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8883 0.0.0.0:* LISTEN 50156/mosquitto tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 927/sshd tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN 50156/mosquitto tcp6 0 0 :::8883 :::* LISTEN 50156/mosquitto tcp6 0 0 :::22 :::* LISTEN 927/sshd tcp6 0 0 :::1883 :::* LISTEN 50156/mosquitto
You can see that the mosquitto MQTT broker is using port 8883.
MQTT Client Confirguration
MQTT Python Client
As in the example above, the certificate in the Python program only needs ca.crt.
import paho.mqtt.client as paho import time import ssl broker = 'rocky' port = 8883 connected = False def on_connect(client, userdata, flags, rc): global connected connected = True print("Client connected") def on_log(client, userdata, level, buf): print("buf:", buf) def on_disconnect(client, userdata, rc): print("client disconnected") client = paho.Client () client.on_log = on_log client.on_connect = on_connect client.on_disconnect = on_disconnect client.tls_set(r"/root/ssl/ca.crt") client.connect(broker, port) while not connected: time.sleep(1) print("Waiting") client.loop() time.sleep(1) print("Publishing") client.publish("test", "I'm python client") time.sleep(1) client.loop() time.sleep(1) client.disconnect()
Now let's run this python program and see if it is receiving from mosquitto_sub.
You can see that "I'm python client" sent from Python is transmitted normally.
Wrapping up
I created a certificate and key using openssl and applied TLS in MQTT Broker. When using MQTT Broker in the internal network, TLS does not necessarily need to be applied. However, when MQTT Broker and client communicate via the Internet, it is often necessary to consider applying TLS to MQTT Broker.
I referenced a lot of information from the following site.
댓글
댓글 쓰기