MQTT Broker Security – 101
This blog is part of IoT Security series where we discuss the basic concepts pertaining to the IoT/IIoT eco-system and its security. If you have not gone through the previous blogs in the series, I would urge you to go through those first. In case you are only interested in MQTT broker security, feel free to continue.
IoT Security – Part 1 (101 – IoT Introduction And Architecture)
IoT Security – Part 11 (Introduction To CoAP Protocol And Security)
In this blog, we are going to look at Client Authentication and other security methods used by MQTT broker for secure connections with MQTT clients
1 Introduction
MQTT protocol is becoming popular in many industries, it also fascinates IoT beginners, enthusiast IoT developers, and security researchers who want to explore this technology for new opportunities.
If you are new to MQTT and want to understand more about the protocol, please go through our blog on MQTT Protocol and Security.
IoT Security – Part 10 (Introduction To MQTT Protocol And Security)
There are many open-source and commercial implementation for MQTT Broker and client available to choose from. But before using any MQTT implementation of MQTT broker, one must understand the security capabilities of MQTT broker and clients.
This blog articulates the information required for beginners to start working on security of MQTT protocol and security capabilities required for MQTT Broker and client.
We are using Eclipse Mosquitto Broker to understand broker configuration and how to configure the Mosquitto broker for desired security mode. We will also look into AWS IoT Core for similar feature and configuration.
2 Data and Connection Security
2.1 Secure Connection
As per MQTT specs TCP ports 8883
 and 1883
 are reserved for MQTT TLS and non TLS communication respectively.
In non TLS communication i.e. on port 1883
, MQTT messages are transferred in plain-text format between MQTT broker and client and should be considered as an unsecure connection. Whereas in TLS communication or secure connection i.e on TCP port 8883
, MQTT messages are encrypted by TLS security layer before transmission.
It is always a good idea to use secure communication between MQTT broker and client.
2.1.1 Mosquitto Broker
Mosquitto Broker provides an option in mosquitto.conf
 file to select listener port for MQTT connection, default value is 1883
. It should be changed to 8883
 for secure (TLS) communication.
1# Port to use for the default listener.
2port 8883
This is just the first step and you still need to configure broker for using certificates to make it work.
2.1.2 AWS IoT Core
AWS IoT core by default uses TLS connection for MQTT on port 8883
2.2 Application data or MQTT Payload security
MQTT protocol is messaging protocol and does not provide any encryption for the application payload it is carrying. It is responsibility of the application to encrypt/decrypt application data (payload) before sending to or after receiving from the MQTT layer to achieve end to end data encryption. Please note that application level encryption is independent of TLS packet encryption.
3 Client Authentication
For any MQTT broker, there are three types of client authentication methods available to verify the identity of MQTT client
- Client Identifier (Client Id)
- Username and Password
- Client Certificates
3.1 Client Identifier (Client Id)
All MQTT clients must have a unique Client Id
 as per the MQTT Spec, and the client must send this Client Id
 with the CONNECT
 packet. The broker uses this Client Id
 to create and maintain the session state.
The Client Id
 is not part of MQTT authentication and is only used to uniquely identify the MQTT connection. However, some broker implementations provide some way to establish client identity using Client Id
 or something derived from Client Id
. However, using client ID alone for authentication or verification is a bad idea because it can be manipulated/spoofed at the client side.
We will see how Mosquitto Broker and AWS IoT Core use client id
 for basic security in following examples
3.1.1 Mosquitto Broker
Mosquitto Broker provides an option called clientid_prefixes
 in mosquitto.conf
 file to configure Client ID prefixes, which allow clients with specified prefixes in their Client ID to connect to the mosquitto broker.
1# =================================================================
2# Security
3# =================================================================
4
5# If set, only clients that have a matching prefix on their
6# clientid will be allowed to connect to the broker. By default,
7# all clients may connect.
8# For example, setting "secure-" here would mean a client "secure-
9# client" could connect but another with clientid "mqtt" couldn't.
10clientid_prefixes C_ID-
Here in above example, clientid_prefixes is set to C_ID- and a client with client id
 let’s say C_ID_Client01 will be allowed to connect, but a client with the Client ID Client01 will not be allowed to connect.
3.1.2 AWS IoT Core
AWS IoT provides the option to set thing id
 while creating thing
 in IoT core, here thing
 id is not the same as Client ID
. However, AWS IoT allows connection for registered thing
 when connection policy is configured for the corresponding thing id
.
Note: If the client withÂ
client id
 asÂclient_1
 is connected and the second client with the sameÂclient id
 i.e.Âclient_1
 is trying to connect the broker, then the first client is disconnected by the broker. This is the bare minimum security provided for any client session by MQTT protocol and keeps a client with intermittent connectivity from spawning multiple MQTT sessions. However, as discussed in our previous blog post on MQTT, it also opens the door for Denial of Service attacks on the MQTT network.
