Add PKI support to horizon backends

Replace legacy SSL support with ansible-role-pki.
It is used to generate required TLS certificates if needed.

Depends-On: https://review.opendev.org/c/openstack/openstack-ansible/+/879085

Change-Id: Id2f9d6f911cee6e58c261c1a68c34a37ab9ced4f
This commit is contained in:
Damian Dabrowski 2023-04-04 23:20:27 +02:00
parent 4686326650
commit db7110d297
9 changed files with 77 additions and 190 deletions

View File

@ -230,16 +230,9 @@ horizon_ssl_protocol: "{{ ssl_protocol | default('ALL -SSLv2 -SSLv3 -TLSv1 -TLSv
horizon_ssl_cipher_suite_tls12: "{{ horizon_ssl_cipher_suite | default(ssl_cipher_suite | default('ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM')) }}" horizon_ssl_cipher_suite_tls12: "{{ horizon_ssl_cipher_suite | default(ssl_cipher_suite | default('ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM')) }}"
# TLS v1.3 # TLS v1.3
horizon_ssl_cipher_suite_tls13: "{{ ssl_cipher_suite_tls13 | default('TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256') }}" horizon_ssl_cipher_suite_tls13: "{{ ssl_cipher_suite_tls13 | default('TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256') }}"
# if using a self-signed certificate, set this to true to regenerate it
horizon_ssl_self_signed_regen: false
horizon_ssl_self_signed_subject: "/C=US/ST=Texas/L=San Antonio/O=IT/CN={{ horizon_server_name }}/subjectAltName=IP.1={{ external_lb_vip_address }}"
# Set these variables to deploy custom certificates # Define if communication between haproxy and service backends should be
# horizon_user_ssl_cert: <path to cert on ansible deployment host> # encrypted with TLS.
# horizon_user_ssl_key: <path to cert on ansible deployment host>
# horizon_user_ssl_ca_cert: <path to cert on ansible deployment host>
# Toggle whether horizon should be served via SSL
# NOTE(damiandabrowski): Remove backward compatibility with horizon_enable_ssl in 2024.1 # NOTE(damiandabrowski): Remove backward compatibility with horizon_enable_ssl in 2024.1
horizon_backend_ssl: "{{ horizon_enable_ssl | default(openstack_service_backend_ssl | default(False)) }}" horizon_backend_ssl: "{{ horizon_enable_ssl | default(openstack_service_backend_ssl | default(False)) }}"
@ -532,3 +525,51 @@ horizon_websso_default_redirect: False
horizon_websso_default_redirect_region: "{{ horizon_websso_keystone_url | default(horizon_keystone_endpoint) }}" horizon_websso_default_redirect_region: "{{ horizon_websso_keystone_url | default(horizon_keystone_endpoint) }}"
horizon_websso_default_redirect_logout: "" horizon_websso_default_redirect_logout: ""
horizon_websso_use_http_referer: True horizon_websso_use_http_referer: True
###
### Backend TLS
###
# Storage location for SSL certificate authority
horizon_pki_dir: "{{ openstack_pki_dir | default('/etc/openstack_deploy/pki') }}"
# Delegated host for operating the certificate authority
horizon_pki_setup_host: "{{ openstack_pki_setup_host | default('localhost') }}"
# horizon server certificate
horizon_pki_keys_path: "{{ horizon_pki_dir ~ '/certs/private/' }}"
horizon_pki_certs_path: "{{ horizon_pki_dir ~ '/certs/certs/' }}"
horizon_pki_intermediate_cert_name: "{{ openstack_pki_service_intermediate_cert_name | default('ExampleCorpIntermediate') }}"
horizon_pki_intermediate_cert_path: "{{ horizon_pki_dir ~ '/roots/' ~ horizon_pki_intermediate_cert_name ~ '/certs/' ~ horizon_pki_intermediate_cert_name ~ '.crt' }}"
horizon_pki_regen_cert: ''
horizon_pki_san: "{{ openstack_pki_san | default('DNS:' ~ ansible_facts['hostname'] ~ ',IP:' ~ management_address) }}"
horizon_pki_certificates:
- name: "horizon_{{ ansible_facts['hostname'] }}"
provider: ownca
cn: "{{ ansible_facts['hostname'] }}"
san: "{{ horizon_pki_san }}"
signed_by: "{{ horizon_pki_intermediate_cert_name }}"
# Installation details for SSL certificates
horizon_pki_install_certificates:
- src: "{{ horizon_user_ssl_cert | default(horizon_pki_certs_path ~ 'horizon_' ~ ansible_facts['hostname'] ~ '-chain.crt') }}"
dest: "{{ horizon_ssl_cert }}"
owner: "{{ horizon_system_user_name }}"
group: "{{ horizon_system_group_name }}"
mode: "0644"
- src: "{{ horizon_user_ssl_key | default(horizon_pki_keys_path ~ 'horizon_' ~ ansible_facts['hostname'] ~ '.key.pem') }}"
dest: "{{ horizon_ssl_key }}"
owner: "{{ horizon_system_user_name }}"
group: "{{ horizon_system_group_name }}"
mode: "0600"
- src: "{{ horizon_user_ssl_ca_cert | default(horizon_pki_intermediate_cert_path) }}"
dest: "{{ horizon_ssl_ca_cert }}"
owner: "{{ horizon_system_user_name }}"
group: "{{ horizon_system_group_name }}"
mode: "0644"
condition: "{{ horizon_user_ssl_ca_cert is defined }}"
# Define user-provided SSL certificates
#horizon_user_ssl_cert: <path to cert on ansible deployment host>
#horizon_user_ssl_key: <path to cert on ansible deployment host>
#horizon_user_ssl_ca_cert: <path to cert on ansible deployment host>

