Configuring TLS support on RabbitMQ

One year ago I wrote a series of posts about RabbitMQ and how to implement a publisher and a consumer.

Now we’ll see how to enable the TLS protocol on RabbitMQ, that is high recommended when the server is published on internet and the communication between the server and the clients must be encrypted.

The configuration is composed of two activities:

• Enabling server side configuration
• Changing the client side connection parameters

Server

First of all, the server side configuration needs TLS certificates, that are the root certificate and the server private and public keys; these certificates must be copied in the home directory (or a subdirectory) of the server.

After that we need to create or modify the rabbitmq.conf file, that is the same directory; the TLS settings are:


#listeners.tcp.default = 5672
listeners.tcp = none
listeners.ssl.default = 5671
ssl_options.cacertfile = path\\to\\cacert.pem
ssl_options.certfile = path\\to\\server_cert.pem
ssl_options.keyfile = path\\to\\server_key.pem
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false



With the first and the second rows we can enable/disable the tcp connection and apply a conservative solution in order to guarantee the communication with the clients that haven’t changed the parameters yet.

When we are sure that there are no longer active connetions on the tcp port, we can close it (listeners.tcp = none).

The other parameters are about ssl connections; we need to specify the port and the certificate relative paths; we can enable the peer verification, that means checking that the certificate presented in the TLS negotiation is trusted based on the root ca (ssl_options.verify); we can define if the clients have to provide it’s own certificate or not (ssl_options.fail_if_no_peer_cert).

Client

The client side changes are about the endpoints connections:


public static readonly List<AmqpTcpEndpoint> AmqpTcpEndpoints = new List<AmqpTcpEndpoint>()
{
new AmqpTcpEndpoint()
{
HostName = ConfigurationManager.AppSettings["RabbitMQHostname1"],
Port = Porta,
Ssl = new SslOption() {
ServerName = ConfigurationManager.AppSettings["RabbitMQHostname1"],
Enabled = true,
AcceptablePolicyErrors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors
}
},
new AmqpTcpEndpoint()
{
HostName = ConfigurationManager.AppSettings["RabbitMQHostname2"],
Port = Porta,
Ssl = new SslOption() {
ServerName = ConfigurationManager.AppSettings["RabbitMQHostname2"],
Enabled = true,
AcceptablePolicyErrors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors
}
}
};



We have to specify the port (5671), and the SSL options:

• the server name
• if the SSL connection is enabled
• An optional setting about the acceptable policy errors

When we configure a TLS connection we can be in two different situations; if our root certificate is signed by a known certification autority, we have nothing to do; but, if the root certificate is self signed, we have to install it in the trusted certificates of the client machine:

Obviously this is the recommended approach but in case when we are unable to do that (for example thousand workstations where the user as no privileges) we can tell the client to ignore certificate errors by enabling the policy SslPolicyErrors.RemoteCertificateChainErrors.

At the end of these operations, we can open the admin console of the server and we’ll see the connections with SSL protocol enabled: