Skip to content

Protect the RabbitMQ Erlang cookie

Severity: highApplies to: RabbitMQ 3.x / 4.x
The fix
Terminal window
# A strong cookie, identical on every node, readable only by rabbitmq
openssl rand -base64 42 | tr -d '\n' | sudo tee /var/lib/rabbitmq/.erlang.cookie
sudo chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie
sudo chmod 400 /var/lib/rabbitmq/.erlang.cookie
sudo systemctl restart rabbitmq-server

Erlang nodes authenticate to each other with a shared secret called the cookie — a string in ~/.erlang.cookie for the account running the node (/var/lib/rabbitmq/.erlang.cookie for RabbitMQ). Two nodes with the same cookie trust each other; two with different cookies can’t cluster.

The critical part: Erlang node-to-node trust is total. Once a node authenticates with the right cookie, the distribution protocol lets it evaluate arbitrary code on the other node. That’s not a vulnerability — it’s how Erlang clustering is designed to work, and it’s extremely powerful.

Which means the cookie is not a clustering detail. It is the credential that grants code execution as the rabbitmq user to anyone who has it and can reach the distribution port (25672).

Two failures make that catastrophic:

  • A weak or default cookie. Some packages and container images generate a predictable cookie, or people set a memorable one like SECRET_COOKIE. An attacker who can reach 25672 and guess or know the cookie connects an Erlang node and runs commands.
  • A world-readable cookie file. If any local user can read /var/lib/rabbitmq/.erlang.cookie, a compromise of any account on the host escalates to the RabbitMQ node — and, on a cluster, to every node sharing it.

The cookie should be long and random:

Terminal window
openssl rand -base64 42 | tr -d '\n'

And the file must be readable only by the RabbitMQ user:

Terminal window
sudo chmod 400 /var/lib/rabbitmq/.erlang.cookie
sudo chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie

400 matters. A 644 cookie file is the same class of problem as a world-readable private key: the secret is present but unprotected.

Every node, identical; between clusters, different

Section titled “Every node, identical; between clusters, different”

On a cluster, every node must have the exact same cookie — that’s what lets them trust each other. Distribute it over a secure channel (configuration management with an encrypted secret, not a copy-paste in Slack), and never commit it to a repository.

Separate clusters should have different cookies. A shared cookie across unrelated brokers means compromising one gives code execution on all of them — turning a blast radius you thought was one broker into your whole messaging estate.

Containers are the common trap: a RABBITMQ_ERLANG_COOKIE environment variable is visible in docker inspect, in the process environment, and often in the image’s build history. Prefer a mounted file with correct permissions over the env var.