Sunday, January 27, 2013

Configuring SSL for RabbitMQ

This is an article in the RabbitMQ Configuration and Management Series.  For more articles like this, please visit the series' index.

Configuring RabbitMQ for SSL is a fairly straight forward process. It involves generating the certificates and key file for the server to perform SSL, and registering those files with RabbitMQ via the rabbitmq.config file.

Generating Certificates

The difficult part of this process is knowing how to generate and manage Public-Key Infrastructure. If you are unfamiliar with this process, or work in an organization that already has it's own infrastructure, we would recommend you consult with whomever manages that infrastructure to get the correct keys and certificates.
In the event that you need to do this work on your own, we have a created a set of scripts that will simplify the process. These scripts literally automate the process documented by RabbitMQ on this page.
  1. Install git on a machine of your choice. This does not have to be on one of the cluster nodes, but you will have to copy files to each broker if you do not.
    sudo yum install git
  2. Clone the CMF-AMQP-Configuration repository.
    git clone https://github.com/Berico-Technologies/CMF-AMQP-Configuration.git
    Change into the CMF-AMQP-Configuration/ssl/ directory:
    cd CMF-AMQP-Configuration/ssl/
    In this directory you will find the following files:
  • openssl.cnf: This is the OpenSSL configuration file.
  • setup_ca.sh: This will setup the Certificate Authority you will need to generate and issue client and server certificates from.
  • make_server_cert.sh: This will generate a certificate for a server (like a RabbitMQ Broker).
  • create_client_cert.sh: This will generate a certificate for a client application (connecting to a RabbitMQ Broker).
  • implode.sh: This will remove all directories and content generated by the other scripts, but it will not delete the scripts of configuration.
    If you choose to fork this configuration in GitHub, the .gitignore file in this directory will prevent the inclusion of the certificate files.
  1. Edit the openssl.cnf file (as needed).
    Here you can specify default values for the certificate. Please see the OpenSSL documentation to get a full list of values.
    By default, this file will force a SHA1 2048-bit key good for 1 year.
  2. Generate a Certificate Authority.
    You may need to use sudo depending on where you put the project.
    sh setup_ca.sh [certificate authority common name (CN)]
    For example:
    sh setup_ca.sh OfficeMagiCA
  3. Generate a Server Certificate.
    You may need to use sudo depending on where you put the project.
    sh make_server_cert.sh [hostname] [password]
    For example:
    sh make_server_cert.sh rabbit3 rabbit
  4. (Optional) Generate a Client Certificate
    This will not be used during this portion of the tutorial.
    You may need to use sudo depending on where you put the project.
    sh create_client_cert.sh [client name] [password]
    For example:
    sh create_client_cert.sh rabbit-client1 rabbit
  5. Copy the certificates to your RabbitMQ Broker.
    The previous processes will have generated a lot of files that you will not need at the Broker. Many of these files were created in the process of generating certificate signing requests (CSR), where a server or client certificate is "stamped" by the CA to establish a "chain of trust".
    For this tutorial, we will need the following certificates:
  • ca/cacert.pem: The Certificate Authority's certificate.
  • server/{hostname}.cert.pem: The Server/Broker's certificate.
  • server/{hostname}.key.pem: The Server/Broker's private key.
    Protect the *.key.pem at all costs! This is literally the password to the certificate (i.e.: don't give this out).
    We have taken the convention of storing the certificates in a folder called ssl located in the RabbitMQ configuration directory (/etc/rabbitmq/).
    Preserving the structure created by the CMF-AMQP-Configuration project, copy those files into the directory:
    sudo mkdir -p /etc/rabbitmq/ssl/ca
    sudo mkdir /etc/rabbitmq/ssl/server
    sudo cp {/path/to/CMF-AMQP-Configuration/ssl/}ca/cacert.pem \
      /etc/rabbitmq/ssl/ca/cacert.pem
    sudo cp {/path/to/CMF-AMQP-Configuration/ssl/}server/{hostname}.key.pem \
      /etc/rabbitmq/ssl/server/{hostname}.key.pem
    sudo cp {/path/to/CMF-AMQP-Configuration/ssl/}server/{hostname}.cert.pem \
      /etc/rabbitmq/ssl/server/{hostname}.cert.pem

    Using our example, it looks like:
    sudo mkdir -p /etc/rabbitmq/ssl/ca
    sudo mkdir /etc/rabbitmq/ssl/server
    sudo cp {/path/to/CMF-AMQP-Configuration/ssl/}ca/cacert.pem \
      /etc/rabbitmq/ssl/ca/cacert.pem
    sudo cp {/path/to/CMF-AMQP-Configuration/ssl/}server/rabbit3.key.pem \
      /etc/rabbitmq/ssl/server/rabbit3.key.pem
    sudo cp {/path/to/CMF-AMQP-Configuration/ssl/}server/rabbit3.cert.pem \
      /etc/rabbitmq/ssl/server/rabbit3.cert.pem
    

Configuring RabbitMQ to support SSL Connections

To configure RabbitMQ to support SSL, you simply need to add some minor configuration options to the rabbitmq.config in the/etc/rabbitmq directory.
If the file doesn't exist, we simply need to create it and RabbitMQ will pick up those changes upon start/restart.
  1. Edit the rabbitmq.config file:
    sudo vi /etc/rabbitmq/rabbitmq.config
  2. Add the following configuration:
    {rabbit, [ {tcp_listeners, [5672] },
               {ssl_listeners, [5673] },
               {ssl_options, [
                 {cacertfile, "/etc/rabbitmq/ssl/ca/cacert.pem" },
                 {certfile, "/etc/rabbitmq/ssl/server/{hostname}.cert.pem" },
                 {keyfile, "/etc/rabbitmq/ssl/server/{hostname}.key.pem" },
                 {verify, verify_peer},
                 {fail_if_no_peer_cert, false }]}
    ]}
    ].
    
    Where our configuration looks like:
    {rabbit, [ {tcp_listeners, [5672] },
               {ssl_listeners, [5673] },
               {ssl_options, [
                 {cacertfile, "/etc/rabbitmq/ssl/ca/cacert.pem" },
                 {certfile, "/etc/rabbitmq/ssl/server/rabbit3.cert.pem" },
                 {keyfile, "/etc/rabbitmq/ssl/server/rabbit3.key.pem" },
                 {verify, verify_peer},
                 {fail_if_no_peer_cert, true }]}
    ]}
    ].
    
    And if you are already clustered with iptables configured:
    {rabbit, [ {tcp_listeners, [5672] },
               {ssl_listeners, [5673] },
               {ssl_options, [
                 {cacertfile, "/etc/rabbitmq/ssl/ca/cacert.pem" },
                 {certfile, "/etc/rabbitmq/ssl/server/rabbit3.cert.pem" },
                 {keyfile, "/etc/rabbitmq/ssl/server/rabbit3.key.pem" },
                 {verify, verify_peer},
                 {fail_if_no_peer_cert, true }]}
    ]},
    {kernel, [ {inet_dist_listen_min, 9100}, 
                {inet_dist_listen_max, 9105} ]}
    ].
    
    There are some important options to note:
  • tcp_listeners: This is the clear-text port to answer requests. Remove this if you want your broker to only accept SSL.
  • ssl_listeners: This is the port to accept SSL connections. Make sure you have enabled that port in iptables.
    The SSL-specific options (ssl_options):
    • cacertfile: The certificate file of the CA.
    • certfile: The certificate of this broker.
    • keyfile: The private key of this broker.
    • verify: If "verify_peer" is set, the client must present a certificate that will be verified by the broker.
    • fail_if_no_peer_cert: This is supposed to mean that the connection will fail if the peer does not preset a certificate and this property is set to true. But do to a bug in Erlang, if the {verify, verify_peer} option is set, fail_if_no_peer_cert is ignored if set to false (i.e.: client will have to supply a validated certificate).
  1. Restart RabbitMQ.
    sudo service rabbitmq-server restart

Verifying SSL

  1. We have supplied a test client to verify if the SSL connection works in the CMF-AMQP-Configuration Repository.
  2. Alternatively, the RabbitMQ Management Console lists the available ports for clients to connect on the main page:

1 comment:

  1. Thanks+, your article was helpful in getting SSL up and running.

    ReplyDelete

Note: Only a member of this blog may post a comment.