3.2 Username and Password
MQTT spec defines the requirement of a username
 and password
 for MQTT client authentication. A client sends the username
 and password
 with the CONNECT
 packet to the MQTT broker and the broker validates the username
 and password
 before accepting the MQTT session.
The username
 and password
 is sent in the CONNECT
 packet to the broker in cleat text format unless encrypted at the transport layer i.e. using port 8883
 for connection.
Note: According to the MQTT spec it is not mandatory to use authentication.
3.2.1 Mosquitto Broker
Mosquitto Broker provides two parameters in mosquitto.conf
 file to enable client authentication by client – username
 and password
.
3.2.1.1 Allow Anonymous
(Please provide a sentence explaining what is allow anonymous) To enable client authentication using credentials, you also need to set allow_anonymous
 parameter to false
 in mosquitto.conf
 file.
1# Defaults to true if no other security options are set. If `password_file` or
2# `psk_file` is set, or if an authentication plugin is loaded which implements
3# username/password or TLS-PSK checks, then `allow_anonymous` defaults to
4# false.
5#
6allow_anonymous false
3.2.1.2 Password file Path
To create a password file, the mosquitto broker comes with mosquitto_passwd
 utility which creates a password file.
Example:
a. Create/append password file and add userÂ
john
 with hashed password
1$ sudo mosquitto_passwd -c /etc/mosquitto/pwfile john <somepassword>
b. Delete a user from a password file
1$ sudo mosquitto_passwd -d /etc/mosquitto/pwfile john <somepassword>
Once password file has been created, set the current location of password file using password_file
 parameter in mosquitto.conf
 file.
1# See the TLS client require_certificate and use_identity_as_username options
2# for alternative authentication options. If an auth_plugin is used as well as
3# password_file, the auth_plugin check will be made first.
4password_file /etc/mosquitto/pwfile
5
Note: The default location of the mosquitto password file for Linux isÂ
/etc/mosquitto/pwfile
 and for windows is the mosquitto installation folderÂ~\mosquitto\passwords.txt
3.2.2 AWS IoT Core
AWS IoT core does not support username and password authentication but it provides option for custom authentication.
Note: Another use ofÂ
username
 is to allow or denyÂtopic
 access to clients based on theirÂusername
, we will see it in following section 4.1.3.2
3.3. Client SSL Certificate
Considered as the most secure method of client authentication, in certificate-based authentication client sends an SSL certificate which is signed by a trusted root CA to the server to authenticate the client.
3.3.1 Mosquitto Broker
Mosquitto broker provides below options in mosquitto.conf
 file to enable certificate-based client authentication.
3.3.1.1 Client Certificate require
When require_certificate
 is set to true
, MQTT clients that provide valid certificate during connection handshake are allow to connect.
1# By default an TLS enabled listener will operate in a similar fashion to a
2# https enabled web server, in that the server has a certificate signed by a CA
3# and the client will verify that it is a trusted certificate. The overall aim
4# is encryption of the network traffic. By setting require_certificate to true,
5# the client must provide a valid certificate in order for the network
6# connection to proceed. This allows access to the broker to be controlled
7# outside of the mechanisms provided by MQTT.
8require_certificate true
3.3.1.2 Root CA file Path
The cafile
 or capath
 must be set to a trusted CA certificate that has signed your server certificate, to enable certificate-based client authentication.
1# At least one of cafile or capath must be defined to enable certificate based
2# TLS encryption. They both define methods of accessing the PEM encoded
3# Certificate Authority certificates that have signed your server certificate
4# and that you wish to trust.
5# cafile defines the path to a file containing the CA certificates.
6# capath defines a directory that will be searched for files
7# containing the CA certificates. For capath to work correctly, the
8# certificate files must have ".crt" as the file ending and you must run
9# "openssl rehash <path to capath>" each time you add/remove a certificate.
10cafile /etc/mosquitto/certs/ca.crt
11#capath
12
3.3.1.3 Server Certificate and keyfile Path
The certfile
 is requested by MQTT client for server authentication during TLS handshake.
1# Path to the PEM encoded server certificate.
2certfile /etc/mosquitto/certs/server.crt
3# Path to the PEM encoded keyfile.
4keyfile /etc/mosquitto/certs/server.key
3.3.2 AWS IoT Core
AWS IoT core uses x.509 certificate-based authentication as default client authentication method.
Read more about AWS IoT client authentication here.
4 Restrict access to server resources
Every MQTT broker must have some access control mechanism to restrict MQTT clients from accessing server resources based on information provided by the client such as User Name, Client Identifier, the hostname/IP address of the client, or the outcome of authentication mechanisms.
4.1 Mosquitto Broker
Mosquitto broker has a mechanism called an access control list
 or ACL
 for MQTT topics, ACL
 is used to control the client access to subscribe and publish to topics on the broker. User name or Client ID is used to restrict access to broker topics.
