dokku-rabbitmq icon indicating copy to clipboard operation
dokku-rabbitmq copied to clipboard

Configuration of SSL

Open UlTriX opened this issue 9 years ago • 9 comments

HI,

does anyone knows if it is possible with any changes to the code to activate SSL in Rabbit?

Do we need another volume besides the data where the keys will be stored ?

I am trying to pass the environment variables needed by rabbit docker but export RABBITMQ_CUSTOM_ENV="RABBITMQ_SSL_CERT_FILE=/var/lib/rabbitmq/ssl_files/cert.pem;RABBITMQ_SSL_KEY_FILE=/var/lib/rabbitmq/ssl_files/key.pem;RABBITMQ_SSL_CA_FILE=/var/lib/rabbitmq/ssl_files/cacert.pem"

cat: /var/lib/rabbitmq/ssl_files/cert.pem: No such file or directory

UlTriX avatar Feb 09 '16 15:02 UlTriX

There seems to be a catch-22 here, where

  • You can't add SSL certificates to the data directory before creating the service, because if the data directory exists you get an "already exists" error
  • You can't create with a custom env for SSL without having certificates already in the data directory, because rabbitmq fails to start if you point it to nonexistent certificates

binary-koan avatar Sep 10 '20 05:09 binary-koan

Where exactly should the ssl certificates exist on the host in order for this to work? I wonder if this could be a flag, and we'd import the ssl files from a location and place them in the right path during service:create?

josegonzalez avatar Sep 10 '20 05:09 josegonzalez

After looking at how this plugin works I finally managed to get SSL working with some awful hacks, so let me explain that first for reference:

  1. Patch the plugin, because the RabbitMQ docker image uses different ports for SSL (5671 instead of 5672): echo "export PLUGIN_DATASTORE_PORTS=(5671 4369 35197 15671)" >> /var/lib/dokku/plugins/enabled/rabbitmq/config
  2. Create SSL certificates with tls-gen according to the RabbitMQ docs: https://www.rabbitmq.com/ssl.html#automated-certificate-generation-transcript
  3. Create the non-SSL rabbitmq instance with dokku rabbitmq:create myqueue
  4. Stop the container with dokku rabbitmq:stop myqueue
  5. Copy the SSL certificates from tls-gen to a new /var/lib/dokku/rabbitmq/myqueue/data/ssl directory
  6. Add all the SSL options manually to /var/lib/dokku/services/rabbitmq/myqueue/ENV, like
RABBITMQ_SSL_CERT_FILE=/var/lib/rabbitmq/ssl/server_certificate.pem
RABBITMQ_SSL_KEY_FILE=/var/lib/rabbitmq/ssl/server_key.pem
RABBITMQ_SSL_CA_FILE=/var/lib/rabbitmq/ssl/ca_certificate.pem
RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT=false
RABBITMQ_SSL_VERIFY=verify_peer
RABBITMQ_MANAGEMENT_SSL_CERT_FILE=/var/lib/rabbitmq/ssl/server_certificate.pem
RABBITMQ_MANAGEMENT_SSL_KEY_FILE=/var/lib/rabbitmq/ssl/server_key.pem
RABBITMQ_MANAGEMENT_SSL_CA_FILE=/var/lib/rabbitmq/ssl/ca_certificate.pem
RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT=false
RABBITMQ_MANAGEMENT_SSL_VERIFY=verify_peer
# Might not be needed?
RABBITMQ_CTL_ERL_ARGS=-proto_dist inet_tls
  1. Destroy the old RabbitMQ container, otherwise the ENV file won't be reloaded: docker ps -aq --no-trunc --filter "status=exited" --filter "name=^/dokku.rabbitmq.myqueue$" --format '{{ .ID }}' | xargs docker rm
  2. Start the service again with dokku rabbitmq:start myqueue - this detects that the container was deleted and recreates it with the new ENV
  3. Expose ports (this will bind to the container ports 5671 and 15671 thanks to the patch in step 1)

Now hopefully no one else has to work all that out 😅


@josegonzalez A flag would actually be really nice. I would imagine being able to do something like

dokku rabbitmq:create myqueue --cert-file=/path/to/certificate.pem --key-file=/path/to/key.pem --ca-file=/path/to/ca.pem

Then if those 3 options are set, during the creation process dokku can copy the files to the data directory, set up the environment variables, and set a flag to change the port mapping if you later run expose.

It's a bit weird having it as 3 arguments which are all-or-nothing, but that would probably make more sense to me than using a folder with set filenames / zip file / whatever

binary-koan avatar Sep 10 '20 11:09 binary-koan

Hi, any news about this without @binary-koan 's awful hacks?

matte0080 avatar Mar 10 '21 10:03 matte0080