View File

@ -30,3 +30,4 @@
daemon_reload: "{{ (ansible_facts['service_mgr'] == 'systemd') | ternary('yes', omit) }}" daemon_reload: "{{ (ansible_facts['service_mgr'] == 'systemd') | ternary('yes', omit) }}"
listen: listen:
- "venv changed" - "venv changed"
- "cert installed"

View File

@ -0,0 +1,6 @@
---
deprecations:
- |
Variables ``horizon_ssl_self_signed_regen`` and
``horizon_ssl_self_signed_subject`` are deprecated. Horizon role uses
ansible-role-pki now so they are no longer needed.

View File

@ -1,31 +0,0 @@
---
# Copyright 2014, 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: "{{ horizon_ssl_cert }}"
state: "absent"
when: horizon_ssl_self_signed_regen | bool
- name: Create self-signed ssl cert
command: >
openssl req -new -nodes -sha256 -x509 -subj
"{{ horizon_ssl_self_signed_subject }}"
-days 3650
-keyout {{ horizon_ssl_key }}
-out {{ horizon_ssl_cert }}
-extensions v3_ca
creates={{ horizon_ssl_cert }}
notify: Restart wsgi process

View File

@ -1,30 +0,0 @@
---
# Copyright 2014, 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: "{{ horizon_ssl_key }}"
content: "{{ hostvars[groups['horizon_all'][0]]['horizon_ssl_key_fact'] | b64decode }}"
owner: "{{ horizon_system_user_name }}"
group: "{{ horizon_system_group_name }}"
mode: "0640"
- name: Distribute self signed ssl cert
copy:
dest: "{{ horizon_ssl_cert }}"
content: "{{ hostvars[groups['horizon_all'][0]]['horizon_ssl_cert_fact'] | b64decode }}"
owner: "{{ horizon_system_user_name }}"
group: "{{ horizon_system_group_name }}"
mode: "0640"

View File

@ -1,31 +0,0 @@
---
# Copyright 2014, 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: "{{ horizon_ssl_cert }}"
register: _horizon_ssl_cert
changed_when: false
- name: Store ssl key
slurp:
src: "{{ horizon_ssl_key }}"
register: _horizon_ssl_key
changed_when: false
- name: Register a fact for the cert and key
set_fact:
horizon_ssl_cert_fact: "{{ _horizon_ssl_cert.content }}"
horizon_ssl_key_fact: "{{ _horizon_ssl_key.content }}"

View File

@ -1,23 +0,0 @@
---
# Copyright 2014, 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.
- include_tasks: horizon_ssl_key_create.yml
when: inventory_hostname == groups['horizon_all'][0]
- include_tasks: horizon_ssl_key_store.yml
when: inventory_hostname == groups['horizon_all'][0]
- include_tasks: horizon_ssl_key_distribute.yml
when: inventory_hostname != groups['horizon_all'][0]

View File

@ -1,44 +0,0 @@
---
# Copyright 2014, 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: Drop user provided ssl cert
copy:
src: "{{ horizon_user_ssl_cert }}"
dest: "{{ horizon_ssl_cert }}"
owner: "root"
group: "root"
mode: "0644"
when: horizon_user_ssl_cert is defined
notify: Restart wsgi process
- name: Drop user provided ssl key
copy:
src: "{{ horizon_user_ssl_key }}"
dest: "{{ horizon_ssl_key }}"
owner: "root"
group: "root"
mode: "0640"
when: horizon_user_ssl_key is defined
notify: Restart wsgi process
- name: Drop user provided ssl CA cert
copy:
src: "{{ horizon_user_ssl_ca_cert }}"
dest: "{{ horizon_ssl_ca_cert }}"
owner: "root"
group: "root"
mode: "0644"
when: horizon_user_ssl_ca_cert is defined
notify: Restart wsgi process

View File

@ -51,32 +51,30 @@
tags: tags:
- horizon-install - horizon-install
- name: Create and install SSL certificates
include_role:
name: pki
tasks_from: main_certs.yml
apply:
tags:
- horizon-config
- pki
vars:
pki_setup_host: "{{ horizon_pki_setup_host }}"
pki_dir: "{{ horizon_pki_dir }}"
pki_create_certificates: "{{ horizon_user_ssl_cert is not defined and horizon_user_ssl_key is not defined }}"
pki_regen_cert: "{{ horizon_pki_regen_cert }}"
pki_certificates: "{{ horizon_pki_certificates }}"
pki_install_certificates: "{{ horizon_pki_install_certificates }}"
when:
- horizon_backend_ssl
tags:
- always
- import_tasks: horizon_post_install.yml - import_tasks: horizon_post_install.yml
tags: tags:
- horizon-config - horizon-config
- import_tasks: horizon_ssl_self_signed.yml
when:
- horizon_backend_ssl | bool
- horizon_user_ssl_cert is not defined or horizon_user_ssl_key is not defined
tags:
- horizon-config
- import_tasks: horizon_ssl_user_provided.yml
when:
- horizon_backend_ssl | bool
tags:
- horizon-config
- name: Update the ca certificates
command: "update-ca-certificates -f"
when:
- horizon_backend_ssl | bool
- ansible_facts['pkg_mgr'] == 'apt'
tags:
- horizon-config
- horizon-ssl
- import_tasks: horizon_service_setup.yml - import_tasks: horizon_service_setup.yml
when: when:
- ('horizon_all' in group_names) - ('horizon_all' in group_names)