diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index f34c68aa9c..df93003f9d 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -35,7 +35,8 @@ kolla_install_type: "binary" kolla_internal_vip_address: "{{ kolla_internal_address }}" kolla_internal_fqdn: "{{ kolla_internal_vip_address }}" kolla_external_vip_address: "{{ kolla_internal_vip_address }}" -kolla_external_fqdn: "{{ kolla_internal_fqdn if kolla_external_vip_address == kolla_internal_vip_address else kolla_external_vip_address }}" +kolla_same_external_internal_vip: "{{ kolla_external_vip_address == kolla_internal_vip_address }}" +kolla_external_fqdn: "{{ kolla_internal_fqdn if kolla_same_external_internal_vip | bool else kolla_external_vip_address }}" kolla_enable_sanity_checks: "no" @@ -467,8 +468,8 @@ opendaylight_websocket_port: "8185" vitrage_api_port: "8999" public_protocol: "{{ 'https' if kolla_enable_tls_external | bool else 'http' }}" -internal_protocol: "http" -admin_protocol: "http" +internal_protocol: "{{ 'https' if kolla_enable_tls_internal | bool else 'http' }}" +admin_protocol: "{{ 'https' if kolla_enable_tls_internal | bool else 'http' }}" #################### # OpenStack options @@ -738,10 +739,13 @@ qdrouterd_user: "openstack" # HAProxy options #################### haproxy_user: "openstack" -haproxy_enable_external_vip: "{{ 'no' if kolla_external_vip_address == kolla_internal_vip_address else 'yes' }}" -kolla_enable_tls_external: "no" +haproxy_enable_external_vip: "{{ 'no' if kolla_same_external_internal_vip | bool else 'yes' }}" +kolla_enable_tls_internal: "no" +kolla_enable_tls_external: "{{ kolla_enable_tls_internal if kolla_same_external_internal_vip | bool else 'no' }}" kolla_external_fqdn_cert: "{{ node_config }}/certificates/haproxy.pem" +kolla_internal_fqdn_cert: "{{ node_config }}/certificates/haproxy-internal.pem" kolla_external_fqdn_cacert: "{{ node_config }}/certificates/haproxy-ca.crt" +kolla_internal_fqdn_cacert: "{{ node_config }}/certificates/haproxy-ca-internal.crt" #################### diff --git a/ansible/roles/common/templates/admin-openrc.sh.j2 b/ansible/roles/common/templates/admin-openrc.sh.j2 index 79a1ada127..0659a350f6 100644 --- a/ansible/roles/common/templates/admin-openrc.sh.j2 +++ b/ansible/roles/common/templates/admin-openrc.sh.j2 @@ -15,6 +15,8 @@ export OS_MANILA_ENDPOINT_TYPE=internalURL export OS_IDENTITY_API_VERSION=3 export OS_REGION_NAME={{ openstack_region_name }} export OS_AUTH_PLUGIN=password -{% if kolla_enable_tls_external | bool and kolla_external_fqdn_cacert %} +{% if kolla_enable_tls_internal | bool and kolla_internal_fqdn_cacert %} +export OS_CACERT={{ kolla_internal_fqdn_cacert }} +{% elif kolla_enable_tls_external | bool and kolla_external_fqdn_cacert %} export OS_CACERT={{ kolla_external_fqdn_cacert }} {% endif %} diff --git a/ansible/roles/haproxy-config/templates/haproxy_single_service_listen.cfg.j2 b/ansible/roles/haproxy-config/templates/haproxy_single_service_listen.cfg.j2 index 528472616f..c23071a373 100644 --- a/ansible/roles/haproxy-config/templates/haproxy_single_service_listen.cfg.j2 +++ b/ansible/roles/haproxy-config/templates/haproxy_single_service_listen.cfg.j2 @@ -1,5 +1,6 @@ #jinja2: lstrip_blocks: True -{%- set tls_bind_info = 'ssl crt /etc/haproxy/haproxy.pem' if kolla_enable_tls_external|bool else '' %} +{%- set external_tls_bind_info = 'ssl crt /etc/haproxy/haproxy.pem' if kolla_enable_tls_external|bool else '' %} +{%- set internal_tls_bind_info = 'ssl crt /etc/haproxy/haproxy-internal.pem' if kolla_enable_tls_internal|bool else '' %} {%- macro userlist_macro(service_name, auth_user, auth_pass) %} userlist {{ service_name }}-user @@ -36,12 +37,17 @@ listen {{ service_name }} {% if external|bool %} {% set vip_address = kolla_external_vip_address %} {% if service_mode == 'http' %} - {% set tls_option = tls_bind_info %} + {% set tls_option = external_tls_bind_info %} {# Replace the XFP header for external https requests #} http-request set-header X-Forwarded-Proto https if { ssl_fc } {% endif %} {% else %} {% set vip_address = kolla_internal_vip_address %} + {% if service_mode == 'http' %} + {% set tls_option = internal_tls_bind_info %} + {# Replace the XFP header for internal https requests #} + http-request set-header X-Forwarded-Proto https if { ssl_fc } + {% endif %} {% endif %} {{ "bind %s:%s %s"|e|format(vip_address, service_port, tls_option)|trim() }} {# Redirect mode sets a redirect scheme instead of members #} diff --git a/ansible/roles/haproxy-config/templates/haproxy_single_service_split.cfg.j2 b/ansible/roles/haproxy-config/templates/haproxy_single_service_split.cfg.j2 index 6bd563f0ab..2e3eee74a7 100644 --- a/ansible/roles/haproxy-config/templates/haproxy_single_service_split.cfg.j2 +++ b/ansible/roles/haproxy-config/templates/haproxy_single_service_split.cfg.j2 @@ -1,5 +1,6 @@ #jinja2: lstrip_blocks: True -{%- set tls_bind_info = 'ssl crt /etc/haproxy/haproxy.pem' if kolla_enable_tls_external|bool else '' %} +{%- set external_tls_bind_info = 'ssl crt /etc/haproxy/haproxy.pem' if kolla_enable_tls_external|bool else '' %} +{%- set internal_tls_bind_info = 'ssl crt /etc/haproxy/haproxy-internal.pem' if kolla_enable_tls_internal|bool else '' %} {%- macro userlist_macro(service_name, auth_user, auth_pass) %} userlist {{ service_name }}-user @@ -29,12 +30,17 @@ frontend {{ service_name }}_front {% if external|bool %} {% set vip_address = kolla_external_vip_address %} {% if service_mode == 'http' %} - {% set tls_option = tls_bind_info %} + {% set tls_option = external_tls_bind_info %} {# Replace the XFP header for external https requests #} http-request set-header X-Forwarded-Proto https if { ssl_fc } {% endif %} {% else %} {% set vip_address = kolla_internal_vip_address %} + {% if service_mode == 'http' %} + {% set tls_option = internal_tls_bind_info %} + {# Replace the XFP header for internal https requests #} + http-request set-header X-Forwarded-Proto https if { ssl_fc } + {% endif %} {% endif %} {{ "bind %s:%s %s"|e|format(vip_address, service_port, tls_option)|trim() }} {# Redirect mode sets a redirect scheme instead of a backend #} diff --git a/ansible/roles/haproxy/tasks/config.yml b/ansible/roles/haproxy/tasks/config.yml index f6f9caa3ce..bea3e76714 100644 --- a/ansible/roles/haproxy/tasks/config.yml +++ b/ansible/roles/haproxy/tasks/config.yml @@ -109,6 +109,23 @@ notify: - Restart haproxy container +- name: Copying over haproxy-internal.pem + vars: + service: "{{ haproxy_services['haproxy'] }}" + copy: + src: "{{ kolla_internal_fqdn_cert }}" + dest: "{{ node_config_directory }}/haproxy/{{ item }}" + mode: "0660" + become: true + when: + - kolla_enable_tls_internal | bool + - inventory_hostname in groups[service.group] + - service.enabled | bool + with_items: + - "haproxy-internal.pem" + notify: + - Restart haproxy container + - name: Copying over haproxy start script vars: service: "{{ haproxy_services['haproxy'] }}" diff --git a/ansible/roles/haproxy/tasks/precheck.yml b/ansible/roles/haproxy/tasks/precheck.yml index 2dde07b845..49a1f3bbd7 100644 --- a/ansible/roles/haproxy/tasks/precheck.yml +++ b/ansible/roles/haproxy/tasks/precheck.yml @@ -77,20 +77,34 @@ check_mode: no run_once: true -- name: Checking if haproxy certificate exists +- name: Checking if external haproxy certificate exists run_once: true local_action: stat path={{ kolla_external_fqdn_cert }} register: haproxy_cert_file changed_when: false when: kolla_enable_tls_external | bool -- name: Fail if haproxy certificate is absent +- name: Fail if external haproxy certificate is absent run_once: true - local_action: fail msg="haproxy certificate file is not found. Ensure it exists as {{ kolla_external_fqdn_cert }}" + local_action: fail msg="External haproxy certificate file is not found. It is configured via 'kolla_external_fqdn_cert'" when: - kolla_enable_tls_external | bool - haproxy_cert_file.stat.exists == false +- name: Checking if internal haproxy certificate exists + run_once: true + local_action: stat path={{ kolla_internal_fqdn_cert }} + register: haproxy_internal_cert_file + changed_when: false + when: kolla_enable_tls_internal | bool + +- name: Fail if internal haproxy certificate is absent + run_once: true + local_action: fail msg="Internal haproxy certificate file is not found. It is configured via 'kolla_internal_fqdn_cert'" + when: + - kolla_enable_tls_internal | bool + - haproxy_internal_cert_file.stat.exists == false + - name: Checking the kolla_external_vip_interface is present fail: "msg='Please check the kolla_external_vip_interface property - interface {{ kolla_external_vip_interface }} not found'" when: diff --git a/ansible/roles/haproxy/templates/haproxy.json.j2 b/ansible/roles/haproxy/templates/haproxy.json.j2 index 9cd43adb94..a51a8ed7ab 100644 --- a/ansible/roles/haproxy/templates/haproxy.json.j2 +++ b/ansible/roles/haproxy/templates/haproxy.json.j2 @@ -25,6 +25,13 @@ "owner": "root", "perm": "0600", "optional": {{ (not kolla_enable_tls_external | bool) | string | lower }} + }, + { + "source": "{{ container_config_directory }}/haproxy-internal.pem", + "dest": "/etc/haproxy/haproxy-internal.pem", + "owner": "root", + "perm": "0600", + "optional": {{ (not kolla_enable_tls_internal | bool) | string | lower }} } ] } diff --git a/ansible/roles/haproxy/templates/haproxy_main.cfg.j2 b/ansible/roles/haproxy/templates/haproxy_main.cfg.j2 index cdc242986f..85b9d7642e 100644 --- a/ansible/roles/haproxy/templates/haproxy_main.cfg.j2 +++ b/ansible/roles/haproxy/templates/haproxy_main.cfg.j2 @@ -13,7 +13,7 @@ global {% endfor %} {% endif %} stats socket /var/lib/kolla/haproxy/haproxy.sock group kolla mode 660 - {% if kolla_enable_tls_external | bool %} + {% if kolla_enable_tls_external or kolla_enable_tls_internal | bool %} ssl-default-bind-ciphers DEFAULT:!MEDIUM:!3DES ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 tune.ssl.default-dh-param 4096 diff --git a/ansible/roles/horizon/defaults/main.yml b/ansible/roles/horizon/defaults/main.yml index a0d2b85da7..ced3f46934 100644 --- a/ansible/roles/horizon/defaults/main.yml +++ b/ansible/roles/horizon/defaults/main.yml @@ -42,10 +42,16 @@ horizon_services: enabled: "{{ enable_horizon }}" mode: "http" external: false - port: "{{ horizon_port }}" + port: "{% if kolla_enable_tls_internal|bool %}443{% else %}{{ horizon_port }}{% endif %}" listen_port: "{{ horizon_listen_port }}" frontend_http_extra: - "balance source" + horizon_redirect: + enabled: "{{ enable_horizon|bool and kolla_enable_tls_internal|bool }}" + mode: "redirect" + external: false + port: "{{ horizon_port }}" + listen_port: "{{ horizon_listen_port }}" horizon_external: enabled: "{{ enable_horizon }}" mode: "http" diff --git a/ansible/roles/horizon/templates/horizon.conf.j2 b/ansible/roles/horizon/templates/horizon.conf.j2 index 425a629e80..9577252496 100644 --- a/ansible/roles/horizon/templates/horizon.conf.j2 +++ b/ansible/roles/horizon/templates/horizon.conf.j2 @@ -33,7 +33,7 @@ TraceEnable off -{% if kolla_enable_tls_external | bool %} +{% if kolla_enable_tls_external or kolla_enable_tls_internal| bool %} Header edit Location ^http://(.*)$ https://$1 {% endif %} diff --git a/ansible/roles/horizon/templates/local_settings.j2 b/ansible/roles/horizon/templates/local_settings.j2 index 77ba0c0bea..868f0057df 100644 --- a/ansible/roles/horizon/templates/local_settings.j2 +++ b/ansible/roles/horizon/templates/local_settings.j2 @@ -55,7 +55,7 @@ DATABASES = { #CSRF_COOKIE_SECURE = True #SESSION_COOKIE_SECURE = True -{% if kolla_enable_tls_external | bool %} +{% if kolla_enable_tls_external or kolla_enable_tls_internal | bool %} SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') CSRF_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True diff --git a/ansible/roles/nova/templates/nova.conf.j2 b/ansible/roles/nova/templates/nova.conf.j2 index c4065a16c7..838b1212db 100644 --- a/ansible/roles/nova/templates/nova.conf.j2 +++ b/ansible/roles/nova/templates/nova.conf.j2 @@ -229,7 +229,7 @@ debug = {{ nova_logging_debug }} [wsgi] api_paste_config = /etc/nova/api-paste.ini -{% if kolla_enable_tls_external | bool %} +{% if kolla_enable_tls_external or kolla_enable_tls_internal | bool %} secure_proxy_ssl_header = HTTP_X_FORWARDED_PROTO {% endif %} diff --git a/ansible/roles/prechecks/tasks/service_checks.yml b/ansible/roles/prechecks/tasks/service_checks.yml index 8a295f93be..14b49fed28 100644 --- a/ansible/roles/prechecks/tasks/service_checks.yml +++ b/ansible/roles/prechecks/tasks/service_checks.yml @@ -33,10 +33,11 @@ when: - nscd_status.rc == 0 -- name: Checking internal and external VIP addresses differ +- name: Validate that internal and external vip address are different when TLS is enabled only on either the internal and external network run_once: True - local_action: fail msg='kolla_external_vip_address and kolla_internal_vip_address must not be the same when TLS is enabled' + local_action: fail msg='kolla_external_vip_address and kolla_internal_vip_address must not be the same when only one network has TLS enabled' changed_when: false when: - - kolla_enable_tls_external | bool - - kolla_external_vip_address == kolla_internal_vip_address + - kolla_enable_tls_external | bool or kolla_enable_tls_internal | bool + - not (kolla_enable_tls_external | bool and kolla_enable_tls_internal | bool) + - kolla_same_external_internal_vip | bool diff --git a/doc/source/admin/advanced-configuration.rst b/doc/source/admin/advanced-configuration.rst index 9a07d043c5..6102671d60 100644 --- a/doc/source/admin/advanced-configuration.rst +++ b/doc/source/admin/advanced-configuration.rst @@ -73,19 +73,26 @@ TLS Configuration ~~~~~~~~~~~~~~~~~ An additional endpoint configuration option is to enable or disable -TLS protection for the external VIP. TLS allows a client to authenticate -the OpenStack service endpoint and allows for encryption of the requests -and responses. - -.. note:: - - The kolla_internal_vip_address and kolla_external_vip_address must - be different to enable TLS on the external network. +TLS protection for the internal and/or external VIP. TLS allows a client to +authenticate the OpenStack service endpoint and allows for encryption of the +requests and responses. The configuration variables that control TLS networking are: - kolla_enable_tls_external - kolla_external_fqdn_cert +- kolla_enable_tls_internal +- kolla_internal_fqdn_cert + +.. note:: + + If TLS is enabled only on the internal or the external network + the kolla_internal_vip_address and kolla_external_vip_address must + be different. + + If there is only a single network configured in your network topology + (opposed to configuring seperate internal and external networks), TLS + can be enabled using only the internal network configuration variables. The default for TLS is disabled, to enable TLS networking: @@ -94,6 +101,12 @@ The default for TLS is disabled, to enable TLS networking: kolla_enable_tls_external: "yes" kolla_external_fqdn_cert: "{{ node_config }}/certificates/mycert.pem" + and/or + + kolla_enable_tls_internal: "yes" + kolla_internal_fqdn_cert: "{{ node_config }}/certificates/mycert-internal.pem" + + .. note:: TLS authentication is based on certificates that have been @@ -111,9 +124,9 @@ These two files will be provided by your Certificate Authority. These two files are the server certificate with private key and the CA certificate with any intermediate certificates. The server certificate needs to be installed with the kolla deployment and is configured with the -``kolla_external_fqdn_cert`` parameter. If the server certificate provided -is not already trusted by the client, then the CA certificate file will -need to be distributed to the client. +``kolla_external_fqdn_cert`` or ``kolla_internal_fqdn_cert`` parameter. +If the server certificate provided is not already trusted by the client, +then the CA certificate file will need to be distributed to the client. When using TLS to connect to a public endpoint, an OpenStack client will have settings similar to this: diff --git a/releasenotes/notes/add-internal-network-tls-configuration-cf9704812f113281.yaml b/releasenotes/notes/add-internal-network-tls-configuration-cf9704812f113281.yaml new file mode 100644 index 0000000000..be9bdb7fc3 --- /dev/null +++ b/releasenotes/notes/add-internal-network-tls-configuration-cf9704812f113281.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Added configuration parameters ``kolla_enable_tls_internal``, + ``kolla_internal_fqdn_cert``, and ``kolla_internal_fqdn_cacert`` to + optionally enable TLS encryption for openstack endpoints on the internal + network.