The acl_file
 parameter in mosquitto.conf
 is a path to a file that contains an access control list. Valid file path enables ACL
 for topic restriction.
1# If an auth_plugin is used as well as acl_file, the auth_plugin check will be
2# made first.
3acl_file /etc/mosquitto/aclfile
Note: Location of defaultÂ
ACL
 file i.eÂaclfile.example
 for linux isÂ/usr/share/doc/mosquitto/examples/aclfile.example
 and for windows it is the mosquito installation folderÂ~\mosquitto\aclfile.example
Default content of aclfile.example
 file
1 # This affects access control for clients with no username.
2topic read $SYS/#
3
4# This only affects clients with username "roger".
5user roger
6topic foo/bar
7
8# This affects all clients.
9pattern write $SYS/broker/connection/%c/state
There are three types of rules by which ACL
 is established and saved in acl_file
4.1.1 topic name
This rule uses the topic
 keyword and is applicable to all anonymous clients. If a client uses credentials for the connection then this rule is ignored for that client.
Below is the format used to define this rule –
1topic [read|write|readwrite] <topic>
Example:
Below line gives read (subscribe) access to any anonymous client and access to any other topic would be denied.
1topic read $SYS/#
4.1.2 user name
This rule uses the user
 keyword and is for the clients that use user credentials for the connection. Below is the format used to define this rule –
1user <username>
2topic [read|write|readwrite] <topic>
Here the username
 is the same as in the password file
Example:
Below lines gives read (subscribe) and write (publish) access to topicÂ
foo/bar
 to a client with user nameÂroger
 and ignored for other clients.
1user roger
2topic foo/bar
4.1.3 pattern substitution with the topic
This rule uses the pattern
 keyword. Using pattern substitution with the topic, a broker allows access to a client using its client id
 or username
.
Below is the format used to define this rule –
1pattern [read|write|readwrite] <topic>
Note: As per Eclipse Mosquitto documentation following patterns are available for substitution
- %c to match the client id of the client
- %u to match the username of the client
The following line is default entry in the ACL file and grants write (publish) access to all clients.
1pattern write $SYS/broker/connection/%c/state
4.1.3.1 Client ID substitution
Following example will illustrate how to use client id
 substation for topic
 access
Example:
Below line allow read access to topicÂ
pattern write sensor/<clientid>/data
 to all clients
1pattern write sensor/%c/data
Below line will allow write access to client with client idÂ
c1
 to access this topic and denies access to all other clients
1pattern write sensor/c1/data
4.1.3.2 User name substitution
Following example will illustrate how to use username
 substation for topic
 access
Example:
Below line allow read access to topicÂ
user/<username>/logintime
 to all client
1pattern read user/%u/logintime
Below line will allow read and write access to the topicÂ
user/john/lastlogin
 to userÂjohn
1pattern read | write user/john/lastlogin
4.2 AWS IoT Core
In AWS IoT, permissions to access the broker’s resources are controlled by AWS IoT Core policies
. Read more on AWS IoT Core policies here.
5 Certificate Revocation List
Though certificate based authentication is considered as most secured, certificate once issued, it cannot be modified and controlling one’s access when it is not expired is a challenge. And then there are scenarios where certificates form cloned or decommissioned devices, are used to get system access.
To avoid such scenarios, Certificate Revocation List (CRL) are issued by certificate authority CA. It contains information of the revoked certificates from decommissioned or compromised devices that no longer be trusted and prevent from any future use.
5.1 Mosquitto Broker
The CRL
 file is must when certificate-based client authentication is used i.e. require_certificate
 set to true
. It contains information of the revoked certificates from decommissioned or compromised client devices to prevent any future use.
You can use the crlfile
 parameter from mosquitto.conf
 to point to the PEM encoded revocation file.
1# If you have require_certificate set to true, you can create a certificate
2# revocation list file to revoke access to particular client certificates. If
3# you have done this, use crlfile to point to the PEM encoded revocation file.
4crlfile /etc/pki/mosquitto/content/crl/mosquitto_crl.pem
5.2 AWS IoT Core
Using AWS IoT console, the user can deactivate or revoke the client certificates. Read more on client certificate activation or deactivation here.
6 Conclusion
There are serval security mechanisms available out there to secure MQTT communication and it varies from implementation to implementation. These security mechanisms implemented at the MQTT broker side, correct configuration of MQTT broker and MQTT client reduce the attack surface in an IoT ecosystem and give a better edge over known attacks. We hope this blog post gave you a good insight about the security mechanisms used to secure MQTT connection between a broker and a client.
Continue to the next part – IoT Security-Part 13 (Introduction To Hardware Recon)