Rate this page:

Programmable Wireless: How to Run a Test MQTT Broker

This tutorial has been deprecated and will shortly be removed.

In this tutorial, we show you how to create a local MQTT test server using Eclipse Mosquitto for testing. You can run Mosquitto in many environments, but launching it via Docker is one of the quickest paths.

After you complete this tutorial, you can run our broadband MQTT Quickstart substituting your server credentials.

What is MQTT?

MQTT is a publish-subscribe messaging protocol built on top of TCP/IP. It stands for Message Queuing Telemetry Transport.

Lightweight protocols like MQTT are perfect for both low-bandwidth Narrowband and Broadband IoT connectivity. They help you mix high-powered and low-powered devices in the same communications channels.

Use a Docker Mosquitto image

We’ll get a local Mosquitto instance up and running quickly using Docker on your machine or virtual host.

If you prefer, Mosquitto is also available via apt, homebrew, or an installer package. Please see the Mosquitto download page for more details on alternative installation methods.

The service we stand up here is unencrypted and not suitable for production. A production-ready implementation of Mosquitto includes:

  • TLS.
  • Strong username/password or PKI certificate credentials.
  • Perhaps an ACL customized to your needs.

To make future tweaks to our Docker image config easier, we are going to create a directory to hold our Mosquitto configuration:

mkdir config

To start up a very public, very lightly protected Mosquitto broker that you — and soon anyone on the Internet — can access using the default configuration on your local machine, first create a basic configuration file in your config directory with the name config/mosquitto.conf

connection_messages true
allow_anonymous false
password_file /mosquitto/config/mosquitto.passwd

listener 1883
protocol mqtt

listener 8000
protocol websockets

Next, create a simple plain text password file. This means that your connectivity is in plaintext — again, this is not suitable for production.

Name this file config/mosquitto.passwd


Please change both username and password to something unique to you.

In a real-world deployment, you should run your password file through Mosquitto’s hashing function:

mosquitto_passwd -U mosquitto.passwd

to update the passwords to hashes. This command will not differentiate between cleartext and previously hashed passwords, so don’t run it twice or the resulting string will be unusable.

To start the eclipse-mosquitto Docker image using this modified configuration file, follow the instructions for your operating system below.


Run this command from the command line:

docker run -it --name mosquitto -p 1883:1883 -p 8000:8000 \
  -v $(pwd)/config:/mosquitto/config eclipse-mosquitto

Let’s dig into the parameters we’re passing to Docker here:

-it runs Docker interactively and allocates a pseudo TTY so you can see output. You can use -d instead to run the process completely in the background.

--name mosquitto specifies a name for our Docker container to make referencing it easier later.

-p 1883:1883 and -p 8000:8000 forward ports 1883 (MQTT) and 8000 (MQTT over websockets) from the container’s environment to the host computer. If you wish to use TLS to protect the communications you would replace the 1883 forward with -p 8883:8883 and supply certificate information — see the mosquitto-tls man page or further in this tutorial.

-v $(pwd)/config:/mosquitto/config forwards our local config directory to the container for the mosquitto.conf and mosquitto.password files.

This initial configuration does not enable Mosquitto’s ability to either write a log file or a persistent data storage location for cross-server-run topic subscriptions. As is, if the server restarts any un-received messages sent to subscribed topics will be lost, as will any retained or willed messages.

The final parameter, eclipse-mosquitto tells Docker we wish to use the eclipse-mosquitto image for the container.

If you are running this on a host with a publicly accessible IP address, your server will be up and available as soon as you run this command.

If you are running it on your local network, you are probably behind a NAT gateway and will need port forwarding or a tool like ngrok before your address is publicly accessible.

If you have a local firewall running, you may have to explicitly allow connections to the port of your choosing. Here we’re using 1883 for cleartext MQTT and 8000 for cleartext Websocket MQTT. Later in the tutorial we will use 8883.

Windows 10 Pro, Enterprise or Educational

Docker requires Windows Hyper-V which is not available on Windows 10 Home Edition. Check out Mosquitto’s website for a Windows installer instead.

Connect locally to the broker

Before talking to the broker from your IoT device, first check everything is working properly.

You can subscribe or publish to your new MQTT broker using either of these options:

Let’s look at both now.

The HiveMQT websocket broker

In this step, you can test your server using the HiveMQ websocket client even if you are only running the service locally. This is because the MQTT client connection comes from your browser, not HiveMQ.

Visit HiveMQ’s web-based client, then:

  1. Change the Host to localhost.
  2. Leave the port at 8000 for a websocket cleartext connection.
  3. We recommend leaving the ClientID at the default random value. ClientIDs must be unique in MQTT.
  4. Set Username and Password to the values you assigned in your mosquitto.passwd file.
  5. Click Connect.

