Add SSL/TLS listener to RabbitMQ

This patch adds a SSL/TLS listener to RabbitMQ without disrupting the existing
plaintext TCP listener.  Various services that use RabbitMQ will have the
option to encrypt messaging traffic with this change.  Documentation is
included for this change.

By default, it will create a self-signed certificate for the user, but users
have the option to specify their own existing certificates as well.

This makes it easier to bring RabbitMQ (and the services which talk to it)
into compliance with PCI DSS 3.1's Requirement 2.2.3.

In addition, this change is recommended within the OpenStack Security Guide.

Closes-bug: 1496001

Change-Id: I0d29cbb6e963b24f77a8375eba8a8c6a558aaf81
This commit is contained in:
Major Hayden 2015-09-15 09:52:19 -05:00
parent d7450b1a10
commit 4a1d412f8c
12 changed files with 263 additions and 2 deletions

View File

@ -0,0 +1,26 @@
`Home <index.html>`__ 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

View File

@ -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

View File

@ -69,6 +69,7 @@
- `Configuring HAProxy (optional) <configure-haproxy.html>`__
- `Configuring Horizon (optional) <configure-horizon.html>`__
- `Configuring Keystone (optional) <configure-keystone.html>`__
- `Configuring RabbitMQ (optional) <configure-rabbitmq.html>`__
- `Securing services with SSL certificates
<configure-sslcertificates.html>`__

View File

@ -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: <path to cert on ansible deployment host>
#rabbitmq_user_ssl_key: <path to cert on ansible deployment host>
#rabbitmq_user_ssl_ca_cert: <path to cert on ansible deployment host>
## 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

View File

@ -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: <path to cert on ansible deployment host>
#rabbitmq_user_ssl_key: <path to cert on ansible deployment host>
#rabbitmq_user_ssl_ca_cert: <path to cert on ansible deployment host>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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}