Security

From the ground up, HiveMQ was designed with maximum security in mind. It is mission critical for many IoT & M2M scenarios to enable secure, encrypted end-to-end communication and advanced authentication and authorization features. HiveMQ gives you the flexibility to enable specific security features for your concrete use. The following shows how to enable and configure these security features.

If you’re new to MQTT security concepts, we recommend reading our MQTT Security Fundamentals Series on our blog.

What is TLS?

Transport Layer Security (TLS) is a cryptographic protocol which allows a secure and encrypted communication at transport layer between a client application and a server. If a TLS listener is enabled in HiveMQ, each client connection for that listener is encrypted and secured by TLS.

Multiple listeners
You can configure HiveMQ with multiple listeners so HiveMQ can handle secure and insecure connections simultaneously. See the Listeners chapter for more details.

For usage scenarios where sensitive information is published via MQTT it is strongly recommended to enable TLS. When configured correctly it is very very hard [1] for an attacker to break the encryption and read the packets on the wire. Since TLS is a proven technology and the whole transport is encrypted, TLS could be a better choice than a hand-rolled payload encryption when security is more important for your scenario than package overhead. See the infobox below for more details.

As in most cases, added security comes with some disadvantages. The most important disadvantage is, that SSL/TLS comes with a significant increase in used bandwidth. While we are talking of tens of bytes here, it can make a huge difference in scenarios where small bandwidth usage is key. Please note that the SSL handshake (which takes place when a connection is established) comes with an additional overhead in terms of bandwidth and CPU. This is very important to consider when you have to deal with many unreliable connections which could easily drop.

Encryption at Transport Layer vs Encryption at Application Layer

Encryption at transport layer [2] has the advantage that the whole connection is encrypted, including all MQTT messages sent from the client to the server and from the server to the client. This ensures that nobody but the client which is connected to HiveMQ can read any message of the communication. Since the payload of the MQTT message remain unencrypted raw bytes in this case, fully interoperability with other MQTT clients (even if they do not use TLS) is ensured. All MQTT messages (not only PUBLISHes) are secured with this technique.

Encryption at application layer means that the payload of a MQTT PUBLISH message is encrypted with an application specific encryption and only clients who know how to encrypt the payload can read the original message. When not used together with TLS the transport is unencrypted and attackers could read the raw message on the wire. If the attacker does not know how to decrypt the payload, the payload of the MQTT PUBLISH message is secure. It is important to understand that only the payload of a MQTT PUBLISH can be encrypted, all other information like the topic of the message is unencrypted. Only PUBLISH payloads can be encrypted, all other MQTT messages like CONNECT cannot be secured with this technique.

Of course both encryption techniques can be used together. If it is important for your scenario that only few trusted clients can decrypt the contents of specific MQTT publishes and you want to secure your complete communication, this could be a great fit.

Java Key- and Trust Store

Java key stores and Java trust stores are containers which contain information needed for SSL like X.509 certificates and keys. Typically each trust store and each key store is persisted in one single file and they are protected by a master password.

Key stores and trust stores are conceptually similar but there is a difference in duty. In a SSL context, key stores provide credentials and trust stores verify credentials. That means, a key store contains a public key certificate and the corresponding private key. [3] Servers (like HiveMQ) typically use key stores to protect the private key for their SSL connections.

Trust stores contain trusted certificates or certificates signed by a CA in order to identify the partner of the SSL connection. Typically clients which want to connect to a server have to store the certificate of the server (or the trusted CA when the server certificate was signed by a CA) to identify the server as a trusted server.

It is possible to use the same file as key store and trust store. We strongly recommend separating them to ensure the security of the private key.

If you are not sure how to create a key store, you can find some useful information in the HowTos chapter.

Autoreload
Key and trust stores are reloaded during runtime. This means for you that adding or removing client certificates from the trust store or changing the server certificate in the key store can be done without downtime. Even the replacing of the key and trust store file is possible if the same master password is used.

Communication Protocol

