MQTT Mosquitto broker – Client Authentication and Client Certificates

After seeing how to set up transport layer security for the Mosquitto MQTT broker by using the Transport layer security on this post, we need to see how to setup client authentication (only authorized clients can connect to the broker) either by using the common user/password based authentication method or using client certificates.

Authentication by user and password:
First let’s enable authentication to the broker by setting up user and password authentication. For enabling this kind of authentication we need to modify the broker configuration (/etc/mosquitto/mosquitto.conf in my case) file and change the following entries:

allow_anonymous false
password_file /etc/mosquitto/passwd_mqtt

Before restarting the MQTT broker we need to add some users to the passwd_mqtt file with the command mosquitto_passwd:

mosquitto_passwd -c passwd_mqtt user1

The -c parameter is for creating the initial password file, if doesn’t exist, otherwise it will overwrite it!. For adding new users or update the passwords just run the command without the -c parameter.

After restarting the broker will should not be able to logon anonymously:

# mosquitto_pub --cafile /etc/mosquitto/certs/ca.crt -h localhost -t "test" -m "message" -p 8883 -d
Client mosqpub/25688-pcortex sending CONNECT
Client mosqpub/25688-pcortex received CONNACK
Connection Refused: not authorised.
Error: The connection was refused.

But providing the user name and password:

# mosquitto_pub --cafile /etc/mosquitto/certs/ca.crt -h localhost -t "test" -m "message" -p 8883 -d -u user1 -P secret
Client mosqpub/25709-pcortex sending CONNECT
Client mosqpub/25709-pcortex received CONNACK
Client mosqpub/25709-pcortex sending PUBLISH (d0, q0, r0, m1, 'test', ... (7 bytes))
Client mosqpub/25709-pcortex sending DISCONNECT 

For subscription, the same has to be done, again by providing a user and password:

# mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile /etc/mosquitto/certs/ca.crt -p 8883 -u user1 -P secret
$SYS/broker/bytes/received 217
$SYS/broker/bytes/sent 20

Authentication by using client certificates
Using client certificates, signed by a certificate authority, assures the client identity. The certificate authority used must be the same used by the server certificates and is only supported over TLS/SSL.
For using client certificates for authentication, we need to change the listener configuration for TLS/SSL by adding the following directives:

listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/hostname.crt
keyfile /etc/mosquitto/certs/hostname.key
require_certificate true
use_identity_as_username true

The require_certificate directive with the value true means that clients must now provide a client certificate to connect.
The use_identity_as_username means that the user name of the connecting user is taken from the CN (Common Name) property of the certificate, otherwise we still need to provide an user and password.

With the above new configuration, we now can’t access the broker with user/password token:

mosquitto_pub --cafile /etc/mosquitto/certs/ca.crt -h localhost -t "test" -m "message" -p 8883 -d -u user1 -P secret
Client mosqpub/26549-pcortex sending CONNECT
Error: A TLS error occurred.

the result on the log file is:

1478537500: New connection from on port 8883.
1478537500: OpenSSL Error: error:140890C7:SSL routines:ssl3_get_client_certificate:peer did not return a certificate
1478537500: Socket error on client , disconnecting.

For accessing now the broker we must provide a client certificate and a private key. The client certificate must be generated from the same CA (Certificate authority) that created the server certificate, otherwise, the client certificate can’t be validated, and the connection fails:

1478537629: New connection from on port 8883.
1478537629: OpenSSL Error: error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed
1478537629: Socket error on client , disconnecting.

So on the same directory where the ca.crt and ca.key are residing execute the script to create the client certificate. For example for creating a client certificate for user1, we need to execute the following command:

# ./ client user1

And we should have three files, two of them the user1.crt, the user certificate, and the user1.key, the user1 private key.

We can now logon to the broker:

# mosquitto_pub --cafile /etc/mosquitto/certs/ca.crt -h localhost -t "test" -m "message" -p 8883 -d  --cert user1.crt --key user1.key 
Client mosqpub/30264-pcortex sending CONNECT
Client mosqpub/30264-pcortex received CONNACK
Client mosqpub/30264-pcortex sending PUBLISH (d0, q0, r0, m1, 'test', ... (7 bytes))
Client mosqpub/30264-pcortex sending DISCONNECT

