RabbitMQ TLS Configuration: Enabling HTTPS on the Management UI and Encrypting AMQP Traffic

RabbitMQ runs two network interfaces that benefit from TLS: the AMQP port (5672) that carries messages between producers, consumers, and the broker, and the management plugin’s HTTP API and web UI (port 15672). This article covers enabling TLS on both, configuring clients, setting up mutual TLS for producer/consumer authentication, and renewing certificates without message loss.

What needs TLS in a RabbitMQ deployment

InterfaceDefault portTLS portWhat it carries
AMQP56725671Application messages, connection credentials
AMQP over WebSocket1567415673Same, for browser-based clients
Management HTTP API1567215671Admin credentials, queue stats, configuration
MQTT18838883IoT device messages
STOMP6161361614STOMP protocol messages

Most deployments need TLS on AMQP and the management UI at minimum.

Generating or obtaining certificates

All RabbitMQ TLS configuration references PEM files on disk. You need:

  • ca.crt — the CA certificate clients will use to verify the server
  • server.crt — the RabbitMQ server certificate (full chain)
  • server.key — the private key

For Let’s Encrypt:

certbot certonly --standalone -d rabbitmq.example.com

For an internal CA:

openssl genrsa -out /etc/rabbitmq/server.key 4096
openssl req -new -key /etc/rabbitmq/server.key \
  -out /etc/rabbitmq/server.csr \
  -subj "/CN=rabbitmq.example.com"

openssl x509 -req -in /etc/rabbitmq/server.csr \
  -CA /etc/pki/ca/ca.crt -CAkey /etc/pki/ca/ca.key \
  -CAcreateserial -out /etc/rabbitmq/server.crt \
  -days 365 \
  -extfile <(echo "subjectAltName=DNS:rabbitmq.example.com")

cp /etc/pki/ca/ca.crt /etc/rabbitmq/ca.crt

Set permissions:

chown rabbitmq:rabbitmq /etc/rabbitmq/server.key /etc/rabbitmq/server.crt /etc/rabbitmq/ca.crt
chmod 640 /etc/rabbitmq/server.key
chmod 644 /etc/rabbitmq/server.crt /etc/rabbitmq/ca.crt

Configuring TLS in rabbitmq.conf

RabbitMQ’s configuration file is at /etc/rabbitmq/rabbitmq.conf. This is the new-style sysctl format (not the Erlang term format used in older versions).

Enable TLS on AMQP (5671)

# Disable plaintext AMQP (recommended for production)
listeners.tcp = none

# Enable TLS AMQP on port 5671
listeners.ssl.default = 5671

ssl_options.cacertfile = /etc/rabbitmq/ca.crt
ssl_options.certfile   = /etc/rabbitmq/server.crt
ssl_options.keyfile    = /etc/rabbitmq/server.key

# Minimum TLS version
ssl_options.versions.1 = tlsv1.2
ssl_options.versions.2 = tlsv1.3

# Strong cipher suites only
ssl_options.ciphers.1 = TLS_AES_256_GCM_SHA384
ssl_options.ciphers.2 = TLS_CHACHA20_POLY1305_SHA256
ssl_options.ciphers.3 = ECDHE-RSA-AES256-GCM-SHA384

# Require peer (client) certificate verification for mutual TLS
# ssl_options.verify               = verify_peer
# ssl_options.fail_if_no_peer_cert = true

Enable HTTPS on the management plugin (15671)

# Disable plaintext management port
management.tcp.port = none

# Enable HTTPS management on port 15671
management.ssl.port       = 15671
management.ssl.cacertfile = /etc/rabbitmq/ca.crt
management.ssl.certfile   = /etc/rabbitmq/server.crt
management.ssl.keyfile    = /etc/rabbitmq/server.key

Restart RabbitMQ and verify

sudo systemctl restart rabbitmq-server
sudo systemctl status rabbitmq-server

# Check listening ports
sudo ss -tlnp | grep -E "5671|15671"

Verify the TLS AMQP port is responding:

openssl s_client -connect rabbitmq.example.com:5671 -servername rabbitmq.example.com </dev/null 2>&1 \
  | openssl x509 -noout -dates -subject

Verify the management HTTPS port:

curl --cacert /etc/rabbitmq/ca.crt https://rabbitmq.example.com:15671/api/overview \
  -u guest:guest | python3 -m json.tool | head -20

Connecting clients to TLS-enabled RabbitMQ

Python (pika)

import pika
import ssl

context = ssl.create_default_context(cafile='/etc/rabbitmq/ca.crt')
context.verify_mode = ssl.CERT_REQUIRED

ssl_options = pika.SSLOptions(context=context, server_hostname='rabbitmq.example.com')

credentials = pika.PlainCredentials('appuser', 'password')
parameters = pika.ConnectionParameters(
    host='rabbitmq.example.com',
    port=5671,
    credentials=credentials,
    ssl_options=ssl_options
)

connection = pika.BlockingConnection(parameters)
channel = connection.channel()
print("Connected via TLS:", connection.is_open)

Java (Spring AMQP)

@Bean
public ConnectionFactory connectionFactory() throws Exception {
    CachingConnectionFactory factory = new CachingConnectionFactory();
    factory.setHost("rabbitmq.example.com");
    factory.setPort(5671);
    factory.setUsername("appuser");
    factory.setPassword("password");

    factory.getRabbitConnectionFactory().useSslProtocol(
        createSslContext()
    );
    return factory;
}

