OpenStack HTTPS Endpoints support
Communication between services usually done via internal
endpoints that are located in internal network. In some
cases it is required to encrypt traffic even on internal
network. This patch unhardcode communication protocol between
Nova and other services. Also adds possibility to specify
ca_file to verify SSL certificates of remote peers.
This change is fully backward compatible.
Related-Prod: PROD-15737
Change-Id: Ic2f07c9dc064150b0c5721104550623778844114
diff --git a/README.rst b/README.rst
index c3a67f1..7aaedd9 100644
--- a/README.rst
+++ b/README.rst
@@ -159,58 +159,80 @@
enabled: true
-Client-side RabbitMQ TLS configuration:
----------------------------------------
+Configuring TLS communications
+------------------------------
-To enable TLS for oslo.messaging you need to provide the CA certificate.
-By default system-wide CA certs is used. Nothing should be specified except `ssl.enabled`.
+**Note:** by default system wide installed CA certs are used, so ``cacert_file`` param is optional, as well as ``cacert``.
+
+
+
+- **RabbitMQ TLS**
.. code-block:: yaml
- nova:
- controller:
- ....
+ nova:
+ compute:
message_queue:
+ port: 5671
ssl:
enabled: True
+ (optional) cacert: cert body if the cacert_file does not exists
+ (optional) cacert_file: /etc/openstack/rabbitmq-ca.pem
+ (optional) version: TLSv1_2
-
-Use `cacert_file` option to specify the CA-cert file path explicitly:
+- **MySQL TLS**
.. code-block:: yaml
- nova:
- controller:
- ....
- message_queue:
+ nova:
+ controller:
+ database:
ssl:
enabled: True
- cacert_file: /etc/ssl/rabbitmq-ca.pem
+ (optional) cacert: cert body if the cacert_file does not exists
+ (optional) cacert_file: /etc/openstack/mysql-ca.pem
-To manage content of the `cacert_file` use the `cacert` option:
+- **Openstack HTTPS API**
+
+
+Set the ``https`` as protocol at ``nova:compute`` and ``nova:controller`` sections :
.. code-block:: yaml
- nova:
- controller:
- ....
- message_queue:
- ssl:
- enabled: True
- cacert: |
-
- -----BEGIN CERTIFICATE-----
- ...
- -----END CERTIFICATE-------
-
- cacert_file: /etc/openstack/rabbitmq-ca.pem
+ nova:
+ controller :
+ identity:
+ protocol: https
+ (optional) cacert_file: /etc/openstack/proxy.pem
+ network:
+ protocol: https
+ (optional) cacert_file: /etc/openstack/proxy.pem
+ glance:
+ protocol: https
+ (optional) cacert_file: /etc/openstack/proxy.pem
-Notice:
- * The `message_queue.port` is set to **5671** (AMQPS) by default if `ssl.enabled=True`.
- * Use `message_queue.ssl.version` if you need to specify protocol version. By default is TLSv1 for python < 2.7.9 and TLSv1_2 for version above.
+.. code-block:: yaml
+
+ nova:
+ compute:
+ identity:
+ protocol: https
+ (optional) cacert_file: /etc/openstack/proxy.pem
+ network:
+ protocol: https
+ (optional) cacert_file: /etc/openstack/proxy.pem
+ image:
+ protocol: https
+ (optional) cacert_file: /etc/openstack/proxy.pem
+ ironic:
+ protocol: https
+ (optional) cacert_file: /etc/openstack/proxy.pem
+
+
+**Note:** the barbican, cinder and placement url endpoints are discovering using service catalog.
Compute nodes
diff --git a/nova/files/ocata/nova-compute.conf.Debian b/nova/files/ocata/nova-compute.conf.Debian
index ecd3b5b..38f3664 100644
--- a/nova/files/ocata/nova-compute.conf.Debian
+++ b/nova/files/ocata/nova-compute.conf.Debian
@@ -3496,6 +3496,9 @@
# Use this endpoint to connect to Keystone (string value)
auth_endpoint={{ compute.identity.get('protocol', 'http') }}://{{ compute.identity.get('host', 'localhost') }}:{{ compute.identity.get('port', '5000') }}/v3
+{%- if compute.identity.get('protocol', 'http') == 'https' %}
+cafile={{ compute.identity.get('cacert_file', compute.cacert_file) }}
+{%- endif %}
# Number of seconds to wait before retrying poll for key creation completion
# (integer value)
@@ -4050,6 +4053,9 @@
#
os_region_name = {{ compute.identity.region }}
catalog_info=volumev2:cinderv2:internalURL
+{%- if compute.image.get('protocol', 'http') == 'https' %}
+cafile={{ compute.identity.get('cacert_file', compute.cacert_file) }}
+{%- endif %}
#
# Info to match when looking for cinder in the service catalog.
#
@@ -5022,7 +5028,7 @@
# (list value)
#api_servers=<None>
{%- if compute.image is defined %}
-api_servers=http://{{ compute.image.host }}:9292
+api_servers = {{ compute.image.get('protocol', 'http') }}://{{ compute.image.host }}:{{ compute.image.get('port', 9292) }}
{% endif %}
#
@@ -5498,7 +5504,7 @@
#
# URL override for the Ironic API endpoint. (string value)
-api_endpoint=http://{{ compute.ironic.host }}:{{ compute.ironic.port }}
+api_endpoint={{ compute.ironic.get('protocol', 'http') }}://{{ compute.ironic.host }}:{{ compute.ironic.port }}
#
# The number of times to retry when a request conflicts.
@@ -5528,10 +5534,9 @@
# PEM encoded Certificate Authority to use when verifying HTTPs connections.
# (string value)
-#cafile=<None>
-
-# PEM encoded client certificate cert file (string value)
-#certfile=<None>
+{%- if compute.ironic.get('protocol', 'http') == 'https' %}
+cafile={{ compute.identity.get('cacert_file', compute.cacert_file) }}
+{%- endif %}
# PEM encoded client certificate key file (string value)
#keyfile=<None>
@@ -5550,7 +5555,7 @@
#auth_section=<None>
# Authentication URL (string value)
-auth_url=http://{{ compute.identity.host }}:{{ compute.identity.port }}/v3
+auth_url={{ compute.identity.get('protocol', 'http') }}://{{ compute.identity.host }}:{{ compute.identity.port }}/v3
# Domain ID to scope to (string value)
#domain_id=<None>
@@ -5687,8 +5692,11 @@
project_name = {{ compute.identity.tenant }}
username = {{ compute.identity.user }}
password = {{ compute.identity.password }}
-auth_uri=http://{{ compute.identity.host }}:5000
-auth_url=http://{{ compute.identity.host }}:35357
+auth_uri={{ compute.identity.get('protocol', 'http') }}://{{ compute.identity.host }}:5000
+auth_url={{ compute.identity.get('protocol', 'http') }}://{{ compute.identity.host }}:35357
+{%- if compute.identity.get('protocol', 'http') == 'https' %}
+cafile={{ compute.identity.get('cacert_file', compute.cacert_file) }}
+{%- endif %}
{%- if compute.cache is defined %}
memcached_servers={%- for member in compute.cache.members %}{{ member.host }}:11211{% if not loop.last %},{% endif %}{%- endfor %}
{%- endif %}
@@ -7101,8 +7109,11 @@
username={{ compute.network.user }}
password={{ compute.network.password }}
project_name={{ compute.identity.tenant }}
-auth_url=http://{{ compute.identity.host }}:{{ compute.identity.port }}/v3
-url=http://{{ compute.network.host }}:{{ compute.network.port }}
+auth_url = {{ compute.identity.get('protocol', 'http') }}://{{ compute.identity.host }}:{{ compute.identity.port }}/v3
+url={{ compute.network.get('protocol', 'http') }}://{{ compute.network.host }}:{{ compute.network.port }}
+{%- if compute.network.get('protocol', 'http') == 'https' %}
+cafile={{ compute.network.get('cacert_file', compute.cacert_file) }}
+{%- endif %}
region_name= {{ compute.network.region }}
extension_sync_interval={{ compute.network.get('extension_sync_interval', '600') }}
auth_type = v3password
@@ -8293,7 +8304,10 @@
project_name = {{ compute.identity.tenant }}
username = {{ compute.identity.user }}
password = {{ compute.identity.password }}
-auth_url=http://{{ compute.identity.host }}:35357/v3
+{%- if compute.identity.get('protocol', 'http') == 'https' %}
+cafile={{ compute.identity.get('cacert_file', compute.cacert_file) }}
+{%- endif %}
+auth_url={{ compute.identity.get('protocol', 'http') }}://{{ compute.identity.host }}:35357/v3
os_interface = internal
#
@@ -9231,8 +9245,9 @@
# CA certificate file to use to verify connecting clients. (string value)
# Deprecated group/name - [DEFAULT]/ssl_ca_file
-#ca_file=<None>
-
+{%- if compute.identity.get('protocol', 'http') == 'htpps' %}
+ca_file={{ compute.image.get('cacert_file', compute.cacert_file) }}
+{%- endif %}
# Certificate file to use when starting the server securely. (string value)
# Deprecated group/name - [DEFAULT]/ssl_cert_file
#cert_file=<None>
diff --git a/nova/files/ocata/nova-controller.conf.Debian b/nova/files/ocata/nova-controller.conf.Debian
index 95cdfad..f6bc29c 100644
--- a/nova/files/ocata/nova-controller.conf.Debian
+++ b/nova/files/ocata/nova-controller.conf.Debian
@@ -3479,6 +3479,9 @@
# Use this endpoint to connect to Keystone (string value)
{%- if controller.get('barbican', {}).get('enabled', False) %}
auth_endpoint={{ controller.identity.get('protocol', 'http') }}://{{ controller.identity.get('host', 'localhost') }}:{{ controller.identity.get('port', '5000') }}/v3
+{%- if controller.identity.get('protocol', 'http') == 'https' %}
+cafile={{ controller.identity.get('cacert_file', controller.cacert_file) }}
+{%- endif %}
{%- endif %}
# Number of seconds to wait before retrying poll for key creation completion
@@ -4050,7 +4053,9 @@
# (string value)
#catalog_info=volumev2:cinderv2:publicURL
catalog_info=volumev2:cinderv2:internalURL
-
+{%- if controller.glance.get('protocol', 'http') == 'https' %}
+cafile={{ controller.identity.get('cacert_file', controller.cacert_file) }}
+{%- endif %}
#
# If this option is set then it will override service catalog lookup with
# this template for cinder endpoint
@@ -5043,7 +5048,7 @@
# (i.e. "http://10.0.1.0:9292" or "https://my.glance.server/image").
# (list value)
#api_servers=<None>
-api_servers = {{ controller.glance.host }}:9292
+api_servers = {{ controller.glance.get('protocol', 'http') }}://{{ controller.glance.host }}:{{ controller.glance.get('port', 9292) }}
#
# Enable insecure SSL (https) requests to glance.
@@ -5703,8 +5708,11 @@
project_name = {{ controller.identity.tenant }}
username = {{ controller.identity.user }}
password = {{ controller.identity.password }}
-auth_uri=http://{{ controller.identity.host }}:5000
-auth_url=http://{{ controller.identity.host }}:35357
+auth_uri={{ controller.identity.get('protocol', 'http') }}://{{ controller.identity.host }}:5000
+auth_url={{ controller.identity.get('protocol', 'http') }}://{{ controller.identity.host }}:35357
+{%- if controller.identity.get('protocol', 'http') == 'https' %}
+cafile={{ controller.identity.get('cacert_file', controller.cacert_file) }}
+{%- endif %}
{%- if controller.cache is defined %}
memcached_servers={%- for member in controller.cache.members %}{{ member.host }}:11211{% if not loop.last %},{% endif %}{%- endfor %}
{%- endif %}
@@ -7082,7 +7090,7 @@
auth_type=v3password
project_domain_name = Default
user_domain_name = Default
-auth_url = http://{{ controller.identity.host }}:35357/v3
+auth_url = {{ controller.identity.get('protocol', 'http') }}://{{ controller.identity.host }}:35357/v3
{% if pillar.neutron is defined and pillar.neutron.server is defined %}
password={{ pillar.neutron.server.identity.password }}
project_name={{ pillar.neutron.server.identity.tenant }}
@@ -7094,8 +7102,10 @@
username={{ controller.network.user }}
region_name= {{ controller.network.region }}
{%- endif %}
-url=http://{{ controller.network.host }}:{{ controller.network.port }}
-
+url={{ controller.network.get('protocol', 'http') }}://{{ controller.network.host }}:{{ controller.network.port }}
+{%- if controller.network.get('protocol', 'http') == 'https' %}
+cafile={{ controller.network.get('cacert_file', controller.cacert_file) }}
+{%- endif %}
{%- if controller.get('networking', 'default') != "contrail" %}
metadata_proxy_shared_secret={{ controller.metadata.password }}
{%- endif %}
@@ -8284,7 +8294,10 @@
project_name = {{ controller.identity.tenant }}
username = {{ controller.identity.user }}
password = {{ controller.identity.password }}
-auth_url=http://{{ controller.identity.host }}:35357/v3
+auth_url={{ controller.identity.get('protocol', 'http') }}://{{ controller.identity.host }}:35357/v3
+{%- if controller.identity.get('protocol', 'http') == 'https' %}
+cafile={{ controller.identity.get('cacert_file', controller.cacert_file) }}
+{%- endif %}
os_interface = internal
#
@@ -9215,7 +9228,9 @@
# CA certificate file to use to verify connecting clients. (string value)
# Deprecated group/name - [DEFAULT]/ssl_ca_file
-#ca_file=<None>
+{%- if controller.identity.get('protocol', 'http') == 'https' %}
+ca_file={{ controller.glance.get('cacert_file', controller.cacert_file) }}
+{%- endif %}
# Certificate file to use when starting the server securely. (string value)
# Deprecated group/name - [DEFAULT]/ssl_cert_file