← News
/PLAYBOOK · 2026-08-16

RabbitMQ Security Hardening: Unauthorized Access Prevention

Default guest/guest and open management ports are the usual RabbitMQ unauthorized-access path. Full config: account hardening, permission lockdown, TLS, and firewall restrictions.

Scope

Backend services using RabbitMQ as middleware, especially on cloud VMs and container clusters. Queues carry orders, payments, logs. Unauthorized access lets an attacker read, mutate, or purge queues — data leak and outage. Applies to RabbitMQ 3.8.x / 3.12.x / 4.x. Hardens both the AMQP port and the management plugin HTTP port.

Prerequisites

Why this happens

Three usual causes of RabbitMQ unauthorized access. One: default `guest`/`guest` is localhost-only, but many deploys open it or never create a dedicated user. Two: management plugin port 15672 and AMQP 5672 exposed to the internet; a weak password finishes the login. Three: no vhost/permission isolation — one account reaches every queue. RabbitMQ also had a management-plugin path traversal (CVE-2019-18674). Closing the public attack surface is the cheapest mitigation.

Steps

1. Kill guest, create a dedicated user

# delete guest (do this in production)
rabbitmqctl delete_user guest

# create a dedicated service user with a strong password
rabbitmqctl add_user order_service '<strong-password>'

# management tag (only if admin UI is needed)
rabbitmqctl set_user_tags order_service management

# permissions: restrict to the target vhost
rabbitmqctl set_permissions -p / order_service '^order\.' '^order\.' '^order\.'

2. vhost isolation, least privilege

# independent vhost per business domain
rabbitmqctl add_vhost order_vhost
rabbitmqctl add_vhost payment_vhost

# least privilege: conf / write / read, open only what you need
rabbitmqctl set_permissions -p order_vhost order_service '^order\.' '^order\.' '^order\.'

Permission args are configure / write / read, in that order. Regex limits resource names. Use `^prefix\.` everywhere to block cross-app access.

3. Bind management off the public internet

Edit `/etc/rabbitmq/rabbitmq.conf`:

# management UI: listen on loopback only
management.tcp.port = 15672
management.tcp.ip = 127.0.0.1

# AMQP: same lockdown
listeners.tcp.default = 5672
listeners.tcp.local = 10.0.0.10:5672

If management is localhost-ops only, front it with Nginx plus extra auth; same pattern as the previous section. Also restrict at the firewall:

firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=10.0.1.0/24 port port=5672 protocol=tcp accept'
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=10.0.1.0/24 port port=15672 protocol=tcp accept'
firewall-cmd --reload

4. Enable TLS

# self-signed cert (use a trusted CA in production)
openssl req -x509 -nodes -newkey rsa:2048 -keyout /etc/rabbitmq/certs/server.key   -out /etc/rabbitmq/certs/server.crt -days 365 -subj "/CN=rabbitmq.example.com"
openssl dhparam -out /etc/rabbitmq/certs/dhparam.pem 2048
# append to rabbitmq.conf
listeners.ssl.default = 5671
ssl_options.cacertfile = /etc/rabbitmq/certs/server.crt
ssl_options.certfile   = /etc/rabbitmq/certs/server.crt
ssl_options.keyfile    = /etc/rabbitmq/certs/server.key
ssl_options.verify     = verify_none
ssl_options.fail_if_no_peer_cert = false

After restart, clients use `amqps://` on 5671. Production should set `verify = verify_peer` and configure a CA for mutual TLS.

5. Disable unused plugins

# list enabled plugins
rabbitmq-plugins list

# keep only what you need; drop unused protocol plugins (MQTT/STOMP)
rabbitmq-plugins disable rabbitmq_mqtt
rabbitmq-plugins disable rabbitmq_stomp

# restart
systemctl restart rabbitmq-server

Verify

# 1. listen ports (15672 should be localhost/internal only)
ss -tlnp | grep -E '5672|15672'

# 2. unauthorized AMQP should be refused
rabbitmqctl list_users
rabbitmqctl list_permissions -p order_vhost

# 3. from an external host: 15672 must not connect (firewall drop)
nc -zv 10.0.0.10 15672

# 4. TLS port
openssl s_client -connect 10.0.0.10:5671 -servername rabbitmq.example.com </dev/null | head -5

FAQ

Q1: Auth fails after deleting guest?

Client is still using guest/guest. Connect with the user from `rabbitmqctl add_user`, and confirm `set_permissions` on the target vhost. For leftover services, prove the new account in a test env, then cut over.

Q2: Old clients fail after TLS?

TLS and plaintext can coexist. Keep `listeners.tcp.default = 5672` for internal plaintext (firewall allowlist), add 5671 for cross-segment encrypted traffic. Migrate clients, then kill plaintext. Do not force `verify_peer` on production clients until the cert chain is verified.

Summary

RabbitMQ hardening is account lockdown + least privilege + network lockdown + transport encryption: delete default guest, dedicated users isolated by vhost, management listen internal-only plus firewall allowlist, TLS on production paths. Pair with regular upgrades and plugin minimization to cut unauthorized access and queue tampering risk.