We have covered the MQTT Basics and MQTT with websockets support, now we talk about security.
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:
- 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 []:
- 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)
- 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.
- 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:
- 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)
- 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 []:
- 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.
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
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
Top comments (0)