If no explicit SSL/TLS version is set, TLS (which is the same as TLSv1) is used to secure the communication between HiveMQ and the clients. If possible, it is recommended to use TLSv1.1 or TLSv1.2, as these protocols tend to be more secure.

By default the following protocols are enabled:

Default protocols
TLSv1.2
TLSv1.1
TLSv1

To enable only specific protocols (e.g. if you know all your clients can use TLS 1.2) you can configure this with an configuration like this:

Configuring TLS versions
<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    ...
    <listeners>
        ...
        <tls-tcp-listener>
            <tls>
                ...
                <!-- Enable specific TLS versions manually -->
                <protocols>
                    <protocol>TLSv1.2</protocol>
                </protocols>
                ...
            </tls>
        </tls-tcp-listener>
    </listeners>
    ...
</hivemq>

Cipher Suites

TLS can only be as secure as the used cipher suites. While your JVM vendor probably makes sure that only secure ciphers are activated by default, you may want to limit HiveMQ to use specific cipher suites you are comfortable with.

By default the following cipher suites are enabled:

Default cipher suites
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
AES256 requires JCE unlimited strength jurisdiction policy files.

If no cipher suite of the above is supported, the cipher suites which are enabled by your JVM are used.

List of cipher suites
You can see a list of available cipher suites for the Oracle JVM here: Oracle JCA documentation.

The list of cipher suites that are enabled by default may change with any release. If you depend on specific cipher suites, please specify them explicitly.

To configure cipher suites explicitly, you can use a configuration similar to the following:

Configuring cipher suites for listeners explicitly
<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    ...
    <tls>
        ...
        <!-- Only allow specific cipher suites -->
        <cipher-suites>
            <cipher-suite>TLS_RSA_WITH_AES_128_CBC_SHA</cipher-suite>
            <cipher-suite>TLS_RSA_WITH_AES_256_CBC_SHA256</cipher-suite>
            <cipher-suite>SSL_RSA_WITH_3DES_EDE_CBC_SHA</cipher-suite>
        </cipher-suites>
        ...
    </tls>
    ...
</hivemq>

Each TLS listener can be configured to have its own list of enabled cipher suites.

Native SSL

This is a HiveMQ Enterprise Edition feature. Find out more about HiveMQ Editions.

HiveMQ comes prepackaged with an OpenSSL implementation called BoringSSL which is maintained by Google and can be activated on Linux or MacOS X. To enable this feature, you can use a configuration that looks like the following:

Configuring native-ssl
<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    ...
    <tls>
        ...
        <native-ssl>true</native-ssl>
    </tls>
    ...
</hivemq>

If for some reason native SSL is not supported on your platform, HiveMQ will perform a graceful fallback to the SSL implementation of your JVM.

If you only configure cipher suites that are available in OpenSSL but not in JVM SSL it can happen that your broker has no matching cipher suites for any client and the initialization of a connection is not possible.

The main advantage of using native SSL lies in its increased performance compared to standard JVM SSL. Another benefit is the availability of additional state-of-the-art cipher suites like a stronger AES with GCM, the CHACHA20 stream cipher and additional cipher suites with elliptic curve algorithms.

If native SSL is enabled, the communication protocol SSLv2Hello can not be disabled.

Randomness

HiveMQ uses /dev/urandom as default source of cryptographically secure randomness, if it is available. It is generally considered secure enough for almost all purposes [4] and has a significantly better performance than /dev/random.

If you want to revert to /dev/random for your random number generation you need to delete the line starting with

 	    JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"

From your $HIVEMQ_HOME/bin/run.sh file if you start HiveMQ manually or the -Djava.security.egd=file:/dev/./urandom option from the configuration file of the init service of your choice.

OCSP stapling

This is a HiveMQ Enterprise Edition feature. Find out more about HiveMQ Editions.

The Online Certificate Status Protocol (OCSP) allows the determination of the SSL certificate status by the OCSP Responder. Every client requests information from the responder directly and requires information about its status. OCSP is commonly used as an alternative for typical certificate revocation list (CRL) because it requires less network traffic due to containing less information than a classic CRL. The smaller amount of data that will need parsing enables more lightweight clients.