After looking at how this plugin works I finally managed to get SSL working with some awful hacks, so let me explain that first for reference:

  1. Patch the plugin, because the RabbitMQ docker image uses different ports for SSL (5671 instead of 5672): echo "export PLUGIN_DATASTORE_PORTS=(5671 4369 35197 15671)" >> /var/lib/dokku/plugins/enabled/rabbitmq/config
  2. Create SSL certificates with tls-gen according to the RabbitMQ docs: https://www.rabbitmq.com/ssl.html#automated-certificate-generation-transcript
  3. Create the non-SSL rabbitmq instance with dokku rabbitmq:create myqueue
  4. Stop the container with dokku rabbitmq:stop myqueue
  5. Copy the SSL certificates from tls-gen to a new /var/lib/dokku/rabbitmq/myqueue/data/ssl directory
  6. Add all the SSL options manually to /var/lib/dokku/services/rabbitmq/myqueue/ENV, like
RABBITMQ_SSL_CERT_FILE=/var/lib/rabbitmq/ssl/server_certificate.pem
RABBITMQ_SSL_KEY_FILE=/var/lib/rabbitmq/ssl/server_key.pem
RABBITMQ_SSL_CA_FILE=/var/lib/rabbitmq/ssl/ca_certificate.pem
RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT=false
RABBITMQ_SSL_VERIFY=verify_peer
RABBITMQ_MANAGEMENT_SSL_CERT_FILE=/var/lib/rabbitmq/ssl/server_certificate.pem
RABBITMQ_MANAGEMENT_SSL_KEY_FILE=/var/lib/rabbitmq/ssl/server_key.pem
RABBITMQ_MANAGEMENT_SSL_CA_FILE=/var/lib/rabbitmq/ssl/ca_certificate.pem
RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT=false
RABBITMQ_MANAGEMENT_SSL_VERIFY=verify_peer
# Might not be needed?
RABBITMQ_CTL_ERL_ARGS=-proto_dist inet_tls
  1. Destroy the old RabbitMQ container, otherwise the ENV file won't be reloaded: docker ps -aq --no-trunc --filter "status=exited" --filter "name=^/dokku.rabbitmq.myqueue$" --format '{{ .ID }}' | xargs docker rm
  2. Start the service again with dokku rabbitmq:start myqueue - this detects that the container was deleted and recreates it with the new ENV
  3. Expose ports (this will bind to the container ports 5671 and 15671 thanks to the patch in step 1)

Now hopefully no one else has to work all that out

@josegonzalez A flag would actually be really nice. I would imagine being able to do something like

dokku rabbitmq:create myqueue --cert-file=/path/to/certificate.pem --key-file=/path/to/key.pem --ca-file=/path/to/ca.pem

Then if those 3 options are set, during the creation process dokku can copy the files to the data directory, set up the environment variables, and set a flag to change the port mapping if you later run expose.

It's a bit weird having it as 3 arguments which are all-or-nothing, but that would probably make more sense to me than using a folder with set filenames / zip file / whatever

Thanks!! Thats been super useful :D

victor-solvethex avatar Mar 29 '21 15:03 victor-solvethex

Is the reason folks are setting up tls for external access to rabbitmq? Or is this always going from a dokku app to a rabbitmq on the same host?

The bit that makes this annoying is that the ports change if using TLS or not. Everything else is... well we can deal with it.

josegonzalez avatar Sep 13 '21 02:09 josegonzalez

Personally I was trying to set it up for external access (running database-ish things on a separate server so we could easily scale and swap out the app servers). Although that's maybe not the kind of setup / scale that dokku is aiming for at the moment anyway

binary-koan avatar Sep 13 '21 12:09 binary-koan

I think there are a few things we can make easier here:

  • add ability to use alternate ports for ssl (an ssl property of some sort?)
  • add a way to actually remove the container. some options:
    • The :stop command either takes a --rm|--rm-container flag
    • The :stop command deletes the container by default and there is a new :pause command that does what stop currently does.
  • add a new command to copy ssl certs into place. this would set an ssl property that would inject the env keys as expected into the ENV config (or remove them)
    • dokku rabbitmq:configure-ssl $SERVICE $cert $filepaths $here
    • dokku rabbitmq:configure-ssl $SERVICE false So the workflow would be:
dokku rabbitmq:create test
dokku rabbitmq:stop test
dokku rabbitmq:configure-ssl $SERVICE $cert-file $key-file $ca-file
dokku rabbitmq:start $SERVICE

This doesn't lend itself well to config management due to the need to check if ssl is configured before configuring it, so I'm curious to hear what folks think might be a good route to solving that might be.

josegonzalez avatar Sep 13 '21 16:09 josegonzalez

The stop/pause changes are now implemented everywhere. The only thing left would be the :configure-ssl command, and we could probably add the configuration output to the :report output, making it easier to use config management.

josegonzalez avatar Dec 26 '22 23:12 josegonzalez