MQTT works by clients “subscribing” to “topics”, and messages being “published” to those topics. Now that you’re connected, subscribe to a topic:

  1. Click on Add New Topic Subscription under Subscriptions.
  2. Subscribe to YOURRANDOMSTRING/# where YOURRANDOMSTRING is any alphanumeric string (with hyphens), such as twilio-loves-mqtt/#. The # indicates a wildcard for any child channels, for example twilio-loves-mqtt, twilio-loves-mqtt/1, twilio-loves-mqtt/sensors/basement/temperature, and so on.
  3. Click on the Subscribe button. Do not press Enter or Return on your keyboard as it will reload the page.
  4. Leave the QoS set to 2, the default.

Finally, publish a message to your topic:

  • Under Publish, ensure the Topic has a topic name that matches the pattern to which you subscribed, such as YOURRANDOMSTRING/data.
  • Type a nice message to yourself in Message.
  • Click Publish.

You should see your message appear in the Messages section.

A command line client

Mosquitto distributes its own client applications as packages for many operating systems. Details can be found on the Mosquitto download page.

The commands below assume you are running this in a Docker image local to your computer. If you are running on a different host, substitute the correct IP address for

MQTT works by clients “subscribing” to “topics”, and messages being “published” to those topics. We will first subscribe to a topic by running this command in a dedicated shell window:

mosquitto_sub -h localhost -p 1883 -u username -P password -t 'testtopic/#'

Then, in another window:

mosquitto_pub -h localhost -p 1883 -u username -P password -t 'testtopic/hello' -m 'Hello, world'

...and you should see your message.

Now let’s connect an IoT device to the broker.

Allow remote connections to your MQTT Broker

If you are running this code on an Internet-connected host such as a VPS, you may already have access. But, if you are running this locally, you probably need to use a proxy to tunnel TCP traffic to your local port 1883. One popular option is to use ngrok.

ngrok is free, but you need to sign up for an account. The ngrok docs have all the information you need to install the software and configure it for use.

ngrok is typically used to forward web traffic, but we wish to forward a raw TCP port. Lucky for us, ngrok supports this:

ngrok tcp 1883

ngrok will provide you a new hostname and port number.

It’s important to note that this port number will not be 1883. The hostname and port number ngrok returns are what you should plug into the hostname and port number in the IoT Quickstarts.

Use ngrok to forward a websocket connection

You can’t use the port returned by ngrok as the remote host for the HiveMQ websocket-based MQTT client.

To enable this, run the following comment to set up a second tunnel to support a remote websocket connection:

ngrok tcp 8000

The resulting host and port are what you should use to substitute in the web tool.

Add encryption to the MQTT broker

In production, you need to secure communication when using MQTT. This will prevent others from eavesdropping or obtaining your credentials.

The mosquitto-tls man page will tell you how to create a self-signed certificate authority both for your server’s certificate and (optionally) client certificates.

The CN for the server certificate you create must match the hostname provided to the MQTT client.

You can temporarily override this using the equivalent of mosquitto_pub and mosquitto_sub’s --insecure mode and disabling server hostname checking. This is recommended only for local testing — do not leave this on in production.

After creating the certificates above — or providing your own — place them into the config/ directory with the following paths and filenames:


We’re using a directory and capath instead of a single cafile. This will help support Twilio Trust Onboard authentication in a later step.

To enable TLS communications with your server, edit the mosquitto.conf and add the following lines:

listener 8883
capath /mosquitto/config/ca/
certfile /mosquitto/config/server.crt
keyfile /mosquitto/config/server.key
tls_version tlsv1.2

Now restart the Docker instance. On Linux or macOS, use ctrl-c if you are running interactively, or docker kill if in a container. This time, we will add port forwarding for MQTTS (8883):


docker run -it -p 8883:8883 -p 8000:8000 -v $(pwd)/config:/mosquitto/config eclipse-mosquitto

Windows 10 Pro, Enterprise or Educational

Docker requires Windows Hyper-V which is not available on Windows 10 Home Edition. Check out Mosquitto’s website for a Windows installer instead.

About certificate authentication

Certificate-based authentication relies on two trust factors: the client trusting the server and the server trusting the client.

Server trust is established by the MQTT client trusting the issuer of the server’s certificate. This is typically accomplished by including a trusted CA certificate or chain in your client.

Client trust is established by the client presenting a certificate signed by a trusted issuer known to the server. The server is configured with a list of trusted certificate issuers that client certificates are validated against.