Each client needs to make an individual request to the OCSP Responder. For large amounts of clients issuing SSL requests, resulting in large amounts of consequential requests to the OCSP responder, the OCSP responder has the potential to become a performance bottleneck. Image 1 illustrates the flow of a client SSL request with OCSP (without OCSP stapling).

OCSP without stapling
Figure 1. A schematic overview of determination of the SSL certificate status by the OCSP Responder

Online Certificate Status Protocol (OCSP) stapling allows the determination of the SSL certificate status by the HiveMQ broker. The broker regularly obtains an OCSP response about its own certificate from the OCSP responder, caches the response and sends it directly to the client in the initial TLS handshake. The client does not have to connect to the OCSP responder directly. This significantly reduces the load on the OCSP responder, since a single request per validity period is sufficient. A request per individual client is no longer necessary.

OCSP stapling
Figure 2. A schematic overview of determination of the SSL certificate status by the HiveMQ broker

A caching interval defines the interval in which new status information gets requested. Between requests the last status will be cached. In case the OCSP responder is not available, the cache-interval will be reduced in order to get status information as soon as possible. HiveMQ will request status-information frequently (every 15 seconds) until a successful response has been received. After a successful OCSP-response has been received the interval is changed back to the configured value automatically. When no valid response has been received by HiveMQ for 30 minutes, the cached response will be cleaned up and no OCSP response will be handed over. HiveMQ will continue its efforts to get a new response from the OCSP responder.

In the following cases HiveMQ request the status from the responder:

  • At startup of the TLS listener

  • By passing the configured cache-interval

  • When the client requires the status and the response is not cached yet

  • If the cached response is expired and a new TLS connection is established

OCSP stapling properties

The <ocsp-stapling> element has the following properties:

Name Default Mandatory Description

enabled

false

no

Enables OCSP stapling.

override-url

none

no

Overrides the URL of the OCSP-Responder contained in the server certificate. Must be set if there is no OCSP URL information in the server certificate.

cache-interval

3600

no

Interval in seconds to cache the OCSP response on the server side from the OCSP stapling responder.

OCSP stapling configuration

The following configuration enables OCSP stapling for a TLS TCP listener:

<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <listeners>
        ...
        <tls-tcp-listener>
            <port>8883</port>
            <bind-address>0.0.0.0</bind-address>
            <tls>
                <keystore>
                    <path>/path/to/the/key/store.jks</path>
                    <password>password-keystore</password>
                    <private-key-password>password-key</private-key-password>
                </keystore>
                <native-ssl>true</native-ssl>
                <ocsp-stapling>
                    <enabled>true</enabled>
                </ocsp-stapling>
            </tls>
        </tls-tcp-listener>
        ...
    </listeners>
</hivemq>
Preconditions
Make sure to set <native-ssl> and <ocsp-stapling><enabled></ocsp-stapling> to true. Otherwise the stapling will be disabled automatically.

The following configuration enables OCSP stapling for a TLS TCP listener with a custom cache-interval and override-url:

<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <listeners>
        ...
        <tls-tcp-listener>
            <port>8883</port>
            <bind-address>0.0.0.0</bind-address>
            <tls>
                <keystore>
                    <path>/path/to/the/key/store.jks</path>
                    <password>password-keystore</password>
                    <private-key-password>password-key</private-key-password>
                </keystore>
                <native-ssl>true</native-ssl>
                <ocsp-stapling>
                    <enabled>true</enabled>
                    <override-url>http://your.ocsp-responder.com:2560</override-url>
                    <cache-interval>3600</cache-interval>
                </ocsp-stapling>
            </tls>
        </tls-tcp-listener>
        ...
    </listeners>
</hivemq>

1. at the time of writing, most attacks on TLS are of theoretical nature
2. Technically TLS works at OSI Layer 5 and 6. For the sake of simplicity we call it transport layer through the document
3. We strongly recommend to refresh your knowledge about private and public key cryptography if you are not sure what this means. This link provides useful information.