diff --git a/doc/source/install-guide/configure-rabbitmq.rst b/doc/source/install-guide/configure-rabbitmq.rst new file mode 100644 index 0000000000..82f2830a6b --- /dev/null +++ b/doc/source/install-guide/configure-rabbitmq.rst @@ -0,0 +1,26 @@ +`Home `__ OpenStack Ansible Installation Guide + +Configuring RabbitMQ (optional) +------------------------------- + +RabbitMQ provides the messaging broker for various OpenStack services. The +openstack-ansible project configures a plaintext listener on port 5672 and +a SSL/TLS encrypted listener on port 5671. + +Customizing the RabbitMQ deployment is done within +``/etc/openstack_deploy/user_variables.yml``. + +Securing RabbitMQ communication with SSL certificates +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The openstack-ansible project provides the ability to secure RabbitMQ +communications with self-signed or user-provided SSL certificates. + +Refer to `Securing services with SSL certificates`_ for available configuration +options. + +.. _Securing services with SSL certificates: configure-sslcertificates.html + +-------------- + +.. include:: navigation.txt diff --git a/doc/source/install-guide/configure.rst b/doc/source/install-guide/configure.rst index 0668642b05..6199550083 100644 --- a/doc/source/install-guide/configure.rst +++ b/doc/source/install-guide/configure.rst @@ -15,6 +15,7 @@ Chapter 5. Deployment configuration configure-swift.rst configure-haproxy.rst configure-horizon.rst + configure-rabbitmq.rst configure-ceilometer.rst configure-keystone.rst configure-sslcertificates.rst diff --git a/doc/source/install-guide/navigation.txt b/doc/source/install-guide/navigation.txt index a2f196d6c2..ffafd61352 100644 --- a/doc/source/install-guide/navigation.txt +++ b/doc/source/install-guide/navigation.txt @@ -69,6 +69,7 @@ - `Configuring HAProxy (optional) `__ - `Configuring Horizon (optional) `__ - `Configuring Keystone (optional) `__ + - `Configuring RabbitMQ (optional) `__ - `Securing services with SSL certificates `__ diff --git a/etc/openstack_deploy/user_variables.yml b/etc/openstack_deploy/user_variables.yml index 8f383aa39c..10245f0934 100644 --- a/etc/openstack_deploy/user_variables.yml +++ b/etc/openstack_deploy/user_variables.yml @@ -101,7 +101,13 @@ glance_swift_store_endpoint_type: internalURL # auth_cluster_required = cephx # auth_service_required = cephx -## Apache SSL Settings + +## SSL Settings +# Adjust these settings to change how SSL connectivity is configured for +# various services. For more information, see the openstack-ansible +# documentation section titled "Securing services with SSL certificates". +# +## SSL: Keystone # These do not need to be configured unless you're creating certificates for # services running behind Apache (currently, Horizon and Keystone). ssl_protocol: "ALL -SSLv2 -SSLv3" @@ -113,7 +119,14 @@ ssl_cipher_suite: "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AE # To override for Horizon only: # - horizon_ssl_protocol # - horizon_ssl_cipher_suite - +# +## SSL: RabbitMQ +# Set these variables if you prefer to use existing SSL certificates, keys and +# CA certificates with the RabbitMQ SSL/TLS Listener +# +#rabbitmq_user_ssl_cert: +#rabbitmq_user_ssl_key: +#rabbitmq_user_ssl_ca_cert: ## Additional pinning generator that will allow for more packages to be pinned as you see fit. ## All pins allow for package and versions to be defined. Be careful using this as versions diff --git a/playbooks/roles/rabbitmq_server/defaults/main.yml b/playbooks/roles/rabbitmq_server/defaults/main.yml index 70e997aeb1..d93b0953d7 100644 --- a/playbooks/roles/rabbitmq_server/defaults/main.yml +++ b/playbooks/roles/rabbitmq_server/defaults/main.yml @@ -51,3 +51,20 @@ rabbitmq_ulimit: 4096 rabbitmq_plugins: - names: rabbitmq_management state: enabled + +# RabbitMQ SSL support +rabbitmq_ssl_cert: /etc/ssl/certs/rabbitmq.pem +rabbitmq_ssl_key: /etc/ssl/private/rabbitmq.key +rabbitmq_ssl_ca_cert: /etc/ssl/certs/rabbitmq-ca.pem + +# Set rabbitmq_ssl_self_signed_regen to true if you want to generate a new +# SSL certificate for RabbitMQ when this playbook runs. You can also change +# the subject of the self-signed certificate here if you prefer. +rabbitmq_ssl_self_signed_regen: false +rabbitmq_ssl_self_signed_subject: "/C=US/ST=Texas/L=San Antonio/O=IT/CN={{ container_name }}" + +# Define user-provided SSL certificates in: +# /etc/openstack_deploy/user_variables.yml +#rabbitmq_user_ssl_cert: +#rabbitmq_user_ssl_key: +#rabbitmq_user_ssl_ca_cert: diff --git a/playbooks/roles/rabbitmq_server/tasks/main.yml b/playbooks/roles/rabbitmq_server/tasks/main.yml index 5f5c4788d9..3f477bb565 100644 --- a/playbooks/roles/rabbitmq_server/tasks/main.yml +++ b/playbooks/roles/rabbitmq_server/tasks/main.yml @@ -20,6 +20,22 @@ - include: rabbitmq_install.yml when: not rabbitmq_ignore_version_state | bool +# RabbitMQ SSL/TLS listener configuration +# +# If the user has not specified a certificate, key and CA certificate, we will +# generate a self-signed SSL certificate and distribute it to each RabbitMQ +# container. +# +# User-provided certificates must be specified within: +# +# playbooks/roles/rabbitmq_server/defaults/main.yml +# +- include: rabbitmq_ssl_self_signed.yml + when: > + rabbitmq_user_ssl_cert is not defined or + rabbitmq_user_ssl_key is not defined +- include: rabbitmq_ssl_user_provided.yml + - include: rabbitmq_set_cookie.yml - include: rabbitmq_post_install.yml - include: rabbitmq_cluster.yml diff --git a/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_key_create.yml b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_key_create.yml new file mode 100644 index 0000000000..4fdc3099d1 --- /dev/null +++ b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_key_create.yml @@ -0,0 +1,37 @@ +--- +# Copyright 2015, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Remove self signed cert for regen + file: + dest: "{{ rabbitmq_ssl_cert }}" + state: "absent" + when: rabbitmq_ssl_self_signed_regen | bool + tags: + - rabbitmq-ssl + +# See playbooks/roles/rabbitmq_server/defaults/main.yml to provide custom +# subject material for certificates or specify a user-provided certificate and +# key pair. +- name: Create self-signed ssl cert + command: > + openssl req -new -nodes -sha256 -x509 -subj + "{{ rabbitmq_ssl_self_signed_subject }}" + -days 3650 + -keyout {{ rabbitmq_ssl_key }} + -out {{ rabbitmq_ssl_cert }} + -extensions v3_ca + creates={{ rabbitmq_ssl_cert }} + tags: + - rabbitmq-ssl diff --git a/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_key_distribute.yml b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_key_distribute.yml new file mode 100644 index 0000000000..70ba0d88d0 --- /dev/null +++ b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_key_distribute.yml @@ -0,0 +1,33 @@ +--- +# Copyright 2015, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Distribute self signed ssl + memcached: + name: "{{ item.name }}" + file_path: "{{ item.src }}" + state: "retrieve" + file_mode: "{{ item.file_mode }}" + dir_mode: "{{ item.dir_mode }}" + server: "{{ memcached_servers }}" + encrypt_string: "{{ memcached_encryption_key }}" + with_items: + - { src: "{{ rabbitmq_ssl_cert }}", name: "rabbitmq_ssl_cert", file_mode: "0640", dir_mode: "0750" } + - { src: "{{ rabbitmq_ssl_key }}", name: "rabbitmq_ssl_key", file_mode: "0640", dir_mode: "0750" } + register: memcache_keys + until: memcache_keys|success + retries: 5 + delay: 2 + tags: + - rabbitmq-ssl diff --git a/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_key_store.yml b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_key_store.yml new file mode 100644 index 0000000000..8dcf5f9fda --- /dev/null +++ b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_key_store.yml @@ -0,0 +1,31 @@ +--- +# Copyright 2015, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Store self signed ssl + memcached: + name: "{{ item.name }}" + file_path: "{{ item.src }}" + state: "present" + server: "{{ memcached_servers }}" + encrypt_string: "{{ memcached_encryption_key }}" + with_items: + - { src: "{{ rabbitmq_ssl_cert }}", name: "rabbitmq_ssl_cert" } + - { src: "{{ rabbitmq_ssl_key }}", name: "rabbitmq_ssl_key" } + register: memcache_keys + until: memcache_keys|success + retries: 5 + delay: 2 + tags: + - rabbitmq-ssl diff --git a/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_self_signed.yml b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_self_signed.yml new file mode 100644 index 0000000000..840b381d8f --- /dev/null +++ b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_self_signed.yml @@ -0,0 +1,31 @@ +--- +# Copyright 2015, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# We create the self-signed SSL certificate and key only on the first +# RabbitMQ container. +- include: rabbitmq_ssl_key_create.yml + when: > + inventory_hostname == groups['rabbitmq_all'][0] + +# The certificate and key are stored in memcached for easy distribution. +- include: rabbitmq_ssl_key_store.yml + when: > + inventory_hostname == groups['rabbitmq_all'][0] + +# The additional RabbitMQ nodes will retrieve their SSL certificates and keys +# from memcached. +- include: rabbitmq_ssl_key_distribute.yml + when: > + inventory_hostname != groups['rabbitmq_all'][0] diff --git a/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_user_provided.yml b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_user_provided.yml new file mode 100644 index 0000000000..09714abe91 --- /dev/null +++ b/playbooks/roles/rabbitmq_server/tasks/rabbitmq_ssl_user_provided.yml @@ -0,0 +1,46 @@ +--- +# Copyright 2015, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# If we have a user-provided SSL certificate from +# /etc/openstack_deploy/user_variables.yml, we should deploy that certificate +# and key to each RabbitMQ container. +- name: Deploy user provided ssl cert and key + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: "root" + group: "root" + mode: "{{ item.mode }}" + with_items: + - { src: "{{ rabbitmq_user_ssl_cert }}", dest: "{{ rabbitmq_ssl_cert }}", mode: "0644" } + - { src: "{{ rabbitmq_user_ssl_key }}", dest: "{{ rabbitmq_ssl_key }}", mode: "0640" } + when: rabbitmq_user_ssl_cert is defined and rabbitmq_user_ssl_key is defined + tags: + - rabbitmq-configs + - rabbitmq-ssl + +# Deploy the user provided CA certificate as well (if the user defined it +# within /etc/openstack_deploy/user_variables.yml). +- name: Deploy user provided ssl CA cert + copy: + src: "{{ rabbitmq_user_ssl_ca_cert }}" + dest: "{{ rabbitmq_ssl_ca_cert }}" + owner: "root" + group: "root" + mode: "0644" + when: rabbitmq_user_ssl_ca_cert is defined + tags: + - keystone-configs + - keystone-ssl diff --git a/playbooks/roles/rabbitmq_server/templates/rabbitmq.config.j2 b/playbooks/roles/rabbitmq_server/templates/rabbitmq.config.j2 index 834c5af81f..249142d7ee 100644 --- a/playbooks/roles/rabbitmq_server/templates/rabbitmq.config.j2 +++ b/playbooks/roles/rabbitmq_server/templates/rabbitmq.config.j2 @@ -1,6 +1,15 @@ [ {rabbit, [ {loopback_users, []}, + {ssl_listeners, [5671]}, + {ssl_options, [{certfile,"{{ rabbitmq_ssl_cert }}"}, + {keyfile,"{{ rabbitmq_ssl_key }}"}, + {% if rabbitmq_ssl_ca_cert is defined -%} + {cacertfile,"{{ rabbitmq_ssl_ca_cert }}"}, + {% endif -%} + {versions, ['tlsv1.2', 'tlsv1.1']}, + {verify,verify_none}, + {fail_if_no_peer_cert,false}]}, {% if rabbitmq_cluster_partition_handling != 'ignore' %}{cluster_partition_handling, {{ rabbitmq_cluster_partition_handling }}},{% endif %} {cluster_nodes, { [ {% for host in groups['rabbitmq_all'] %}'rabbit@{{ hostvars[host]['ansible_ssh_host'] }}'{% if not loop.last %}, {% endif %}{% endfor %}], disc}