If we check the log, we have the following:

1478539830: New client connected from as mosqpub/27159-pcortex (c1, k60, u'user1').
1478539830: Client mosqpub/27159-pcortex disconnected.
1478601507: New connection from on port 8883.

We can see that the broker extracted the username from the certificate property CN. If we don’t use the use_identity_as_username as true we need to provide the username and password and the client certificate. In this case, the certificate is validated, and the user used to logon might not be the same as the one defined on the CN certificate property. So without this directive we either need to allow anonymous logon again or define user and passwords.

Additional thoughts:
With user and password authentication we can revoke access to an user, by deleting it from the password file or changing the password.
But what about the authentication based on client certificates? As long the certificate is valid, the user can logon at will, since the broker will always accept it until the end of the certificate validation date.
The solution for this is to revocate the client certificate so when it is used, the broker rejects it. For this functionality, most Certificate Authorities provide the revocation list by providing either by CRL (Certificate Revocation list) file, or by OSCP (Online Status Certificate Protocol), and the server checks the client certificate on this list before allowing access. Mosquitto broker only works with CRL files.

We need to modify the listener configuration to verify the client certificates if it was revocated or not:

listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/hostname.crt
keyfile /etc/mosquitto/certs/hostname.key
require_certificate true
use_identity_as_username true
crlfile /etc/mosquitto/certs/ca.crl

The issue now is that the script that we are using for generating certificates doesn’t generate CRLs, and so we can’t revocate certificates by using this script.

We can do it by hand, but that wouldn’t make our life much easier, since revocating certificates means that the CA server must now track all certificates and their status.
One possible solution is to use scripts that allow to create (a not very secure) CA: easy-ca. These scripts will replace the script and allow the revocation of certificates.

Getting the easy-CA scripts:

git clone

I’m omitting a lot of output that these scripts do, namely asking for the Organization name, CA passwords and so on.

Somewhere where we find suitable we create our CA:

Generating the CA:

# cd ~ 
# ~/easy-ca/create-root-ca -d CA
# cd CA

Then at the CA directory we created, we can now create our broker certificate and user certificate. Make sure that the names make sense.

Generating the broker certificate:

# bin/create-ssl -s brokername
# bin/create-client -c user1

At the end we have the following files:


We now have all the needed files for setting up our broker with support for CRL.

# sudo -s
# cp ~/CA/ca/ca.crt /etc/mosquitto/certs
# cp ~/CA/crl/ca.crl /etc/mosquitto/certs
# cp ~/CA/certs/brokername.server.crt /etc/mosquitto/certs/brokername.crt
# cp ~/CA/private/brokername.server.key /etc/mosquitto/certs/brokername.key

And restarting the broker we have the new certificates in place.
We can test now by using our CA user certificate:

# cd ~/CA
# mosquitto_pub --cafile /etc/mosquitto/certs/ca.crt -h localhost -t "test" -m "message" -p 8883 -d  --cert certs/user1.client.crt --key private/user1.client.key 
Client mosqpub/7424-pcortex sending CONNECT
Client mosqpub/7424-pcortex received CONNACK
Client mosqpub/7424-pcortex sending PUBLISH (d0, q0, r0, m1, 'test', ... (7 bytes))
Client mosqpub/7424-pcortex sending DISCONNECT

It works. Now let’s revoke the user certificate:

# bin/revoke-cert -c certs/user1.client.crt 

Revoking certificate 'certs/user1.client.crt'

Reason for revocation: 

1. unspecified
2. keyCompromise
3. CACompromise
4. affiliationChanged
5. superseded
6. cessationOfOperation
7. certificateHold

Enter 1-7 [1]: 2
You are about to revoke this certificate with reason 'keyCompromise'.
Are you SURE you wish to continue? [y/N]: y
Using configuration from conf/ca.conf
Revoking Certificate 02.
Data Base Updated
Using configuration from conf/ca.conf

Server certificate revoked.

We need to copy the new CRL to the directory where mosquitto expects the CRL:

# sudo cp crl/ca.crl /etc/mosquitto/certs

And after restarting the broker we have:

