Chapter 8

Listeners and TLS

EMQX listeners and TLS: what each of 1883/8083/8084/8883 is for, how to add and edit a listener, TLS certificates and the mTLS concept, and how to handle port conflicts.

Why this matters

So far you have connected mostly over plain TCP on 1883, but one thing EMQX 5.8.9 does is let a single broker listen on several "exits" at once: standard MQTT (TCP), WebSocket, secure WebSocket, and encrypted connections over SSL/TLS. If you want some devices on an encrypted port, Home Assistant on WebSocket and your testing on 1883, you need to understand what these listeners are, how to add and edit them, and above all how certificates work.

This chapter walks through what each of the five ports is for, how to add and edit a listener under Management → Listeners, and how one-way and mutual authentication work in SSL/TLS and mTLS. It also covers the port conflict that trips up home installs most often (Mosquitto holding 1883, WebRTC holding 8083) and how to migrate safely from the Dashboard.

Core concepts

A listener is the server-side point at which EMQX accepts MQTT client connections. Each one has a transport protocol (TCP/SSL/WebSocket/WSS) plus a bind address and port, and you can set how many concurrent connections it accepts (max_connections). One EMQX instance can run several listeners at the same time, so clients with different jobs can use different protocols and ports.

The official docs list four main transports: TCP (1883), SSL (8883), WebSocket (8083) and Secure WebSocket (8084). The Dashboard itself is served by the add-on on 18083 (HTTP), so the "five ports" you hear about day to day are 1883, 8083, 8084, 8883 and 18083.

