Securing a Mosquitto server
Security for IoT, mobile, and web applications is an extremely important topic that deserves entire books dedicated to it. Each solution has its own security requirements, and it is very important to consider all of them when developing each component of the solution.
If we use MQTT to publish values that are neither confidential nor critical for other applications, our only concern may be to keep control over the maximum number of subscribers to topics to make sure that the messages are always available. This way, we can avoid the failure of MQTT in delivering messages to a huge number of subscribers.
However, most of the times, we won't be working on a solution that can share the data with the entire world without limitations and doesn't need to care about data confidentiality and integrity in addition to data availability. Imagine that we are working on a solution that includes a mobile app that allows users to control a huge drone. If the drone flies the wrong way, we can do harm to real people. We cannot allow any unknown publisher to be able to send messages to the topics that allow us to control the drone. We have to make sure that the right person is controlling the drone and that the commands sent as part of the messages cannot be altered by an intruder in the middle of the road.
Tip
The different levels of security come at a price, that is, there is always an additional overhead. Hence, we should always keep a balance to avoid overheads that can make the entire solution unfeasible and unusable. Whenever we add more security, we will require additional bandwidth and we will add a processing overhead to the clients and the server. We have to take into account that some cryptographic algorithms that work without problems in modern smartphones aren't suitable for IoT boards with a constrained processing power. Sometimes, the security requirements can force us to use specific hardware, such as more powerful IoT boards. We definitely have to consider security before purchasing all the hardware for our solution.
Another important thing that we must take into account is that many security levels require maintenance tasks, which might be unfeasible in certain cases or extremely difficult to achieve in other cases. For example, if we decide to use a certificate for each device that will become a client of the MQTT server, we will have to generate and distribute a certificate for each device. We have to access the filesystem for the device to copy new files to it. In case we have to invalidate a certificate, it would be necessary to provide a new certificate to the affected device. Consider a situation in which all the devices are distributed in different locations, which are difficult to access; we must have a mechanism to remotely access the device and be able to provide it with the new certificate. This task would also require security because we don't want anybody else to access the device's filesystem. Thus, things can become extremely complex once we start analyzing all the security requirements and the possible and necessary maintenance tasks.
Each MQTT server or broker implementation can provide specific security features. We will work with some of the features provided by Mosquitto out of the box. Specific security requirements might make us decide to work with a specific MQTT server or broker implementation.
When we work with Mosquitto, we can implement security in the following levels:
- Network: We can use a Virtual Private Network (VPN) to extend a private network across the Internet.
- Transport: MQTT uses TCP as the transport protocol, and therefore, by default, the communications aren't encrypted. Transport Layer Security (TLS) is usually referred to as TLS/SSL, because Secure Socket Layers (SSL) is its predecessor. We can use TLS to secure and encrypt communications between the MQTT clients and the MQTT server. The usage of TLS with MQTT is sometimes referred to as MQTTS. TLS allows us to provide both privacy and data integrity. We can use TLS client certificates to provide authentication.
- Application: At this level, we can take advantage of the features included in MQTT to provide application-level authentication and authorization. We can use
ClientId
(Client Identifier) to identify each client and combine it with user name and password authentication. We can add additional security mechanisms at this level. For example, we can encrypt the message payload and/or add integrity checks to ensure data integrity. However, the topic would still be unencrypted, and therefore, TLS is the only way of making sure that everything is encrypted. We can work with plugins to provide more complex authentication and authorization mechanisms. We can grant or deny permissions to each user to control which topics they can subscribe to and which topics they can publish messages to.
Tip
The most popular MQTT implementations provide support for TLS. However, make sure that you check the features before selecting the appropriate MQTT server for your solution.
We won't cover all the security topics because it would require one or more entire books dedicated to these topics. Instead, we will focus on the most common features used in transport-level security first, and then, we will move to application-level security. The usage of VPNs is out of the scope of this book. However, you must consider their usage based on your specific needs. We will use Mosquitto for our examples, but you can follow many similar procedures for any other MQTT server you decide to use. Everything we will learn will be useful for any other MQTT server that provides support for the same security features that we will use with Mosquitto.