If your client’s certificates are generated by an authority you control, validating the certificate issued by a trusted party may be sufficient for your needs. If the client certificates are issued by a third-party that issues many certificates, you may have one additional step: authorizing specific certificates by common name or fingerprint.

Self-generated certificate authentication

To use the self-issued certificates — as described in in the Mosquitto documentation — you just need to require certificates. The ca.crt you provided for the server’s certificate will also apply for clients.

In your mosquitto.conf file add this under the capath, certfile, and keyfile parameters:

require_certificate true

You should remove the password_file directive from the mosquitto.conf file unless you want to require both a valid certificate and a username/password.

Twilio Trust Onboard

On October 31, 2022, support for Programmable Wireless Trust Onboard will end. On this date, Programmable Wireless Trust Onboard certificates will no longer be available for sync or download in Console. Trust Onboard certificates that have already been synced to your backend services can continue to be used to authenticate devices until the device certificates expire in 30 years’ time. Trust Onboard SIMs will continue to work for connectivity as regular Programmable Wireless SIMs, which can connect to T-Mobile USA’s network in the United States and their global connectivity partners around the world.

If you are integrating Twilio Trust Onboard or are utilizing other client certificates from a shared provider, you will want to also authorize individual clients instead of trusting all certificates with a given chain. This prevents someone else’s Trust Onboard SIM (or other shared certificate) from being implicitly trusted.

To trust a Twilio Trust Onboard client certificate, the server will need to trust the certificates that make up the intermediate issuer and root issuer. You can find these certificates here.

mkdir config/ca
pushd config/ca
curl -O
curl -O
curl -O
openssl rehash .

You will likely either use Available or Signing — not both — so you can choose which is the most appropriate for your use-case.

There is no harm in specifying both though. You’ll need to explicitly allow individual clients in the ACL as described below.

openssl rehash . generates symbolic links using the SHA-1 fingerprint for quick lookup by the Mosquitto process. If your install of the openssl client utilities doesn’t support the rehash command, you can try c_rehash . instead. This is needed by some webservers to find the intermediates, so is an important step.

If the issuer of your client certificates also issues certificates for others — this is the case for Twilio Trust Onboard — you should also explicitly allow the certificates for your clients.

You have two choices, depending on how you wamt to map the certificate CN to a Mosquitto username in your mosquitto.conf file:

use_subject_as_username true

will produce usernames of the form: CN=WCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,OU=Wireless,O=Twilio Inc.,L=San Francisco,ST=CA,C=US


use_identity_as_username true

will produce usernames of the form: WCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

use_identity_as_username produces more easily managed usernames while use_subject_as_username produces more fine-grained certificate information which may be useful for certificate issuers other than Twilio Trust Onboard.

Generate usernames for the tutorial

For this tutorial, we will use use_identity_as_username true to make the ACL more readable.

In either situation, you are relying on the trusted CA certificates you have configured to prevent spoofed certificates with a matching subject or identity from being allowed access.

The WCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX SID is available by downloading your certificates in bulk on the download certificates page in the Twilio console.

The certificate SID is the WCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX portion of the file name, without the trailing -signing.pem or -available.pem.

Setting up the ACL for many clients is best deferred to an auth_plugin within Mosquitto. However, for our quick test we’ll use Mosquitto’s standard ACL file for identities, mapped to usernames, instead.

In the sample below, we will give all authorized clients equal access to all topics in the system.

You can easily restrict this in any way your use-case requires, for example a temperature sensor that can only public to its own endpoint: topic write sensors/temperature/building_1.

Create a file named mosquitto.acl and populate it with your Trust Onboard SIM’s certificate SIDs:

topic readwrite #

Authenticating with Mosquitto and Trust Onboard

The easiest path to connecting to Mosquitto using Trust Onboard is using the Trust Onboard SDK to obtain the Available certificate and private key at runtime in your application.

You can then provide this certificate and key to Mosquitto during client setup. If you are working with the Mosquitto command line pub’n’sub tools, you can also use the trust_onboard_tool CLI to instead export the certificate and private key to the file system for authentication.

Please keep in mind that writing the private key out to disk can be risky. If anyone else can access that disk, consider using the private key only in RAM (or a RAM disk) to reduce the chance of it leaking.

Rate this page:

Thank you for your feedback!

Please select the reason(s) for your feedback. The additional information you provide helps us improve our documentation:

Sending your feedback...
🎉 Thank you for your feedback!
Something went wrong. Please try again.

Thanks for your feedback!

Refer us and get $10 in 3 simple steps!

Step 1

Get link

Get a free personal referral link here

Step 2

Give $10

Your user signs up and upgrade using link

Step 3

Get $10

1,250 free SMSes
OR 1,000 free voice mins
OR 12,000 chats
OR more