Add support for encrypting Ironic API

This patch introduces an optional backend encryption for the Ironic API
and Ironic Inspector 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 Ironic service.

Change-Id: I3e82c8ec112e53f907e89fea0c8c849072dcf957
Partially-Implements: blueprint add-ssl-internal-network
Depends-On: https://review.opendev.org/#/c/742776/
This commit is contained in:
James Kirsch 2020-08-17 14:28:39 -07:00
parent 3c02c966cb
commit 316b0496b3
8 changed files with 177 additions and 10 deletions

View File

@ -16,12 +16,14 @@ ironic_services:
external: false
port: "{{ ironic_api_port }}"
listen_port: "{{ ironic_api_listen_port }}"
tls_backend: "{{ ironic_enable_tls_backend }}"
ironic_api_external:
enabled: "{{ enable_ironic }}"
mode: "http"
external: true
port: "{{ ironic_api_port }}"
listen_port: "{{ ironic_api_listen_port }}"
tls_backend: "{{ ironic_enable_tls_backend }}"
ironic-conductor:
container_name: ironic_conductor
group: ironic-conductor
@ -45,12 +47,14 @@ ironic_services:
external: false
port: "{{ ironic_inspector_port }}"
listen_port: "{{ ironic_inspector_listen_port }}"
tls_backend: "{{ ironic_enable_tls_backend }}"
ironic_inspector_external:
enabled: "{{ enable_ironic }}"
mode: "http"
external: true
port: "{{ ironic_inspector_port }}"
listen_port: "{{ ironic_inspector_listen_port }}"
tls_backend: "{{ ironic_enable_tls_backend }}"
ironic-pxe:
container_name: ironic_pxe
group: ironic-pxe
@ -253,3 +257,8 @@ ironic_ks_users:
user: "{{ ironic_inspector_keystone_user }}"
password: "{{ ironic_inspector_keystone_password }}"
role: "admin"
####################
# TLS
####################
ironic_enable_tls_backend: "{{ kolla_enable_tls_backend }}"

View File

@ -40,6 +40,7 @@
module_name: uri
module_args:
url: "{{ ironic_internal_endpoint }}"
validate_certs: false
register: result
until: result is success
retries: 12

View File

@ -33,7 +33,7 @@
- include_tasks: copy-certs.yml
when:
- kolla_copy_ca_into_containers | bool
- kolla_copy_ca_into_containers | bool or ironic_enable_tls_backend | bool
- name: Copying over config.json files for services
template:
@ -244,5 +244,29 @@
notify:
- "Restart {{ item.key }} container"
- name: Copying over ironic-api-wsgi.conf
template:
src: "ironic-api-wsgi.conf.j2"
dest: "{{ node_config_directory }}/ironic-api/ironic-api-wsgi.conf"
mode: "0660"
become: true
when:
- inventory_hostname in groups["ironic-api"]
- ironic_services["ironic-api"].enabled | bool
notify:
- "Restart ironic-api container"
- name: Copying over ironic-inspector-wsgi.conf
template:
src: "ironic-inspector-wsgi.conf.j2"
dest: "{{ node_config_directory }}/ironic-inspector/ironic-inspector-wsgi.conf"
mode: "0660"
become: true
when:
- inventory_hostname in groups["ironic-inspector"]
- ironic_services["ironic-inspector"].enabled | bool
notify:
- "Restart ironic-inspector container"
- import_tasks: check-containers.yml
when: kolla_action != "config"

View File

