Using SSL

Whenever the RabbitMQ broker is exposed to the Internet, it is highly advisable to protect the connections by using the SSL library.

RabbitMQ does not implement SSL by itself, but it uses the certificate mechanism of the given language, Erlang for the server and Java, .NET, or whatever for the clients.

Here, we will see how to have a basic protection with SSL, that is, how to encrypt the connections from the RabbitMQ clients to the broker.

This is enough to avoid simple security attacks. With no SSL, usernames and passwords are sent just in clear through the network.

Getting ready

The current example has the following prerequisites:

  • A Linux OS hosting the RabbitMQ broker
  • openssl Linux package
  • The latest Erlang distribution—at least R14B
  • Java JDK on the client, either on Linux or Windows

We have chosen to limit this recipe to just Linux on the server side because on Windows, there are too many version combinations—some with limited or no functionality at all. It is a good idea to run your secured Internet facing RabbitMQ servers on Linux or a Unix OS.

For more information on Windows support, you can go to http://www.rabbitmq.com/ssl.html.

How to do it…

Perform the following steps to set up the Certificate Authority and configure the server:

  1. On the server, create the Certificate Authority (CA) directory stub as per the script in the example path Chapter03/Recipe03/certificates/01_setup_CA.sh:
    mkdir testca
    cd testca
    mkdir certs private
    chmod 700 private
    echo 01 > serial
    touch index.txt
  2. Customize the openssl configuration file, which you can already find in Chapter03/Recipe03/certificates/testca/openssl.cnf.
  3. Create the self-signed CA certificates as done in Chapter03/Recipe03/certificates/02_create_CA_certificates.sh:
    openssl req -x509 -config openssl.cnf -newkeyrsa:2048 -days 365 -out cacert.pem -outform PEM -subj /CN=MyTestCA/ -nodes
    openssl x509 -in cacert.pem -out cacert.cer -outform DER
  4. Create the RabbitMQ server private key as in Chapter03/Recipe03/certificates/03_create_server_certificates.sh:
    openssl genrsa -out key.pem 2048
  5. Create the server certificate request:
    openssl req -new -key key.pem -out req.pem -outform PEM -subj /CN=$(hostname)/O=server/ -nodes
  6. In the CA directory, sign the request to obtain the signed certificate:
    openssl ca -config openssl.cnf -in ../server/req.pem –out ../server/cert.pem -notext -batch –extensions server_ca_extensions
  7. Copy from Chapter03/Recipe03/certificates, the CA certificate, the server certificate, and the server private key, which we have just created, to the absolute paths:
    /usr/local/certificates/testca/cacert.pem
    /usr/local/certificates/server/cert.pem
    /usr/local/certificates/server/key.pem
  8. Create the RabbitMQ configuration file, rabbitmq.config, in the appropriate directory (/etc/rabbitmq) by copying it from Chapter03/Recipe03/rabbitmq.config:
    [
    {rabbit, [
    {ssl_listeners, [5671]},
    {ssl_options, [
    {cacertfile,"/usr/local/certificates/testca/cacert.pem"},
    {certfile,"/usr/local/certificates/server/cert.pem"},
    {keyfile,"/usr/local/certificates/server/key.pem"},
    {verify,verify_peer},
    {fail_if_no_peer_cert,false}]}
    ]}
    ].
  9. Restart the RabbitMQ server:
    rabbitmqctl stop
    rabbitmq-server–detached.

    When you restart a RabbitMQ node, the Erlang Node will also restart.

  10. In the Java client, the connection to the server is now made, as shown in Chapter03/Recipe03/src/rmqexample/Publish.java:
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost(hostname);
    factory.setPort(5671);
    factory.useSslProtocol();
    Connection connection = factory.newConnection();

How it works…

We started this recipe by creating a CA with which we will sign the certificates for the server.

We have performed this step on the server, but in the real world, the CA and, in particular, its private key (created in step 3) should be kept separate.

After the CA is ready, we have to prepare the server certificate as shown in steps 4-6.

We are almost done. We just need to copy the CA certificate, the server certificate, and the server public key to the final path (step 7). We have chosen to store them in /usr/local/certificates, but it is totally arbitrary since they are referenced in the RabbitMQ configuration file, rabbitmq.config.

This file does not exist by default. It must be placed in the standard configuration directory, usually in /etc/rabbitmq.

Apart from the security files, we have configured the RabbitMQ SSL port (5671), and a couple of options in rabbitmq.config:

  • Verify: When this is set to verify_peer, it tells RabbitMQ that if the client presents a certificate, it will be checked and rejected if not valid (because the CA is not the same or because it is expired)
  • fail_if_no_peer_cert: When this is set to false, it tells RabbitMQ to accept clients that do not present any certificate at all

After we have restarted RabbitMQ (you must use rabbitmqctl stop and restart the service), you can verify whether it has got the options by examining the logfile in /var/log/rabbitmq. You should be able to find a line as follows:

started SSL Listener on [::]:5671

Furthermore, by opening the management plugin from a browser, you will be able to get similar information (see the Managing RabbitMQ from a browser recipe), as shown in the following screenshot:

How it works…

At this point it is possible to connect via SSL from a client by just adding these two options to the connection factory:

factory.setPort(5671);
factory.useSslProtocol();

Now the connection is encrypted using the keys configured in the server.

There's more…

Since we are using server certificates only, the communication between the server and the client is encrypted, but we are not protected against MITM (man-in-the-middle) attacks.

If we want to let any client connect to the server and avoid MITM attacks, we can use the same strategy as that used by HTTPS and the browsers, which is signing the certificates with trusted third-party CAs and verifying the domain signed in the certificates. Otherwise, we can just go on and read the next recipe.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset