Clustering Communication using TLS (SSL)

Sometimes is desirable to make the Erlang nodes talk to each other using TLS (SSL), and thus make the whole RabbitMQ cluster communication via TLS. To achieve that we need to make the Erlang distribution mechanism to use TLS. In this document we are going to review the steps to make this possible.


First we need to create the TLS certificate that's going to be used by the Erlang distribution mechanism. We assume you have done that already, otherwise follow the guide here. Once we have our certificates ready we need to concatenate the server certificate and key into one file, for example, assuming we have the files server_certificate.pem and server_key.pem we can do the following:

cat server_certificate.pem server_key.pem > rabbit.pem

Then we have to tell Erlang where to find the ssl library during startup. We can create a variable like this:

echo `erl -eval 'io:format("~p", [code:lib_dir(ssl, ebin)]),halt().' -noshell`
export ERL_SSL_PATH=/path/to/erl/lib/ssl-5.3.5/ebin

There first we find where Erlang has the ssl library, and then the variable ERL_SSL_PATH is set with the result from the first command without the double quotes.

By using the previous information now is time to craft the $RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS environment variable so RabbitMQ is able to start Erlang using TLS for distribution. We do that by setting the proto_dist argument to inet_tls and then telling Erlang what certificate to use (in our case that's the rabbit.pem file we just created). Finally we set secure renegotiation to true. Here's the whole command:

-proto_dist inet_tls \
-ssl_dist_opt server_certfile /path/to/rabbit.pem \
-ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true

Keep in mind that every Erlang program that tries to communicate with our RabbitMQ server by using Erlang's distribution must now use TLS as well. One of such programs is rabbitmqctl that we use for administering RabbitMQ. This means we have to do what we just did for $RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS but this time for the environment variable RABBITMQ_CTL_ERL_ARGS.

Now that we have this in place, it's just a matter of starting RabbitMQ as we usually do to get the Erlang distribution to use TLS for internode communication. Keep in mind that other nodes in the cluster that want to join our initial node must use the same certificate and the same RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS arguments. The same applies for rabbitmqctl.


If you are using the OSX Standalone Release, then you need to add some extra arguments in order to run the erl command to find the path of Erlang's TLS library. Assuming you are inside the folder where you installed the standalone release, the commands will look like these:

echo erts-6.1/bin/erl -boot releases/3.4.3/start_clean \
-eval 'io:format("~p", [code:lib_dir(ssl, ebin)]),halt().' -noshell
export ERL_SSL_PATH=/path/to/erl/lib/ssl-5.3.5/ebin

The difference is that we need to specify the path to the erl executable and also provide a path to a boot file, which in our case is inside the releases folder of our standalone installation.

Once you have ran the previous commands, then you can proceed to create the environment variables as explained above on the Linux section


Coming soon.