@ -0,0 +1,50 @@
{% set ironic_log_dir = '/var/log/kolla/ironic' %}
{% set wsgi_directory = '/usr/bin' if ironic_install_type == 'binary' else '/var/lib/kolla/venv/bin' %}
{% if ironic_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') }}:{{ ironic_api_listen_port }}
ServerSignature Off
ServerTokens Prod
TraceEnable off
KeepAliveTimeout {{ kolla_httpd_keep_alive }}
<Directory "{{ wsgi_directory }}">
<FilesMatch "^ironic-api-wsgi$">
Options None
Require all granted
</FilesMatch>
</Directory>
ErrorLog "{{ ironic_log_dir }}/apache-error.log"
<IfModule log_config_module>
CustomLog "{{ ironic_log_dir }}/apache-access.log" common
</IfModule>
{% if ironic_logging_debug | bool %}
LogLevel info
{% endif %}
<VirtualHost *:{{ ironic_api_listen_port }}>
WSGIDaemonProcess ironic-api processes={{ openstack_service_workers }} threads=1 user=ironic group=ironic display-name=%{GROUP}
WSGIProcessGroup ironic-api
WSGIScriptAlias / {{ wsgi_directory }}/ironic-api-wsgi
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
<IfVersion >= 2.4>
ErrorLogFormat "%{cu}t %M"
</IfVersion>
ErrorLog "{{ ironic_log_dir }}/ironic-api-error.log"
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" logformat
CustomLog "{{ ironic_log_dir }}/ironic-api-access.log" logformat
{% if ironic_enable_tls_backend | bool %}
SSLEngine on
SSLCertificateFile /etc/ironic/certs/ironic-cert.pem
SSLCertificateKeyFile /etc/ironic/certs/ironic-key.pem
{% endif %}
</VirtualHost>

View File

@ -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": "ironic-api",
"command": "/usr/sbin/{{ apache_binary }} -DFOREGROUND",
"config_files": [
{
"source": "{{ container_config_directory }}/ironic.conf",
"dest": "/etc/ironic/ironic.conf",
"owner": "ironic",
"perm": "0600"
},
{
"source": "{{ container_config_directory }}/ironic-api-wsgi.conf",
"dest": "/etc/{{ apache_conf_dir }}/ironic-api-wsgi.conf",
"owner": "ironic",
"perm": "0600"
}{% if ironic_policy_file is defined %},
{
"source": "{{ container_config_directory }}/{{ ironic_policy_file }}",
"dest": "/etc/ironic/{{ ironic_policy_file }}",
"owner": "ironic",
"perm": "0600"
}{% endif %}{% if ironic_enable_tls_backend | bool %},
{
"source": "{{ container_config_directory }}/ironic-cert.pem",
"dest": "/etc/ironic/certs/ironic-cert.pem",
"owner": "ironic",
"perm": "0600"
},
{
"source": "{{ container_config_directory }}/ironic-key.pem",
"dest": "/etc/ironic/certs/ironic-key.pem",
"owner": "ironic",
"perm": "0600"
}{% endif %}
],
"permissions": [

View File

@ -0,0 +1,50 @@
{% set ironic_log_dir = '/var/log/kolla/ironic' %}
{% set wsgi_directory = '/usr/bin' if ironic_install_type == 'binary' else '/var/lib/kolla/venv/bin' %}
{% if ironic_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') }}:{{ ironic_inspector_listen_port }}
ServerSignature Off
ServerTokens Prod
TraceEnable off
KeepAliveTimeout {{ kolla_httpd_keep_alive }}
<Directory "{{ wsgi_directory }}">
<FilesMatch "^ironic-inspector-wsgi$">
Options None
Require all granted
</FilesMatch>
</Directory>
ErrorLog "{{ ironic_log_dir }}/apache-error-ironic-inspector.log"
<IfModule log_config_module>
CustomLog "{{ ironic_log_dir }}/apache-access-ironic-inspector.log" common
</IfModule>
{% if ironic_logging_debug | bool %}
LogLevel info
{% endif %}
<VirtualHost *:{{ ironic_inspector_listen_port }}>
WSGIDaemonProcess ironic-inspector processes={{ openstack_service_workers }} threads=1 user=ironic group=ironic display-name=%{GROUP}
WSGIProcessGroup ironic-inspector
WSGIScriptAlias / {{ wsgi_directory }}/ironic-inspector-wsgi
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
<IfVersion >= 2.4>
ErrorLogFormat "%{cu}t %M"
</IfVersion>
ErrorLog "{{ ironic_log_dir }}/ironic-inspector-error.log"
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" logformat
CustomLog "{{ ironic_log_dir }}/ironic-inspector-access.log" logformat
{% if ironic_enable_tls_backend | bool %}
SSLEngine on
SSLCertificateFile /etc/ironic/certs/ironic-cert.pem
SSLCertificateKeyFile /etc/ironic/certs/ironic-key.pem
{% endif %}
</VirtualHost>

View File

@ -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": "ironic-inspector --config-file /etc/ironic-inspector/inspector.conf",
"command": "/usr/sbin/{{ apache_binary }} -DFOREGROUND",
"config_files": [
{
"source": "{{ container_config_directory }}/inspector.conf",
"dest": "/etc/ironic-inspector/inspector.conf",
"owner": "ironic-inspector",
"perm": "0600"
},
{
"source": "{{ container_config_directory }}/ironic-inspector-wsgi.conf",
"dest": "/etc/{{ apache_conf_dir }}/ironic-inspector-wsgi.conf",
"owner": "ironic",
"perm": "0600"
}{% if ironic_policy_file is defined %},
{
"source": "{{ container_config_directory }}/{{ ironic_policy_file }}",
"dest": "/etc/ironic/{{ ironic_policy_file }}",
"owner": "ironic",
"perm": "0600"
}{% endif %}{% if ironic_enable_tls_backend | bool %},
{
"source": "{{ container_config_directory }}/ironic-cert.pem",
"dest": "/etc/ironic/certs/ironic-cert.pem",
"owner": "ironic",
"perm": "0600"
},
{
"source": "{{ container_config_directory }}/ironic-key.pem",
"dest": "/etc/ironic/certs/ironic-key.pem",
"owner": "ironic",
"perm": "0600"
}{% endif %}
]
}

View File

@ -35,13 +35,6 @@ driver = noop
policy_file = {{ ironic_policy_file }}
{% endif %}
{% if service_name == 'ironic-api' %}
[api]
host_ip = {{ api_interface_address }}
port = {{ ironic_api_listen_port }}
api_workers = {{ openstack_service_workers }}
{% endif %}
{% if service_name == 'ironic-conductor' %}
[conductor]
automated_clean=false