From c8f105a9070e25cee613962683639a351aad185c Mon Sep 17 00:00:00 2001 From: Mark Goddard Date: Wed, 27 Nov 2019 17:37:39 +0000 Subject: [PATCH] Support internal API TLS encryption Kolla Ansible Train introduces support for TLS encryption of the internal API. This change introduces support for internal API encryption in Kayobe. The following new variables are introduced: * kolla_enable_tls_internal * kolla_internal_tls_cert * kolla_internal_fqdn_cacert Also only set kolla_*_fqdn_cacert in globals.yml if set. Change-Id: If432afde374fe247d09c952e110c9567e17daea1 Story: 2006959 Task: 37649 --- ansible/group_vars/all/kolla | 33 +++++++++++++---- ansible/kolla-ansible.yml | 1 + ansible/roles/kolla-ansible/defaults/main.yml | 12 ++++--- ansible/roles/kolla-ansible/tasks/config.yml | 30 ++++++++++++---- .../kolla-ansible/templates/globals.yml.j2 | 7 ++++ .../kolla-ansible/tests/test-defaults.yml | 6 +++- .../roles/kolla-ansible/tests/test-extras.yml | 4 +++ .../kolla-ansible/tests/test-requirements.yml | 4 ++- .../templates/public-openrc.sh.j2 | 2 ++ doc/source/configuration/kolla-ansible.rst | 35 +++++++++++++++++-- etc/kayobe/kolla.yml | 32 +++++++++++++---- .../internal-api-tls-4e7383e6a0262f5f.yaml | 14 ++++++++ 12 files changed, 153 insertions(+), 27 deletions(-) create mode 100644 releasenotes/notes/internal-api-tls-4e7383e6a0262f5f.yaml diff --git a/ansible/group_vars/all/kolla b/ansible/group_vars/all/kolla index 2868ecbed..abf58709d 100644 --- a/ansible/group_vars/all/kolla +++ b/ansible/group_vars/all/kolla @@ -318,7 +318,10 @@ kolla_ansible_target_venv: "{{ virtualenv_path ~ '/kolla-ansible' }}" kolla_ansible_vault_password: "{{ lookup('env', 'KAYOBE_VAULT_PASSWORD') | default }}" # Whether TLS is enabled for the external API endpoints. -kolla_enable_tls_external: "no" +kolla_enable_tls_external: "{{ kolla_enable_tls_internal if public_net_name == internal_net_name else 'no' }}" + +# Whether TLS is enabled for the internal API endpoints. +kolla_enable_tls_internal: "no" # Whether debug logging is enabled. kolla_openstack_logging_debug: "False" @@ -411,14 +414,30 @@ kolla_ansible_custom_passwords: "{{ kolla_ansible_default_custom_passwords }}" ############################################################################### # TLS certificate bundle management -# Optionally copy a TLS certificate bundle into place. +# External API certificate bundle. # -# When enabled, this will copy the contents of kolla_tls_cert into place for -# use by HAProxy +# When kolla_enable_tls_external is true, this should contain an X.509 +# certificate bundle for the external API. # # Note that this should be formatted as a literal style block scalar. -kolla_tls_cert: +# TODO(mgoddard): Remove the deprecated support for kolla_tls_cert in the +# Ussuri cycle. +kolla_external_tls_cert: "{{ kolla_tls_cert | default }}" -# Path to a CA certificate file to use for the OS_CACERT environment variable in -# openrc files when TLS is enabled, instead of Kolla-Ansible's default. +# Path to a CA certificate file to use for the OS_CACERT environment variable +# in public-openrc.sh file when TLS is enabled, instead of Kolla-Ansible's +# default. kolla_external_fqdn_cacert: + +# Internal API certificate bundle. +# +# When kolla_enable_tls_internal is true, this should contain an X.509 +# certificate bundle for the internal API. +# +# Note that this should be formatted as a literal style block scalar. +kolla_internal_tls_cert: + +# Path to a CA certificate file to use for the OS_CACERT environment variable +# in admin-openrc.sh file when TLS is enabled, instead of Kolla-Ansible's +# default. +kolla_internal_fqdn_cacert: diff --git a/ansible/kolla-ansible.yml b/ansible/kolla-ansible.yml index 50481f5a5..854fdd30d 100644 --- a/ansible/kolla-ansible.yml +++ b/ansible/kolla-ansible.yml @@ -288,6 +288,7 @@ vars: kolla_ansible_install_epel: "{{ yum_install_epel }}" kolla_external_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy.pem" + kolla_internal_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy-internal.pem" kolla_ansible_passwords_path: "{{ kayobe_config_path }}/kolla/passwords.yml" # NOTE: This differs from the default SELinux mode in kolla ansible, # which is permissive. The justification for using this mode is twofold: diff --git a/ansible/roles/kolla-ansible/defaults/main.yml b/ansible/roles/kolla-ansible/defaults/main.yml index d7a440a21..2294dc679 100644 --- a/ansible/roles/kolla-ansible/defaults/main.yml +++ b/ansible/roles/kolla-ansible/defaults/main.yml @@ -200,12 +200,15 @@ kolla_neutron_ml2_tenant_network_types: [] #################### # TLS options #################### -# To provide encryption and authentication on the kolla_external_vip_interface, -# TLS can be enabled. When TLS is enabled, certificates must be provided to -# allow clients to perform authentication. +# To provide encryption and authentication on the external and/or internal +# APIs, TLS can be enabled. When TLS is enabled, certificates must be provided +# to allow clients to perform authentication. kolla_enable_tls_external: +kolla_enable_tls_internal: kolla_external_fqdn_cert: +kolla_internal_fqdn_cert: kolla_external_fqdn_cacert: +kolla_internal_fqdn_cacert: ############################# # Ironic options @@ -299,7 +302,8 @@ kolla_ansible_custom_passwords: {} # When set, this will copy the contents of this variable into place for # use by HAProxy. -kolla_tls_cert: +kolla_external_tls_cert: +kolla_internal_tls_cert: ############################################################################### # SELinux diff --git a/ansible/roles/kolla-ansible/tasks/config.yml b/ansible/roles/kolla-ansible/tasks/config.yml index 6519fc892..57b73065b 100644 --- a/ansible/roles/kolla-ansible/tasks/config.yml +++ b/ansible/roles/kolla-ansible/tasks/config.yml @@ -100,14 +100,32 @@ dest: "{{ kolla_config_path }}/passwords.yml" remote_src: True -- name: Ensure the HAProxy TLS certificate bundle is copied into place - block: - - file: +- block: + - name: Ensure external HAProxy TLS directory exists + file: path: "{{ kolla_external_fqdn_cert | dirname }}" state: directory recurse: yes - - copy: - content: "{{ kolla_tls_cert }}" + + - name: Ensure the external HAProxy TLS certificate bundle is copied into place + copy: + content: "{{ kolla_external_tls_cert }}" dest: "{{ kolla_external_fqdn_cert }}" when: - - kolla_tls_cert is not none + - kolla_external_tls_cert is not none + - kolla_external_tls_cert | length > 0 + +- block: + - name: Ensure internal HAProxy TLS directory exists + file: + path: "{{ kolla_internal_fqdn_cert | dirname }}" + state: directory + recurse: yes + + - name: Ensure the internal HAProxy TLS certificate bundle is copied into place + copy: + content: "{{ kolla_internal_tls_cert }}" + dest: "{{ kolla_internal_fqdn_cert }}" + when: + - kolla_internal_tls_cert is not none + - kolla_internal_tls_cert | length > 0 diff --git a/ansible/roles/kolla-ansible/templates/globals.yml.j2 b/ansible/roles/kolla-ansible/templates/globals.yml.j2 index a16ee2329..6bc96d479 100644 --- a/ansible/roles/kolla-ansible/templates/globals.yml.j2 +++ b/ansible/roles/kolla-ansible/templates/globals.yml.j2 @@ -180,9 +180,16 @@ neutron_tenant_network_types: {{ kolla_neutron_ml2_tenant_network_types | join(' # To provide encryption and authentication on the kolla_external_vip_interface, # TLS can be enabled. When TLS is enabled, certificates must be provided to # allow clients to perform authentication. +kolla_enable_tls_internal: {{ kolla_enable_tls_internal | bool }} kolla_enable_tls_external: {{ kolla_enable_tls_external | bool }} kolla_external_fqdn_cert: "{{ kolla_external_fqdn_cert }}" +kolla_internal_fqdn_cert: "{{ kolla_internal_fqdn_cert }}" +{% if kolla_external_fqdn_cacert %} kolla_external_fqdn_cacert: "{{ kolla_external_fqdn_cacert }}" +{% endif %} +{% if kolla_internal_fqdn_cacert %} +kolla_internal_fqdn_cacert: "{{ kolla_internal_fqdn_cacert }}" +{% endif %} ################ # Region options diff --git a/ansible/roles/kolla-ansible/tests/test-defaults.yml b/ansible/roles/kolla-ansible/tests/test-defaults.yml index 1c51780fe..b87e05153 100644 --- a/ansible/roles/kolla-ansible/tests/test-defaults.yml +++ b/ansible/roles/kolla-ansible/tests/test-defaults.yml @@ -30,8 +30,10 @@ kolla_external_vip_address: "10.0.0.2" kolla_external_fqdn: "fake.external.fqdn" kolla_enable_tls_external: False - kolla_enable_grafana: False kolla_external_fqdn_cert: "fake-cert" + kolla_enable_tls_internal: False + kolla_internal_fqdn_cert: "fake-cert" + kolla_enable_grafana: False kolla_openstack_logging_debug: False - name: Verify kolla-ansible installation @@ -70,6 +72,8 @@ neutron_plugin_agent: "openvswitch" kolla_enable_tls_external: False kolla_external_fqdn_cert: "fake-cert" + kolla_enable_tls_internal: False + kolla_internal_fqdn_cert: "fake-cert" openstack_logging_debug: False kolla_user: "kolla" kolla_group: "kolla" diff --git a/ansible/roles/kolla-ansible/tests/test-extras.yml b/ansible/roles/kolla-ansible/tests/test-extras.yml index ad4c40c30..477ecefee 100644 --- a/ansible/roles/kolla-ansible/tests/test-extras.yml +++ b/ansible/roles/kolla-ansible/tests/test-extras.yml @@ -96,6 +96,8 @@ - "fake-ml2-tenant-type-2" kolla_enable_tls_external: False kolla_external_fqdn_cert: "fake-cert" + kolla_enable_tls_internal: False + kolla_internal_fqdn_cert: "fake-cert" kolla_openstack_logging_debug: True grafana_local_admin_user_name: "grafana-admin" kolla_inspector_dhcp_pool_start: "1.2.3.4" @@ -229,6 +231,8 @@ neutron_plugin_agent: "openvswitch" kolla_enable_tls_external: False kolla_external_fqdn_cert: "fake-cert" + kolla_enable_tls_internal: False + kolla_internal_fqdn_cert: "fake-cert" openstack_logging_debug: True grafana_admin_username: "grafana-admin" ironic_dnsmasq_dhcp_range: "1.2.3.4,1.2.3.5" diff --git a/ansible/roles/kolla-ansible/tests/test-requirements.yml b/ansible/roles/kolla-ansible/tests/test-requirements.yml index a6063a07d..eea40f192 100644 --- a/ansible/roles/kolla-ansible/tests/test-requirements.yml +++ b/ansible/roles/kolla-ansible/tests/test-requirements.yml @@ -32,8 +32,10 @@ kolla_external_vip_address: "10.0.0.2" kolla_external_fqdn: "fake.external.fqdn" kolla_enable_tls_external: False - kolla_enable_grafana: False + kolla_enable_tls_internal: False kolla_external_fqdn_cert: "fake-cert" + kolla_internal_fqdn_cert: "fake-cert" + kolla_enable_grafana: False kolla_openstack_logging_debug: False - name: List Python packages installed in virtualenv diff --git a/ansible/roles/public-openrc/templates/public-openrc.sh.j2 b/ansible/roles/public-openrc/templates/public-openrc.sh.j2 index 6e04ca764..a78008871 100644 --- a/ansible/roles/public-openrc/templates/public-openrc.sh.j2 +++ b/ansible/roles/public-openrc/templates/public-openrc.sh.j2 @@ -5,6 +5,8 @@ export OS_AUTH_URL={{ public_openrc_auth_url }} {% elif "export OS_INTERFACE" in line %} export OS_INTERFACE=public +{% elif "export OS_CACERT" in line and kolla_external_fqdn_cacert is not none %} +export OS_CACERT={{ kolla_external_fqdn_cacert }} {% else %} {{ line }} {% endif %} diff --git a/doc/source/configuration/kolla-ansible.rst b/doc/source/configuration/kolla-ansible.rst index 0a0f93a6a..edcc40ea9 100644 --- a/doc/source/configuration/kolla-ansible.rst +++ b/doc/source/configuration/kolla-ansible.rst @@ -202,7 +202,7 @@ The following variables affect TLS encryption of the public API. ``kolla_enable_tls_external`` Whether TLS is enabled for the public API endpoints. Default is ``no``. -``kolla_tls_cert`` +``kolla_external_tls_cert`` A TLS certificate bundle to use for the public API endpoints, if ``kolla_enable_tls_external`` is ``true``. Note that this should be formatted as a literal style block scalar. @@ -211,6 +211,20 @@ The following variables affect TLS encryption of the public API. variable in openrc files when TLS is enabled, instead of Kolla Ansible's default. +The following variables affect TLS encryption of the internal API. Currently +this requires all Kolla images to be built with the API's root CA trusted. + +``kolla_enable_tls_internal`` + Whether TLS is enabled for the internal API endpoints. Default is ``no``. +``kolla_internal_tls_cert`` + A TLS certificate bundle to use for the internal API endpoints, if + ``kolla_enable_tls_internal`` is ``true``. Note that this should be + formatted as a literal style block scalar. +``kolla_internal_fqdn_cacert`` + Path to a CA certificate file to use for the ``OS_CACERT`` environment + variable in openrc files when TLS is enabled, instead of Kolla Ansible's + default. + Example: enabling TLS for the public API ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -222,12 +236,29 @@ Here is an example: --- kolla_enable_tls_external: yes - kolla_tls_cert: | + kolla_external_tls_cert: | -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- kolla_external_fqdn_cacert: /path/to/ca/certificate/bundle +Example: enabling TLS for the internal API +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It is highly recommended to use TLS encryption to secure the internal API. +Here is an example: + +.. code-block:: yaml + :caption: ``$KAYOBE_CONFIG_PATH/kolla.yml`` + + --- + kolla_enable_tls_internal: yes + kolla_internal_tls_cert: | + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- + kolla_internal_fqdn_cacert: /path/to/ca/certificate/bundle + Custom Global Variables ----------------------- diff --git a/etc/kayobe/kolla.yml b/etc/kayobe/kolla.yml index 591bb5fbb..cb66c1900 100644 --- a/etc/kayobe/kolla.yml +++ b/etc/kayobe/kolla.yml @@ -152,6 +152,9 @@ # Whether TLS is enabled for the external API endpoints. Default is 'no'. #kolla_enable_tls_external: +# Whether TLS is enabled for the internal API endpoints. Default is 'no'. +#kolla_enable_tls_internal: + # Whether debug logging is enabled. Default is 'false'. #kolla_openstack_logging_debug: @@ -269,18 +272,35 @@ ############################################################################### # TLS certificate bundle management -# Optionally copy a TLS certificate bundle into place. +# External API certificate bundle. # -# When enabled, this will copy the contents of kolla_tls_cert into place for -# use by HAproxy. +# When kolla_enable_tls_external is true, this should contain an X.509 +# certificate bundle for the external API. # # Note that this should be formatted as a literal style block scalar. -#kolla_tls_cert: +# +# NOTE: kolla_tls_cert has been renamed to kolla_external_tls_cert. Support for +# the deprecated name kolla_tls_cert will be removed in a future release. +#kolla_external_tls_cert: -# Path to a CA certificate file to use for the OS_CACERT environment variable in -# openrc files when TLS is enabled, instead of Kolla-Ansible's default. +# Path to a CA certificate file to use for the OS_CACERT environment variable +# in public-openrc.sh file when TLS is enabled, instead of Kolla-Ansible's +# default. #kolla_external_fqdn_cacert: +# Internal API certificate bundle. +# +# When kolla_enable_tls_internal is true, this should contain an X.509 +# certificate bundle for the internal API. +# +# Note that this should be formatted as a literal style block scalar. +#kolla_internal_tls_cert: + +# Path to a CA certificate file to use for the OS_CACERT environment variable +# in admin-openrc.sh file when TLS is enabled, instead of Kolla-Ansible's +# default. +#kolla_internal_fqdn_cacert: + ############################################################################### # Dummy variable to allow Ansible to accept this file. workaround_ansible_issue_8743: yes diff --git a/releasenotes/notes/internal-api-tls-4e7383e6a0262f5f.yaml b/releasenotes/notes/internal-api-tls-4e7383e6a0262f5f.yaml new file mode 100644 index 000000000..72643fd69 --- /dev/null +++ b/releasenotes/notes/internal-api-tls-4e7383e6a0262f5f.yaml @@ -0,0 +1,14 @@ +--- +features: + - | + Adds support for encryption of internal API traffic. This can be done via + the following variables: + + * ``kolla_enable_tls_internal`` + * ``kolla_internal_tls_cert`` + * ``kolla_internal_fqdn_cacert`` +deprecations: + - | + The variable ``kolla_tls_cert`` has been deprecated in favour of + ``kolla_external_tls_cert``. Support for using ``kolla_tls_cert`` will be + removed in a future release.