From d6251506f7cb4f797f5c957bafbf4814355020b1 Mon Sep 17 00:00:00 2001 From: James Kirsch Date: Thu, 30 Apr 2020 22:43:37 -0700 Subject: [PATCH] Add support for encrypting Nova API This patch introduces an optional backend encryption for the Nova API service. When used in conjunction with enabling TLS for service API endpoints, network communcation will be encrypted end to end, from client through HAProxy to the Nova service. Change-Id: I48e1540b973016079d5686b328e82239dcffacfd Partially-Implements: blueprint add-ssl-internal-network --- ansible/roles/nova/defaults/main.yml | 9 +++ ansible/roles/nova/tasks/config.yml | 14 +++- .../nova/templates/nova-api-wsgi.conf.j2 | 70 +++++++++++++++++++ ansible/roles/nova/templates/nova-api.json.j2 | 22 +++++- ansible/roles/nova/templates/nova.conf.j2 | 9 --- 5 files changed, 113 insertions(+), 11 deletions(-) create mode 100644 ansible/roles/nova/templates/nova-api-wsgi.conf.j2 diff --git a/ansible/roles/nova/defaults/main.yml b/ansible/roles/nova/defaults/main.yml index c871c7bdc4..3c13a50a88 100644 --- a/ansible/roles/nova/defaults/main.yml +++ b/ansible/roles/nova/defaults/main.yml @@ -17,24 +17,28 @@ nova_services: external: false port: "{{ nova_api_port }}" listen_port: "{{ nova_api_listen_port }}" + tls_backend: "{{ nova_enable_tls_backend }}" nova_api_external: enabled: "{{ enable_nova }}" mode: "http" external: true port: "{{ nova_api_port }}" listen_port: "{{ nova_api_listen_port }}" + tls_backend: "{{ nova_enable_tls_backend }}" nova_metadata: enabled: "{{ enable_nova }}" mode: "http" external: false port: "{{ nova_metadata_port }}" listen_port: "{{ nova_metadata_listen_port }}" + tls_backend: "{{ nova_enable_tls_backend }}" nova_metadata_external: enabled: "{{ enable_nova }}" mode: "http" external: true port: "{{ nova_metadata_port }}" listen_port: "{{ nova_metadata_listen_port }}" + tls_backend: "{{ nova_enable_tls_backend }}" nova-scheduler: container_name: "nova_scheduler" group: "nova-scheduler" @@ -190,3 +194,8 @@ nova_git_repository: "{{ kolla_dev_repos_git }}/{{ project_name }}" nova_dev_repos_pull: "{{ kolla_dev_repos_pull }}" nova_dev_mode: "{{ kolla_dev_mode }}" nova_source_version: "{{ kolla_source_version }}" + +#################### +# TLS +#################### +nova_enable_tls_backend: "{{ kolla_enable_tls_backend }}" diff --git a/ansible/roles/nova/tasks/config.yml b/ansible/roles/nova/tasks/config.yml index d077643d96..bfd41be697 100644 --- a/ansible/roles/nova/tasks/config.yml +++ b/ansible/roles/nova/tasks/config.yml @@ -33,7 +33,7 @@ - include_tasks: copy-certs.yml when: - - kolla_copy_ca_into_containers | bool + - kolla_copy_ca_into_containers | bool or nova_enable_tls_backend | bool - name: Copying over config.json files for services become: true @@ -83,5 +83,17 @@ notify: - "Restart {{ item.key }} container" +- name: Copying over nova-api-wsgi.conf + template: + src: "nova-api-wsgi.conf.j2" + dest: "{{ node_config_directory }}/nova-api/nova-api-wsgi.conf" + mode: "0660" + become: true + when: + - inventory_hostname in groups["nova-api"] + - nova_services["nova-api"].enabled | bool + notify: + - "Restart nova-api container" + - import_tasks: check-containers.yml when: kolla_action != "config" diff --git a/ansible/roles/nova/templates/nova-api-wsgi.conf.j2 b/ansible/roles/nova/templates/nova-api-wsgi.conf.j2 new file mode 100644 index 0000000000..e5bf1f0c41 --- /dev/null +++ b/ansible/roles/nova/templates/nova-api-wsgi.conf.j2 @@ -0,0 +1,70 @@ +{% set nova_log_dir = '/var/log/kolla/nova' %} +{% set wsgi_directory = '/usr/bin' if nova_install_type == 'binary' else '/var/lib/kolla/venv/bin' %} +{% if nova_enable_tls_backend | bool %} +{% if kolla_base_distro in ['centos'] %} +LoadModule ssl_module /usr/lib64/httpd/modules/mod_ssl.so +{% else %} +LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so +{% endif %} +{% endif %} +Listen {{ api_interface_address | put_address_in_context('url') }}:{{ nova_api_listen_port }} +Listen {{ api_interface_address | put_address_in_context('url') }}:{{ nova_metadata_listen_port }} + +ServerSignature Off +ServerTokens Prod +TraceEnable off +KeepAliveTimeout {{ kolla_httpd_keep_alive }} + + + + Options None + Require all granted + + + +ErrorLog "{{ nova_log_dir }}/apache-error.log" + +CustomLog "{{ nova_log_dir }}/apache-access.log" common + + +{% if nova_logging_debug | bool %} +LogLevel info +{% endif %} + + + WSGIDaemonProcess nova-api processes={{ openstack_service_workers }} threads=1 user=nova group=nova display-name=%{GROUP} + WSGIProcessGroup nova-api + WSGIScriptAlias / {{ wsgi_directory }}/nova-api-wsgi + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + ErrorLog "{{ nova_log_dir }}/nova-api-error.log" + LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" logformat + CustomLog "{{ nova_log_dir }}/nova-api-access.log" logformat +{% if nova_enable_tls_backend | bool %} + SSLEngine on + SSLCertificateFile /etc/nova/certs/nova-cert.pem + SSLCertificateKeyFile /etc/nova/certs/nova-key.pem +{% endif %} + + + + WSGIDaemonProcess nova-metadata processes={{ openstack_service_workers }} threads=1 user=nova group=nova display-name=%{GROUP} + WSGIProcessGroup nova-metadata + WSGIScriptAlias / {{ wsgi_directory }}/nova-metadata-wsgi + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + ErrorLog "{{ nova_log_dir }}/nova-metadata-error.log" + LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" logformat + CustomLog "{{ nova_log_dir }}/nova-metadata-access.log" logformat +{% if nova_enable_tls_backend | bool %} + SSLEngine on + SSLCertificateFile /etc/nova/certs/nova-cert.pem + SSLCertificateKeyFile /etc/nova/certs/nova-key.pem +{% endif %} + diff --git a/ansible/roles/nova/templates/nova-api.json.j2 b/ansible/roles/nova/templates/nova-api.json.j2 index f52b27ecc0..ea392fcbd9 100644 --- a/ansible/roles/nova/templates/nova-api.json.j2 +++ b/ansible/roles/nova/templates/nova-api.json.j2 @@ -1,17 +1,37 @@ +{% set apache_binary = 'apache2' if kolla_base_distro in ['ubuntu', 'debian'] else 'httpd' %} +{% set apache_conf_dir = 'apache2/conf-enabled' if kolla_base_distro in ['ubuntu', 'debian'] else 'httpd/conf.d' %} { - "command": "nova-api", + "command": "/usr/sbin/{{ apache_binary }} -DFOREGROUND", "config_files": [ { "source": "{{ container_config_directory }}/nova.conf", "dest": "/etc/nova/nova.conf", "owner": "nova", "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/nova-api-wsgi.conf", + "dest": "/etc/{{ apache_conf_dir }}/nova-api-wsgi.conf", + "owner": "nova", + "perm": "0600" }{% if nova_policy_file is defined %}, { "source": "{{ container_config_directory }}/{{ nova_policy_file }}", "dest": "/etc/nova/{{ nova_policy_file }}", "owner": "nova", "perm": "0600" + }{% endif %}{% if nova_enable_tls_backend | bool %}, + { + "source": "{{ container_config_directory }}/nova-cert.pem", + "dest": "/etc/nova/certs/nova-cert.pem", + "owner": "nova", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/nova-key.pem", + "dest": "/etc/nova/certs/nova-key.pem", + "owner": "nova", + "perm": "0600" }{% endif %} ], "permissions": [ diff --git a/ansible/roles/nova/templates/nova.conf.j2 b/ansible/roles/nova/templates/nova.conf.j2 index 16ef6db36e..d37200a559 100644 --- a/ansible/roles/nova/templates/nova.conf.j2 +++ b/ansible/roles/nova/templates/nova.conf.j2 @@ -8,15 +8,6 @@ log_file = /var/log/kolla/nova/nova-super-conductor.log {% endif %} state_path = /var/lib/nova - -osapi_compute_listen = {{ api_interface_address }} -osapi_compute_listen_port = {{ nova_api_listen_port }} -osapi_compute_workers = {{ openstack_service_workers }} -metadata_workers = {{ openstack_service_workers }} - -metadata_listen = {{ api_interface_address }} -metadata_listen_port = {{ nova_metadata_listen_port }} - allow_resize_to_same_host = true # Though my_ip is not used directly, lots of other variables use $my_ip