mosquitto_pub --cafile /etc/mosquitto/certs/ca.crt -h localhost -t "test" -m "message" -p 8883 -d  --cert certs/user1.client.crt --key private/user1.client.key  
Client mosqpub/7640-pcortex sending CONNECT
Error: A TLS error occurred.

And on the logs:

1478625909: OpenSSL Error: error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed
1478625909: Socket error on client , disconnecting.
1478625910: New connection from on port 8883.

22 thoughts on “MQTT Mosquitto broker – Client Authentication and Client Certificates

  1. This article and your transport security article are by far the most clear and concise resources I’ve found on this topic. From a complete coding novice, thanks a lot for taking the time to make them.

    1. Well, I had the same problem regarding MQTT security and at the end, since that I also found nothing on the web, I’ve had to write this 🙂

      1. Question. When I’m implementing certificates on the client side, I ran the again as you suggested and ended up with my 3 additional files. I then moved these files to my /etc/mosquitto/certs directory. Lastly I wanted to add them to my local mosquitto.conf file but realized I didn’t know the proper syntax to add multiple certificates. I’ve tried the following, simply putting a space between the paths… obviously this didn’t work:

        #MQTT over TLS/SSL

        listener 8883
        cafile /etc/mosquitto/certs/ca.crt
        certfile /etc/mosquitto/certs/RP3-CSB.crt /etc/mosquitto/certs/user1.crt
        keyfile /etc/mosquitto/certs/RP3-CSB.key user1.key /etc/mosquitto/certs/user1.key
        require_certificate true
        use_identity_as_username true
        tls_version tlsv1.2

        #End of MQTT over TLS/SSL

        allow_anonymous false
        password_file /etc/mosquitto/conf.d/passwd

        log_type error
        log_type warning
        log_type notice
        log_type information

        connection_messages true
        log_timestamp true

        Any suggestions?


  2. So I actually did get this to work with the following config. As you’ll notice, I had to create a whole separate listener and that listener must be on a separate port.

    Am I going about this the wrong way? Is there a better way to do this?

    #MQTT over TLS/SSL

    listener 8883
    cafile /etc/mosquitto/certs/ca.crt
    certfile /etc/mosquitto/certs/RP3-CSB.crt
    keyfile /etc/mosquitto/certs/RP3-CSB.key
    require_certificate true
    use_identity_as_username true
    tls_version tlsv1.2

    #End of MQTT over TLS/SSL

    listener 8884
    cafile /etc/mosquitto/certs/ca.crt
    certfile /etc/mosquitto/certs/user1.crt
    keyfile /etc/mosquitto/certs/user1.key
    require_certificate true
    use_identity_as_username true
    tls_version tlsv1.2

    #End of MQTT over TLS/SSL

    allow_anonymous false
    password_file /etc/mosquitto/conf.d/passwd

    log_type error
    log_type warning
    log_type notice
    log_type information

    connection_messages true
    log_timestamp true

  3. Hi: I think there is some confusion regarding your configuration. From what you have sent, you are using the user certificate on the mosquitto configuration. This is not necessary and it is not right. The only configuration needed is the first one where the server certificate is used. User certificates are only used on the client side.

    Now both the server and the users certificate must belong to the same CA, so when the client which uses the user certificate with the public key to communicate to the broker, the broker can check the signature validity.

    The user private key is always kept with the user otherwise it won’t be private…

    By other words: The broker only needs to have configured the server certificate and private key.

    The user to connect must provide the user certificate that holds the public key and also the user private key.

    Both private keys never should be used for anything else.

    The user certificates and keys are used as the following example:

    mosquitto_pub –cafile /etc/mosquitto/certs/ca.crt -h localhost -t “test” -m “message” -p 8883 -d –cert certs/user1.client.crt –key private/user1.client.key

    I hope I was able to help.

    1. That is very helpful. I absolutely did not understand correctly.

      So, in the above example, I’m simply running MQTT in different command windows for testing. Are you saying, in a more realistic example, the ca.crt is the only file that needs to be included in the /etc/mosquitto/certs directory? That the user1.crt and user1.key would be on the separate device that is trying to communicate with the broker?

      If yes, and I have multiple clients using multiple different private client certs and keys, what belongs in the certfile and keyfile positions in the mosquitto configuration file?

      If no, I obviously still don’t understand.

      Basically your explanation lead me to believe that ca.crt is required on the broker side and user1.crt and user1.key (the public and private key) are required only on the client side? Is this correct?

      Thanks again for your assistance in this, I’d be lost without it.


      1. Hi, yes you are correct, on the broker side the only thing needed is the CA cert and the broker cert and private key, nothing else. The broker does not need to track users or clients. That’s the CA job.

        So each client then has its own user/client cert and user/client private key.

        Since all certificates the broker and the client are created using the same CA, this means that the broker only needs to check on connection if the user certificate is valid against the CA and it does this with its own CA cert.

        The process is a bit more complicated, but basically its just that.

        So no need to add users on the broker. Just create user/client certificates from the same broker CA and it will just work fine on any client. Off course the user creating the certs must be authorized and the CA must be protected.

  4. Hi,

    Is it also possible to use client authentication with a certificate for web socket connections?

    Kind regards,

    1. Not sure, since I didn’t try it out. The web sockets certificate FQDN must match the URL used for web sockets connection that is for sure otherwise the browser would complain.
      Since client auth based on certs are supported by the browser it really depends if mosquitto does support it… I’ll have to check it.

  5. Really nice and clear explanation, Thank you!
    I am a newbie and learning mosquitto and SSL/TLS. I have a situation where I have to create clients dynamically. After reading your article, I am comfortable using client side SSL certificates. I am thinking of doing some rest calls that my clients will do, and get dynamically generated certificates for themselves(using openssl), as the rest service is already secured. My question to you is, am I thinking the right way and should I also make use_identity_as_username to false and create user and password for each client so that on connecting to my mosquitto server, each client must provide a certificate, user and password.
    Thank you.

    1. Using certificates AND user and password means that you have two things to manage, the certificates and the passwords. using only the certificates for authentication and security merges the two functions. It really depends on your use case what is better.

  6. You wrote “For subscription, the same has to be done, again by providing an user and password:”
    it should read “For subscription, the same has to be done, again by providing a user and password:”
    The simple rule in English is if the following word in this case “USER” sound like it begins with a vowel you prefix with “AN”
    otherwise always “A”
    Not a vowel mind you but SOUNDS like a vowel invariably this will actually be a vowel but not always.
    An example being words starting with Yo which sound like a U which of course is a vowel.

    BTW congratulations for an incredible article.

  7. These self-signed certificates work when testing locally but create ssl handshake error when used on server. What may be the solution?

  8. Hey,

    first of all thanks for this guide as there really is not much to find regarding the whole procedure out there. 🙂

    So i just tried setting up my mosquitto using TLS following this tutorial. But now i ran into a problem i can´t figure out how to solve…
    I created the ca.crt + server.crt and .key with the “./” script from owntracks, set up the config for these files and the connection only using the ca.crt and username, password worked just fine.
    Now i created the client files named node1.crt and node1.key with the same script (“./ client node1”). Also enabled require_certificate and use_identity_as_username in the config. Now i try to connect to the broker using the command

    pi@raspberrypi:~ $ mosquitto_pub -h localhost -p 8883 -t test/test -m “message” –cafile /etc/mosquitto/certs/ca.crt –cert /etc/mosquitto/certs/node1.crt –key /etc/mosquitto/certs/node1.key

    i get the following error in the console:
    “Error: Problem setting TLS options.”

    And in the .log file i get this message:
    “OpenSSL Error: error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown
    Socket error on client , disconnecting.”

    I can´t figure out what the problem is here. Any suggestions on how to solve this?

    1. Hey,

      i was able to solve this problem now. 🙂
      Read up in a few forums and apparently the console log error “Problem setting TLS options” is commonly caused by wrong access rights for the files. In my case this was caused by executing the mosquitto clients without sudo in the console while the owner of the cert and keyfile was root and so only the root user had reading privileges.
      So all i had to do in the end was either using sudo with the clients in the console to be able to read the files or change the owner/group of the key and certfiles to the default user of the raspberry.

  9. how to Generating the broker certificate?
    I have issue in the below command
    # bin/create-ssl -s brokername
    # bin/create-client -c user1

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.