To reach an encrypted entry point, the client performs an SSL/TLS handshake and checks the server certificate. There are two forms: one-way authentication (the client checks the server) and mutual authentication (mTLS) (the server checks the client's certificate as well). Certificates and the handshake are covered later in this chapter.

Terms at a glance

TermPlain EnglishIn one line
Listenerlistening endpointThe point where EMQX accepts client connections
TLStransport layer securityThe protocol that encrypts traffic in transit; SSL was its predecessor
Certificatedigital IDA digital proof of identity (X.509)
CAcertificate authorityThe body that issues certificates and vouches for them
mTLSmutual TLSThe server checks the client's certificate too
WebSocketbrowser transportThe MQTT channel a browser uses
Portnetwork port numberThe number a protocol comes in and goes out on

Hands-on

  1. Browse the existing listeners

    Log in to the Dashboard and open Management → Listeners in the sidebar. The listeners already there are listed, for example TCP (1883), SSL (8883), WebSocket (8083) and WSS (8084), each with its protocol and port. Use Add to create a new listener.

  2. Edit the SSL listener and swap in your certificates

    In the Listeners list, click the Name of the SSL listener (for example default) to open its edit page. There you can replace TLS Cert (the server certificate), TLS Key (its private key) and CA Cert (the trusted CA); by default EMQX uses the built-in test certificates (under etc/certs). Click Update when you are done.

  3. Turn the mTLS handshake on or off

    On the same page, the TLS Verify switch decides whether the client certificate is checked (mutual). To require mTLS, set TLS Verify to Enable and Fail If No Peer Cert to true; a client with no certificate then fails during the handshake.

  4. Deal with a port conflict

    If a port is taken (say 8083 is in use by WebRTC), stop the service that conflicts first, then go to the Listeners page, change that listener's port and click Update. Note: if the listener is defined in emqx.conf, a change made in the Dashboard only holds until the next EMQX restart.

The five ports and their protocols

Because the add-on runs in host_network mode on the Home Assistant host, these five ports are the host's own ports. Here is the mapping.

PortProtocolWhat it is for
1883MQTT (TCP)Standard MQTT; what Home Assistant and Zigbee use most
8083MQTT/WSMQTT over WebSocket (the browser test client uses this)
8084MQTT/WSSSecure WebSocket (a WebSocket encrypted with TLS)
8883MQTTSMQTT over SSL/TLS: standard MQTT, encrypted
18083HTTPThe EMQX Dashboard web interface

Per the docs, the MQTT path on a WebSocket listener defaults to /mqtt. You may have some devices on 1883 only and others on the encrypted 8883; anything running in a web browser goes to 8083 (or 8084 for the secure version). You do not have to keep all five in play — pick the one you actually need as each requirement comes up.

TLS, certificates and mTLS

TLS (Transport Layer Security) encrypts data at the transport layer. EMQX uses it for MQTT connections, for Data Integration reaching out to external resources, and between cluster nodes; each of those can be one-way or mutual. In one-way TLS the client checks the server's identity certificate; in mutual TLS (mTLS) the server checks the client's certificate as well, which blocks a man-in-the-middle attack.

SSL/TLS needs three files: certfile (the server certificate), keyfile (its private key) and cacertfile (the list of trusted CAs). EMQX ships with a set of certificates meant only for testing (under etc/certs), so the 8883 listener you see works out of the box as a one-way test setup. Before you go live, replace them with certificates issued by a trusted CA (your own domain plus a CA that clients already trust), and keep the private key readable only by the system and by you.

You implement mTLS by turning on TLS Verify on the SSL listener and setting Fail If No Peer Cert to true, which forces every client to present a trusted certificate during the handshake. EMQX also reloads certificates every 120 seconds by default, so replacing the server certificate does not always require an EMQX restart.

Port conflicts and migration

Because of host_network, these five ports share their numbers with the other services on the Home Assistant host, and two conflicts come up most often: the official README states plainly that it "cannot run at the same time as Mosquitto" (both want 1883), and WebRTC (AlexxIT) shares 8083 with EMQX.

The add-on README gives the procedure: stop the conflicting service (Mosquitto, say) first, then start EMQX. If you want both running, go to Management → Listeners, change the port on the listener that clashes or add a listener on a different port, then start that service again. You can also keep only the listeners you need (1883 and 8883, for example) and close the rest, which shrinks the attack surface exposed to scanners.

One note from the official docs is worth keeping in mind: if a listener is defined in emqx.conf, a change made in the Dashboard only holds until the next EMQX restart. To make a setting stick from startup onwards, use a config file or an environment variable (the add-on's EMQX_LISTENERS__* variables are covered in Chapter 17).

Troubleshooting

  • EMQX fails to start and the log says the port is already in use: work out which port it is, stop the Mosquitto (1883) or WebRTC (8083) that clashes, then start EMQX. If you want them to coexist long term, go to Listeners afterwards and change the port on one side.
  • 8883 stops accepting connections after a certificate change: check that certfile and keyfile are a matching pair, that the CA and the server certificate are in PEM format, and that the CN (or SAN) on the server certificate matches the address the client connects to (otherwise you get a Hostname/IP does not match certificate error). Use Reset in Listeners to go back to the test certificates and isolate the problem.
  • Every client without a certificate drops after you enable mTLS: that is what mTLS is meant to do — mutual authentication insists that the client present a trusted certificate. To relax it for now, set TLS Verify back to one-way, or issue that client a trusted client certificate first.
  • You changed a port in the Dashboard and the restart reverted it: the listener is almost certainly defined in emqx.conf, and a Dashboard change only holds until the restart. To make it permanent, override it at startup with the add-on's environment variables (EMQX_LISTENERS__*); Chapter 17 has the details.

FAQ

Do I have to open all five ports, or can I close some

You do not need all of them. Keep only the ports you actually use (1883 plus 18083, for example) and stop or renumber the WebSocket and SSL listeners. The fewer you run, the safer you are: every extra open port is extra attack surface.

8883 and 8084 sound alike, what is the difference

8883 is "standard MQTT, encrypted (MQTT over SSL/TLS)"; 8084 is "an encrypted WebSocket channel (MQTT over WSS)". Both encrypt the traffic; they differ in the transport underneath. The first is for native MQTT clients over TCP, the second for the WebSocket a browser uses. Their unencrypted counterparts are 1883 and 8083.

One-way or mTLS, which should I choose

Start with one-way: the client sends and receives encrypted and checks the server certificate, which is already enough to keep the traffic from being read. Move up to mTLS when you want "only devices holding a certificate you issued to get in", but prepare a certificate for every device first, or every device without one will be locked out.

Can I use a certificate I signed myself

For "testing", yes; for "production", no. What EMQX ships with is a test certificate, and the official docs say plainly that production needs a certificate issued by a trusted CA. A self-signed certificate also means installing your CA on every client before it will be trusted, which goes wrong easily in a home with many devices.

Official sources