rabbitmq ssl on docker

I had recendly switched my lab environemt to some new shiny hardware and dockerized some of the services.

To have that environment setup like it would have been in production, i try to configure ssl wherever possible and expose only the really needed ports to the world.

environment

The host use NGINX as proxy and SSL termination for most services that expose a WebGUI that are running inside of containers. To have valid certificates I use let's encrypt to get them and the perfect acme.sh bash client to issue the certificates.

Some variables need to be known to understand the following. The NGINX provides a default server with the following configuration:

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  location /.well-known/acme-challenge/ {
        alias /var/www/le_root/.well-known/acme-challenge/;
  }
  location / {
    rewrite ^ https://$host$request_uri? permanent;
  }
}

This enables me to provide a HTTP endpoint to verify the certificates. The second importand variable is, all persistent data is stored in /srv/$someName.

As this host is exposed, it should run SSL enabled on the first start.

get the certificate

Issue the certificate is straigt forward, if the choosen DNS entry is already known in the world.

acme.sh --issue \
    -d rabbit.example.org \
    --webroot /srv/www/le_root/

For the next step I have defined already how I will name the docker container for rabbitMQ, the command will exit with an error that the container is not present yet, but the important part - it will copy the certificates to the wanted location is done before the error.

acme.sh --install-cert \
    -d rabbit.example.org \
    --cert-file /srv/ssl/rabbit/rabbit.example.org.cert \
    --key-file /srv/ssl/rabbit/rabbit.example.org.key \
    --ca-file /srv/ssl/rabbit/ca.cert \
    --reloadcmd "docker restart rabbit.example.org"

get rabbitmq

I like to have the management plugin for rabbitMQ and that my containers are small - use managment-alpine tag from the official docker image worked for me the best.

The following command to get the container up and running in a secure way took me only a few hours try&error, reading other peoples work and guessing. I hope that this post will make it more easy for others.

docker run -d --hostname rabbit.example.org \
  --name rabbit.example.org \
  -p 127.0.0.1:15672:15672 \
  -p 127.0.0.1:15671:15671 \
  -p 5671:5671 \
  -p 5672:5672 \
  -p 127.0.0.1:4369:4369 \
  -p 127.0.0.1:25672:25672 \
  -e RABBITMQ_DEFAULT_USER=admin \
  -e RABBITMQ_DEFAULT_PASS=LetMe!n \
  -e RABBITMQ_SSL_CERT_FILE=/certs/rabbit.example.org.cert \
  -e RABBITMQ_SSL_KEY_FILE=/certs/rabbit.example.org.key \
  -e RABBITMQ_SSL_CA_FILE=/certs/ca.cert \
  -e RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT=false \
  -e RABBITMQ_SSL_VERIFY=verify_peer \
  -v /srv/ssl/rabbit/:/certs \
  -v /srv/rabbit/:/var/lib/rabbitmq \
  rabbitmq:management-alpine

The above created container only expose the default AMQP ports to the world. It would not be possible to create a cluster with that ( 4369 and 25672 would be needed to the outside too ) but you get a single rabbitMQ running on docker with SSL enabled.

To have the environment stable, the acme.sh installation should be re-run

acme.sh --install-cert \
    -d rabbit.example.org \
    --cert-file /srv/ssl/rabbit/rabbit.example.org.cert \
    --key-file /srv/ssl/rabbit/rabbit.example.org.key \
    --ca-file /srv/ssl/rabbit/ca.cert \
    --reloadcmd "docker restart rabbit.example.org"

Now the container will be restarted once new certificates are installed.

enable managment

The managment interface should run in a subfolder of a given NGINX virtual host. The final working solution for that is simple:

     location /rabbitmq/ {
                rewrite         /rabbitmq/(.*) /$1 break;
                proxy_pass      https://127.0.0.1:15671;
                proxy_redirect  off;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

But getting that up and running took me a while. The default docker image expose the interface only via SSL if SSL is enabled, to realize that I just need to take a short walk in the park to fresh up my view.

Setting up a system that is secured take some more work, but having system security in mind will save you - and propably your company time and money.

(c) header image http://maxpixel.freegreatpicture.com/Alcohol-Cask-Wooden-Heritage-Kegs-Barrel-Wine-52934

Show Comments