private SSLContext createSslContext() throws Exception {
    KeyStore trustStore = KeyStore.getInstance("JKS");
    trustStore.load(new FileInputStream("/etc/app/rabbitmq-truststore.jks"), "trustpass".toCharArray());
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
    tmf.init(trustStore);
    SSLContext ctx = SSLContext.getInstance("TLSv1.3");
    ctx.init(null, tmf.getTrustManagers(), null);
    return ctx;
}

.NET (RabbitMQ.Client)

var sslOption = new SslOption
{
    Enabled = true,
    ServerName = "rabbitmq.example.com",
    CertificateValidationCallback = null, // use system trust store
    // Or specify a custom CA:
    // CertPath = "/etc/app/rabbitmq-ca.crt",
    Version = SslProtocols.Tls13
};

var factory = new ConnectionFactory
{
    HostName = "rabbitmq.example.com",
    Port = 5671,
    UserName = "appuser",
    Password = "password",
    Ssl = sslOption
};

Mutual TLS — authenticating clients by certificate

Mutual TLS lets RabbitMQ verify that clients hold a certificate signed by a trusted CA. This is useful for service-to-service connections where you want to avoid password authentication entirely.

Server-side configuration

In rabbitmq.conf:

ssl_options.verify               = verify_peer
ssl_options.fail_if_no_peer_cert = true

Generating client certificates

# For each service/client
openssl genrsa -out /etc/app/client.key 4096
openssl req -new -key /etc/app/client.key \
  -out /etc/app/client.csr \
  -subj "/CN=my-service/O=example"

openssl x509 -req -in /etc/app/client.csr \
  -CA /etc/pki/ca/ca.crt -CAkey /etc/pki/ca/ca.key \
  -CAcreateserial -out /etc/app/client.crt -days 365

RabbitMQ external auth plugin (mapping certificate CN to user)

Enable the auth mechanism plugin so certificate CN maps to RabbitMQ users:

rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl

Add to rabbitmq.conf:

auth_mechanisms.1 = EXTERNAL
ssl_cert_login_from = common_name

Create a RabbitMQ user with the same name as the CN:

rabbitmqctl add_user my-service ""
rabbitmqctl set_permissions -p / my-service ".*" ".*" ".*"

Now my-service can connect with its client certificate without a password.

Python client with mutual TLS

context = ssl.create_default_context(cafile='/etc/app/ca.crt')
context.load_cert_chain(certfile='/etc/app/client.crt', keyfile='/etc/app/client.key')
context.verify_mode = ssl.CERT_REQUIRED

Certificate renewal without message loss

RabbitMQ reads certificate files at startup and on reload. Replacing a certificate with zero downtime requires:

  1. Copy the new certificate and key into place (same filenames):
cp new-server.crt /etc/rabbitmq/server.crt
cp new-server.key /etc/rabbitmq/server.key
chown rabbitmq:rabbitmq /etc/rabbitmq/server.crt /etc/rabbitmq/server.key
chmod 640 /etc/rabbitmq/server.key
  1. Reload RabbitMQ without dropping active connections:
rabbitmqctl eval 'ssl:clear_pem_cache().'

This clears RabbitMQ’s internal TLS/PEM cache. New connections will use the updated certificate immediately. Existing connections continue until they reconnect.

For a full restart (required on older RabbitMQ versions):

sudo systemctl restart rabbitmq-server

Brief downtime occurs during the restart. Applications with retry logic and durable queues will recover automatically.

Let’s Encrypt renewal hook

sudo nano /etc/letsencrypt/renewal-hooks/deploy/rabbitmq.sh
#!/bin/bash
DOMAIN=rabbitmq.example.com
DEST=/etc/rabbitmq

cp /etc/letsencrypt/live/${DOMAIN}/fullchain.pem ${DEST}/server.crt
cp /etc/letsencrypt/live/${DOMAIN}/privkey.pem   ${DEST}/server.key
cp /etc/letsencrypt/live/${DOMAIN}/chain.pem     ${DEST}/ca.crt

chown rabbitmq:rabbitmq ${DEST}/server.crt ${DEST}/server.key ${DEST}/ca.crt
chmod 640 ${DEST}/server.key
chmod 644 ${DEST}/server.crt ${DEST}/ca.crt

# Clear TLS cache without full restart
rabbitmqctl eval 'ssl:clear_pem_cache().'
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/rabbitmq.sh

Troubleshooting

SymptomCauseFix
{tls_alert,{unknown_ca,...}}Client does not trust server CADistribute CA cert to client
{tls_alert,{certificate_required,...}}Mutual TLS required, client sent no certAdd client cert to application config
Management UI unreachable on 15671HTTPS not configured for management pluginAdd management.ssl.* config block
handshake_failure after upgradeTLS version mismatch (TLS 1.0/1.1 disabled)Upgrade client library or adjust ssl_options.versions
failed to open certificate fileWrong path or permissionsCheck path and chown rabbitmq

Summary

RabbitMQ TLS is configured in rabbitmq.conf by setting listeners.ssl.default and certificate paths for AMQP, and management.ssl.* for the web UI. Disabling the plaintext ports (listeners.tcp = none) prevents accidental unencrypted connections. For stronger security, enable mutual TLS with ssl_options.verify = verify_peer and issue per-service client certificates. Certificate renewal is non-disruptive using rabbitmqctl eval 'ssl:clear_pem_cache().' on modern RabbitMQ versions.

Scroll to Top