From df13274e15bced4f6f661ae56f5d3980b1e46914 Mon Sep 17 00:00:00 2001 From: Jonathan Rosser Date: Mon, 26 Apr 2021 16:34:34 +0100 Subject: [PATCH] Use ansible-role-pki to generate SSL certificates Supports two scenarios: 1) variables defined in defaults/main.yml are sufficient to create a root/intermediate CA certificate for rabbitmq when this role is used outside openstack-ansible. 2) when: openstack_pki_dir openstack_pki_setup_host openstack_pki_authorities openstack_pki_service_intermediate_cert_name are defined, an external CA already created on the deploy host with a previous run of ansible-role-pki will be used as the CA. Server certificates for the rabbitmq instances are created from the data in rabbitmq_pki_certificates in both situations: Depends-On: https://review.opendev.org/c/openstack/openstack-ansible/+/788031 Change-Id: I4cb7c48a74a307217b645cb8528fdbb0f7b9f596 --- defaults/main.yml | 80 +++++++++++++++++++++++++-- tasks/main.yml | 35 +++++------- tasks/rabbitmq_ssl_key_create.yml | 48 ---------------- tasks/rabbitmq_ssl_key_distribute.yml | 58 ------------------- tasks/rabbitmq_ssl_key_store.yml | 37 ------------- tasks/rabbitmq_ssl_self_signed.yml | 25 --------- tasks/rabbitmq_ssl_user_provided.yml | 55 ------------------ 7 files changed, 89 insertions(+), 249 deletions(-) delete mode 100644 tasks/rabbitmq_ssl_key_create.yml delete mode 100644 tasks/rabbitmq_ssl_key_distribute.yml delete mode 100644 tasks/rabbitmq_ssl_key_store.yml delete mode 100644 tasks/rabbitmq_ssl_self_signed.yml delete mode 100644 tasks/rabbitmq_ssl_user_provided.yml diff --git a/defaults/main.yml b/defaults/main.yml index 34bd82e9..779bf097 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -101,16 +101,84 @@ rabbitmq_plugins: - name: rabbitmq_management state: enabled -# RabbitMQ SSL support +# Storage location for SSL certificate authority +rabbitmq_pki_dir: "{{ openstack_pki_dir | default('/etc/pki/rabbitmq-ca') }}" + +# Delegated host for operating the certificate authority +rabbitmq_pki_setup_host: "{{ openstack_pki_setup_host | default('localhost') }}" + +# Create a certificate authority if one does not already exist +rabbitmq_pki_create_ca: "{{ openstack_pki_authorities is not defined | bool }}" +rabbitmq_pki_regen_ca: '' +rabbitmq_pki_authorities: + - name: "RabbitMQRoot" + country: "GB" + state_or_province_name: "England" + organization_name: "Example Corporation" + organizational_unit_name: "IT Security" + cn: "RabbitMQ Root CA" + provider: selfsigned + basic_constraints: "CA:TRUE" + key_usage: + - digitalSignature + - cRLSign + - keyCertSign + not_after: "+3650d" + - name: "RabbitMQIntermediate" + country: "GB" + state_or_province_name: "England" + organization_name: "Example Corporation" + organizational_unit_name: "IT Security" + cn: "RabbitMQ Intermediate CA" + provider: ownca + basic_constraints: "CA:TRUE,pathlen:0" + key_usage: + - digitalSignature + - cRLSign + - keyCertSign + not_after: "+3650d" + signed_by: "RabbitMQRoot" + +# Installation details for certificate authorities +rabbitmq_pki_install_ca: + - name: "RabbitMQRoot" + condition: "{{ rabbitmq_pki_create_ca }}" + +# Rabbitmq server certificate +rabbitmq_pki_keys_path: "{{ rabbitmq_pki_dir ~ '/certs/private/' }}" +rabbitmq_pki_certs_path: "{{ rabbitmq_pki_dir ~ '/certs/certs/' }}" +rabbitmq_pki_intermediate_cert_name: "{{ openstack_pki_service_intermediate_cert_name | default('RabbitMQIntermediate') }}" +rabbitmq_pki_intermediate_cert_path: "{{ rabbitmq_pki_dir ~ '/roots/' ~ rabbitmq_pki_intermediate_cert_name ~ '/certs/' ~ rabbitmq_pki_intermediate_cert_name ~ '.crt' }}" +rabbitmq_pki_regen_cert: '' +rabbitmq_pki_certificates: + - name: "rabbitmq_{{ ansible_facts['hostname'] }}" + provider: ownca + cn: "{{ ansible_facts['hostname'] }}" + san: "{{ 'DNS:' ~ ansible_facts['hostname'] ~ ',IP:' ~ rabbitmq_node_address }}" + signed_by: "{{ rabbitmq_pki_intermediate_cert_name }}" + +# RabbitMQ destination files for SSL certificates rabbitmq_ssl_cert: /etc/rabbitmq/rabbitmq.pem rabbitmq_ssl_key: /etc/rabbitmq/rabbitmq.key rabbitmq_ssl_ca_cert: /etc/rabbitmq/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={{ ansible_facts['hostname'] }}" +# Installation details for SSL certificates +rabbitmq_pki_install_certificates: + - src: "{{ rabbitmq_user_ssl_cert | default(rabbitmq_pki_certs_path ~ 'rabbitmq_' ~ ansible_facts['hostname'] ~ '-chain.crt') }}" + dest: "{{ rabbitmq_ssl_cert }}" + owner: "rabbitmq" + group: "rabbitmq" + mode: "0644" + - src: "{{ rabbitmq_user_ssl_key | default(rabbitmq_pki_keys_path ~ 'rabbitmq_' ~ ansible_facts['hostname'] ~ '.key.pem') }}" + dest: "{{ rabbitmq_ssl_key }}" + owner: "rabbitmq" + group: "rabbitmq" + mode: "0600" + - src: "{{ rabbitmq_user_ssl_ca_cert | default(rabbitmq_pki_intermediate_cert_path) }}" + dest: "{{ rabbitmq_ssl_ca_cert }}" + owner: "rabbitmq" + group: "rabbitmq" + mode: "0644" # Define user-provided SSL certificates in: # /etc/openstack_deploy/user_variables.yml diff --git a/tasks/main.yml b/tasks/main.yml index 2b7dd2da..0f2e2511 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -32,26 +32,21 @@ - include_tasks: 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_tasks: rabbitmq_ssl_self_signed.yml - when: > - rabbitmq_user_ssl_cert is not defined or - rabbitmq_user_ssl_key is not defined - tags: - - rabbitmq_server-config - -- include_tasks: rabbitmq_ssl_user_provided.yml - tags: - - rabbitmq_server-config +- name: Create and install SSL certificates + include_role: + name: pki + tasks_from: "{{ rabbitmq_pki_create_ca | ternary('main.yml', 'main_certs.yml') }}" + vars: + pki_setup_host: "{{ rabbitmq_pki_setup_host }}" + pki_dir: "{{ rabbitmq_pki_dir }}" + pki_create_ca: "{{ rabbitmq_pki_create_ca }}" + pki_regen_ca: "{{ rabbitmq_pki_regen_ca }}" + pki_authorities: "{{ rabbitmq_pki_authorities }}" + pki_install_ca: "{{ rabbitmq_pki_install_ca }}" + pki_create_certificates: "{{ rabbitmq_user_ssl_cert is not defined and rabbitmq_user_ssl_key is not defined }}" + pki_regen_certificates: "{{ rabbitmq_pki_regen_cert }}" + pki_certificates: "{{ rabbitmq_pki_certificates }}" + pki_install_certificates: "{{ rabbitmq_pki_install_certificates }}" - include_tasks: rabbitmq_set_cookie.yml tags: diff --git a/tasks/rabbitmq_ssl_key_create.yml b/tasks/rabbitmq_ssl_key_create.yml deleted file mode 100644 index 3dd5f2a8..00000000 --- a/tasks/rabbitmq_ssl_key_create.yml +++ /dev/null @@ -1,48 +0,0 @@ ---- -# 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 - -- name: Ensure rabbitmq user owns the self-signed key and certificate - file: - path: "{{ item }}" - owner: rabbitmq - group: rabbitmq - with_items: - - "{{ rabbitmq_ssl_key }}" - - "{{ rabbitmq_ssl_cert }}" - tags: - - rabbitmq-ssl diff --git a/tasks/rabbitmq_ssl_key_distribute.yml b/tasks/rabbitmq_ssl_key_distribute.yml deleted file mode 100644 index dbc9b346..00000000 --- a/tasks/rabbitmq_ssl_key_distribute.yml +++ /dev/null @@ -1,58 +0,0 @@ ---- -# 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 key - copy: - dest: "{{ rabbitmq_ssl_key }}" - content: "{{ hostvars[groups[rabbitmq_host_group][0]]['rabbitmq_ssl_key_fact'] | b64decode }}" - owner: "rabbitmq" - group: "rabbitmq" - mode: "0640" - tags: - - rabbitmq-ssl - -- name: Distribute self signed ssl cert - copy: - dest: "{{ rabbitmq_ssl_cert }}" - content: "{{ hostvars[groups[rabbitmq_host_group][0]]['rabbitmq_ssl_cert_fact'] | b64decode }}" - owner: "rabbitmq" - group: "rabbitmq" - mode: "0640" - tags: - - rabbitmq-ssl - -- name: Ensure rabbitmq user owns the self-signed key and certificate - file: - path: "{{ item }}" - owner: rabbitmq - group: rabbitmq - with_items: - - "{{ rabbitmq_ssl_key }}" - - "{{ rabbitmq_ssl_cert }}" - tags: - - rabbitmq-ssl - -# This is here because there was a different way of configuring SSL/TLS -# for RabbitMQ that used a mode of 0750 for the RabbitMQ directory. That has -# since been updated but we need to ensure that old environments get this -# critical update during upgrades. -# -# See bug 1513668 in Launchpad for more details. -- name: Ensure /etc/rabbitmq is set to the default mode of 0755 - file: - path: /etc/rabbitmq - mode: 0755 - tags: - - rabbitmq-ssl diff --git a/tasks/rabbitmq_ssl_key_store.yml b/tasks/rabbitmq_ssl_key_store.yml deleted file mode 100644 index 6124685e..00000000 --- a/tasks/rabbitmq_ssl_key_store.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -# 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 ssl cert - slurp: - src: "{{ rabbitmq_ssl_cert }}" - register: _rabbitmq_ssl_cert - changed_when: false - tags: - - rabbitmq-ssl - -- name: Store ssl key - slurp: - src: "{{ rabbitmq_ssl_key }}" - register: _rabbitmq_ssl_key - changed_when: false - tags: - - rabbitmq-ssl - -- name: Register a fact for the cert and key - set_fact: - rabbitmq_ssl_cert_fact: "{{ _rabbitmq_ssl_cert.content }}" - rabbitmq_ssl_key_fact: "{{ _rabbitmq_ssl_key.content }}" - tags: - - rabbitmq-ssl diff --git a/tasks/rabbitmq_ssl_self_signed.yml b/tasks/rabbitmq_ssl_self_signed.yml deleted file mode 100644 index 4a1347f1..00000000 --- a/tasks/rabbitmq_ssl_self_signed.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -# 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_tasks: rabbitmq_ssl_key_create.yml - when: inventory_hostname == groups[rabbitmq_host_group][0] - -- include_tasks: rabbitmq_ssl_key_store.yml - when: inventory_hostname == groups[rabbitmq_host_group][0] - -- include_tasks: rabbitmq_ssl_key_distribute.yml - when: inventory_hostname != groups[rabbitmq_host_group][0] diff --git a/tasks/rabbitmq_ssl_user_provided.yml b/tasks/rabbitmq_ssl_user_provided.yml deleted file mode 100644 index 510fc797..00000000 --- a/tasks/rabbitmq_ssl_user_provided.yml +++ /dev/null @@ -1,55 +0,0 @@ ---- -# 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 - copy: - src: "{{ rabbitmq_user_ssl_cert }}" - dest: "{{ rabbitmq_ssl_cert }}" - owner: "rabbitmq" - group: "rabbitmq" - mode: "0644" - when: rabbitmq_user_ssl_cert is defined - tags: - - rabbitmq-configs - - rabbitmq-ssl - -- name: Deploy user provided ssl key - copy: - src: "{{ rabbitmq_user_ssl_key }}" - dest: "{{ rabbitmq_ssl_key }}" - owner: "rabbitmq" - group: "rabbitmq" - mode: "0600" - when: 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: "rabbitmq" - group: "rabbitmq" - mode: "0644" - when: rabbitmq_user_ssl_ca_cert is defined - tags: - - keystone-configs - - keystone-ssl