Skip to content

Enable TLS for RabbitMQ

Severity: highApplies to: RabbitMQ 3.x / 4.x
The fix/etc/rabbitmq/rabbitmq.conf
listeners.ssl.default = 5671
listeners.tcp = none # no plaintext AMQP
ssl_options.cacertfile = /etc/rabbitmq/tls/ca.pem
ssl_options.certfile = /etc/rabbitmq/tls/server.pem
ssl_options.keyfile = /etc/rabbitmq/tls/server.key
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false
ssl_options.versions.1 = tlsv1.3
ssl_options.versions.2 = tlsv1.2
Terminal window
sudo systemctl restart rabbitmq-server

Without TLS, RabbitMQ sends the AMQP authentication and every message body in cleartext. Message brokers carry exactly the data you’d least like on the wire — job payloads, user events, and frequently credentials and tokens inside those messages. Anyone on the network path reads all of it.

RabbitMQ’s own auth is undermined by plaintext transport too: the username and password are sent in the clear on connect, so a hardened user model is only as private as the link underneath it.

The now-familiar trap, and RabbitMQ makes it easy to fall into: adding listeners.ssl.default = 5671 adds a TLS listener. It does not remove the plaintext one on 5672. A broker with both is not protected — a client connects to 5672 in the clear and is accepted.

listeners.tcp = none is what closes it. Do that once every client speaks TLS, and confirm with rabbitmq-diagnostics listeners rather than assuming — see network listeners.

RabbitMQ’s TLS options are frequently misconfigured because two settings interact in a way that isn’t obvious:

Setting Effect
verify = verify_none Encrypt, but don’t check the client’s certificate
verify = verify_peer Check the client certificate if one is presented
fail_if_no_peer_cert = true Require a client certificate — reject connections without one

The combination that means “mutual TLS, client certs required” is verify = verify_peer and fail_if_no_peer_cert = true. verify_peer alone does not require a client cert — it only validates one if the client happens to send it, so a client with no certificate still connects. That surprises people who set verify_peer believing they’d mandated client certificates.

If you only want server-authenticated TLS (encryption, server identity verified by the client, but no client certs), verify_peer with fail_if_no_peer_cert = false is correct and far easier to operate. Mutual TLS is stronger but means issuing and rotating a certificate per client.

The client side matters too: a client must be configured to verify the server certificate (verify_peer on its end, with the CA), or it encrypts without checking who it’s talking to — the same sslmode=require vs verify-full distinction as Postgres.

RabbitMQ refuses to start if keyfile is too permissive:

Terminal window
sudo chown rabbitmq:rabbitmq /etc/rabbitmq/tls/server.key
sudo chmod 400 /etc/rabbitmq/tls/server.key

A key readable by other users is both a startup failure and a real exposure.