diff --git a/ansible/certificates.yml b/ansible/certificates.yml index 4b6d2528d96eb96769d8b7542d183c2a0d4be263..28a1a5f8ee1cd400e3ea63c16be394781751efa3 100644 --- a/ansible/certificates.yml +++ b/ansible/certificates.yml @@ -1,6 +1,8 @@ --- - import_playbook: gather-facts.yml - when: kolla_enable_tls_backend | default(false) | bool + when: >- + kolla_enable_tls_backend | default(false) | bool or + rabbitmq_enable_tls | default(false) | bool - name: Apply role certificates hosts: localhost diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index aa4938b08045d43528fa468a8c3477c86e327766..fe30d155eab3add98c642d5478db7d02256e40be 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -192,6 +192,11 @@ om_notify_vhost: "/" notify_transport_url: "{{ om_notify_transport }}://{% for host in groups[om_notify_group] %}{{ om_notify_user }}:{{ om_notify_password }}@{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ om_notify_port }}{% if not loop.last %},{% endif %}{% endfor %}/{{ om_notify_vhost }}" +# Whether to enable TLS for oslo.messaging communication with RabbitMQ. +om_enable_rabbitmq_tls: "{{ rabbitmq_enable_tls | bool }}" +# CA certificate bundle in containers using oslo.messaging with RabbitMQ TLS. +om_rabbitmq_cacert: "{{ rabbitmq_cacert }}" + #################### # Networking options #################### @@ -426,7 +431,7 @@ qdrouterd_port: "31459" qinling_api_port: "7070" -rabbitmq_port: "5672" +rabbitmq_port: "{{ '5671' if rabbitmq_enable_tls | bool else '5672' }}" rabbitmq_management_port: "15672" rabbitmq_cluster_port: "25672" rabbitmq_epmd_port: "4369" @@ -748,6 +753,10 @@ osprofiler_backend_connection_string: "{{ redis_connection_string if osprofiler_ rabbitmq_user: "openstack" rabbitmq_monitoring_user: "" outward_rabbitmq_user: "openstack" +# Whether to enable TLS encryption for RabbitMQ client-server communication. +rabbitmq_enable_tls: "no" +# CA certificate bundle in RabbitMQ container. +rabbitmq_cacert: "/etc/ssl/certs/{{ 'ca-certificates.crt' if kolla_base_distro in ['debian', 'ubuntu'] else 'ca-bundle.trust.crt' }}" #################### # Qdrouterd options diff --git a/ansible/roles/aodh/templates/aodh.conf.j2 b/ansible/roles/aodh/templates/aodh.conf.j2 index 6745323ca695fbb5d75a6ed328409b4180abd71c..b9c3b08475d1a3b19b1401c277f5137681101e1f 100644 --- a/ansible/roles/aodh/templates/aodh.conf.j2 +++ b/ansible/roles/aodh/templates/aodh.conf.j2 @@ -58,3 +58,8 @@ topics = {{ aodh_enabled_notification_topics | map(attribute='name') | join(',') driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} diff --git a/ansible/roles/barbican/templates/barbican.conf.j2 b/ansible/roles/barbican/templates/barbican.conf.j2 index d7b698579f6ee6bcd2db26fd1750daeafed69b65..1c858fa6ddac9e2e00916c5af2704f770747928e 100644 --- a/ansible/roles/barbican/templates/barbican.conf.j2 +++ b/ansible/roles/barbican/templates/barbican.conf.j2 @@ -75,6 +75,12 @@ topics = {{ barbican_enabled_notification_topics | map(attribute='name') | join( driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [oslo_middleware] enable_proxy_headers_parsing = True diff --git a/ansible/roles/blazar/templates/blazar.conf.j2 b/ansible/roles/blazar/templates/blazar.conf.j2 index 734b9c326d5054baecfaf4b22f00c3c0f4c4ec34..2fdc6adfa6a5254f64ac5541576f0ad1fce203f2 100644 --- a/ansible/roles/blazar/templates/blazar.conf.j2 +++ b/ansible/roles/blazar/templates/blazar.conf.j2 @@ -60,6 +60,11 @@ topics = {{ blazar_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} {% if blazar_policy_file is defined %} [oslo_policy] diff --git a/ansible/roles/ceilometer/templates/ceilometer.conf.j2 b/ansible/roles/ceilometer/templates/ceilometer.conf.j2 index 1f15481fa8ba8b4c4a3d42253b4c09a25997bc15..e87fdb494a07c99ba0dd3426f751b1fcb0e0f945 100644 --- a/ansible/roles/ceilometer/templates/ceilometer.conf.j2 +++ b/ansible/roles/ceilometer/templates/ceilometer.conf.j2 @@ -35,6 +35,12 @@ ca_file = /etc/ceilometer/vmware_ca [oslo_messaging_notifications] transport_url = {{ notify_transport_url }} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if ceilometer_policy_file is defined %} [oslo_policy] policy_file = {{ ceilometer_policy_file }} diff --git a/ansible/roles/certificates/tasks/generate-backend.yml b/ansible/roles/certificates/tasks/generate-backend.yml index 8eab9e48b3c8abca51323e95de8dc9a9b30e5678..341f5dcdb73c6d90fbbbd3e602553bf0ac668876 100644 --- a/ansible/roles/certificates/tasks/generate-backend.yml +++ b/ansible/roles/certificates/tasks/generate-backend.yml @@ -62,3 +62,16 @@ src: "{{ backend_dir }}/backend.key" dest: "{{ kolla_certificates_dir }}/backend-key.pem" mode: "0660" + +- name: Copy backend TLS certificate and key for RabbitMQ + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + remote_src: true + with_items: + - src: "{{ kolla_tls_backend_cert }}" + dest: "{{ kolla_certificates_dir }}/rabbitmq-cert.pem" + - src: "{{ kolla_tls_backend_key }}" + dest: "{{ kolla_certificates_dir }}/rabbitmq-key.pem" + when: + - rabbitmq_enable_tls | bool diff --git a/ansible/roles/certificates/tasks/main.yml b/ansible/roles/certificates/tasks/main.yml index 21b253bebb619cd91e0278ff59e431593c54680b..f8d80dd9b98845c76c4b82cfd37a798a3be332b8 100644 --- a/ansible/roles/certificates/tasks/main.yml +++ b/ansible/roles/certificates/tasks/main.yml @@ -3,4 +3,4 @@ - include_tasks: generate.yml - include_tasks: generate-backend.yml when: - - kolla_enable_tls_backend | bool + - kolla_enable_tls_backend | bool or rabbitmq_enable_tls | bool diff --git a/ansible/roles/cinder/templates/cinder.conf.j2 b/ansible/roles/cinder/templates/cinder.conf.j2 index 2ab967de6f34842723081e674b6c8b41527bd420..c80ae265de8bc4fdb65fa4f319c7da376297b20c 100644 --- a/ansible/roles/cinder/templates/cinder.conf.j2 +++ b/ansible/roles/cinder/templates/cinder.conf.j2 @@ -69,6 +69,12 @@ topics = {{ cinder_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [oslo_middleware] enable_proxy_headers_parsing = True diff --git a/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2 b/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2 index cc1ebaf5aa531165275deecae47ffe7d26b937bb..16293a79a671b567d235ba610431cf598df91504 100644 --- a/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2 +++ b/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2 @@ -43,6 +43,12 @@ lock_path = /var/lib/cloudkitty/tmp policy_file = {{ cloudkitty_policy_file }} {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [collect] collector = {{ cloudkitty_collector_backend }} {% if cloudkitty_custom_metrics_used %} diff --git a/ansible/roles/cyborg/templates/cyborg.conf.j2 b/ansible/roles/cyborg/templates/cyborg.conf.j2 index 61a5673b1df99a87bde99d0c03f89c284f53b556..89a3191090c6296a2b4796e0688cd43277246233 100644 --- a/ansible/roles/cyborg/templates/cyborg.conf.j2 +++ b/ansible/roles/cyborg/templates/cyborg.conf.j2 @@ -54,3 +54,9 @@ topics = {{ cyborg_enabled_notification_topics | map(attribute='name') | join(', {% else %} driver = noop {% endif %} + +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} diff --git a/ansible/roles/designate/templates/designate.conf.j2 b/ansible/roles/designate/templates/designate.conf.j2 index 2d1701aa56412a3b88bd887e479ae90529f99c3c..67101ef742823f7fd4391669f77e0500d47e2553 100644 --- a/ansible/roles/designate/templates/designate.conf.j2 +++ b/ansible/roles/designate/templates/designate.conf.j2 @@ -89,6 +89,12 @@ topics = {{ designate_enabled_notification_topics | map(attribute='name') | join driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [oslo_concurrency] lock_path = /var/lib/designate/tmp diff --git a/ansible/roles/glance/templates/glance-api.conf.j2 b/ansible/roles/glance/templates/glance-api.conf.j2 index 5ad3a5c00cf26324550315449ab523d17c63c7b4..d784df3ca8861be816161343cec976bf9f25e10e 100644 --- a/ansible/roles/glance/templates/glance-api.conf.j2 +++ b/ansible/roles/glance/templates/glance-api.conf.j2 @@ -120,6 +120,12 @@ topics = {{ glance_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if glance_policy_file is defined %} [oslo_policy] policy_file = {{ glance_policy_file }} diff --git a/ansible/roles/heat/templates/heat.conf.j2 b/ansible/roles/heat/templates/heat.conf.j2 index c7245e0a26c80fe9fbc33e37e138b59f9c422385..08f32be9abe4a491837991b68861fe47983f800e 100644 --- a/ansible/roles/heat/templates/heat.conf.j2 +++ b/ansible/roles/heat/templates/heat.conf.j2 @@ -84,6 +84,12 @@ topics = {{ heat_enabled_notification_topics | map(attribute='name') | join(',') driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if heat_policy_file is defined %} [oslo_policy] policy_file = {{ heat_policy_file }} diff --git a/ansible/roles/ironic/templates/ironic-inspector.conf.j2 b/ansible/roles/ironic/templates/ironic-inspector.conf.j2 index 3a3d4a8933898754e5f140deff64d17face946e9..ac7f62211e5975da31cd521321c9a9a4a2d81ab6 100644 --- a/ansible/roles/ironic/templates/ironic-inspector.conf.j2 +++ b/ansible/roles/ironic/templates/ironic-inspector.conf.j2 @@ -12,6 +12,12 @@ transport_url = {{ rpc_transport_url }} [oslo_messaging_notifications] transport_url = {{ notify_transport_url }} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [ironic] {% if enable_keystone | bool %} auth_url = {{ keystone_admin_url }} diff --git a/ansible/roles/ironic/templates/ironic.conf.j2 b/ansible/roles/ironic/templates/ironic.conf.j2 index 79d387cf8a5e480b7ce7721feb3c226705693e9e..7854d0eccc5e06448b0c5ee0f4cd26e2dafb3d73 100644 --- a/ansible/roles/ironic/templates/ironic.conf.j2 +++ b/ansible/roles/ironic/templates/ironic.conf.j2 @@ -30,6 +30,12 @@ topics = {{ ironic_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if ironic_policy_file is defined %} [oslo_policy] policy_file = {{ ironic_policy_file }} diff --git a/ansible/roles/karbor/templates/karbor.conf.j2 b/ansible/roles/karbor/templates/karbor.conf.j2 index d31985b12c7815302c882af38528a6da38444bc8..936f204f27673f2bb231be6c9bd9c8060baea811 100644 --- a/ansible/roles/karbor/templates/karbor.conf.j2 +++ b/ansible/roles/karbor/templates/karbor.conf.j2 @@ -57,5 +57,11 @@ topics = {{ karbor_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [oslo_middleware] enable_proxy_headers_parsing = True diff --git a/ansible/roles/keystone/templates/keystone.conf.j2 b/ansible/roles/keystone/templates/keystone.conf.j2 index 06d57eb3b2f6312f84c0224758fe7d55ea7c56ba..730107eaca1bfa8ea7b1df6047abea161fe61369 100644 --- a/ansible/roles/keystone/templates/keystone.conf.j2 +++ b/ansible/roles/keystone/templates/keystone.conf.j2 @@ -59,6 +59,11 @@ topics = {{ keystone_enabled_notification_topics | map(attribute='name') | join( driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} {% if enable_osprofiler | bool %} [profiler] diff --git a/ansible/roles/magnum/templates/magnum.conf.j2 b/ansible/roles/magnum/templates/magnum.conf.j2 index c0cb531aa9c86cea563295e027ca1af79a1629f8..f1d9742562f68121cc865f94c1673aed458cefcf 100644 --- a/ansible/roles/magnum/templates/magnum.conf.j2 +++ b/ansible/roles/magnum/templates/magnum.conf.j2 @@ -112,6 +112,12 @@ topics = {{ magnum_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if magnum_policy_file is defined %} [oslo_policy] policy_file = {{ magnum_policy_file }} diff --git a/ansible/roles/manila/templates/manila.conf.j2 b/ansible/roles/manila/templates/manila.conf.j2 index 171033f732accc77accbf3b008543aa2c4903460..9bf62cadf7ee42865e9867b56cb7dd66919bac84 100644 --- a/ansible/roles/manila/templates/manila.conf.j2 +++ b/ansible/roles/manila/templates/manila.conf.j2 @@ -54,6 +54,11 @@ topics = {{ manila_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} [oslo_middleware] enable_proxy_headers_parsing = True diff --git a/ansible/roles/masakari/templates/masakari.conf.j2 b/ansible/roles/masakari/templates/masakari.conf.j2 index 5a0bab0fc945759ac9444af7bd0d8fdae13763d0..da0ef60ad4c9bab06c917e4eab2d7e3dd8554ab3 100644 --- a/ansible/roles/masakari/templates/masakari.conf.j2 +++ b/ansible/roles/masakari/templates/masakari.conf.j2 @@ -48,6 +48,12 @@ topics = notifications driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [oslo_middleware] enable_proxy_headers_parsing = True diff --git a/ansible/roles/mistral/templates/mistral.conf.j2 b/ansible/roles/mistral/templates/mistral.conf.j2 index de3540ad5c393bd57d4631a0303013781353a63e..c784c1105eee290d2d58f5ccac2d940dc9a7cf72 100644 --- a/ansible/roles/mistral/templates/mistral.conf.j2 +++ b/ansible/roles/mistral/templates/mistral.conf.j2 @@ -70,6 +70,12 @@ topics = {{ mistral_enabled_notification_topics | map(attribute='name') | join(' driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if mistral_policy_file is defined %} [oslo_policy] policy_file = {{ mistral_policy_file }} diff --git a/ansible/roles/murano/templates/murano.conf.j2 b/ansible/roles/murano/templates/murano.conf.j2 index ce67b458f7e043806622fa03a603261d6fd8416a..5b9194a7743138108edabb1cd380bb14bc823768 100644 --- a/ansible/roles/murano/templates/murano.conf.j2 +++ b/ansible/roles/murano/templates/murano.conf.j2 @@ -59,6 +59,12 @@ topics = {{ murano_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [oslo_middleware] enable_proxy_headers_parsing = True diff --git a/ansible/roles/neutron/templates/neutron.conf.j2 b/ansible/roles/neutron/templates/neutron.conf.j2 index 4b8510dea5a77feba7f29f5bc199b870ef5c7021..ee7ed148c8b0a5e7f3facc29bac64d71fd84c2ee 100644 --- a/ansible/roles/neutron/templates/neutron.conf.j2 +++ b/ansible/roles/neutron/templates/neutron.conf.j2 @@ -129,6 +129,12 @@ topics = {{ neutron_enabled_notification_topics | map(attribute='name') | join(' driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if neutron_policy_file is defined %} [oslo_policy] policy_file = {{ neutron_policy_file }} diff --git a/ansible/roles/nova-cell/templates/nova.conf.j2 b/ansible/roles/nova-cell/templates/nova.conf.j2 index d54ab23be5563a9b59e01700032684df1b5de20d..81852d5e700b1ea40bafedc204e8540bdc4f8be5 100644 --- a/ansible/roles/nova-cell/templates/nova.conf.j2 +++ b/ansible/roles/nova-cell/templates/nova.conf.j2 @@ -183,6 +183,12 @@ topics = {{ nova_enabled_notification_topics | map(attribute='name') | join(',') driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if service_name in nova_cell_services_require_policy_json and nova_policy_file is defined %} [oslo_policy] policy_file = {{ nova_policy_file }} diff --git a/ansible/roles/nova/templates/nova.conf.j2 b/ansible/roles/nova/templates/nova.conf.j2 index 5a7f88dbbda2cc10ae9c90516cf21f6ae997181a..2795c1475945d217c3d61dc6f4d0c0cdc4e3f2d5 100644 --- a/ansible/roles/nova/templates/nova.conf.j2 +++ b/ansible/roles/nova/templates/nova.conf.j2 @@ -132,6 +132,12 @@ topics = {{ nova_enabled_notification_topics | map(attribute='name') | join(',') driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if service_name in nova_services_require_policy_json and nova_policy_file is defined %} [oslo_policy] policy_file = {{ nova_policy_file }} diff --git a/ansible/roles/octavia/templates/octavia.conf.j2 b/ansible/roles/octavia/templates/octavia.conf.j2 index 33289a9a91763b9d3f193ab0819b51e5e8c18ab9..3d42d7aa77f8268ad6da497d9c0bbcf9c4655f65 100644 --- a/ansible/roles/octavia/templates/octavia.conf.j2 +++ b/ansible/roles/octavia/templates/octavia.conf.j2 @@ -88,6 +88,12 @@ rpc_thread_pool_size = 2 [oslo_messaging_notifications] transport_url = {{ notify_transport_url }} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if octavia_policy_file is defined %} [oslo_policy] policy_file = {{ octavia_policy_file }} diff --git a/ansible/roles/qinling/templates/qinling.conf.j2 b/ansible/roles/qinling/templates/qinling.conf.j2 index 030edd9354574377630206695fe2b2d2fd07542f..ee9f8702c96ff36d9608649f279dd1288b6430d7 100644 --- a/ansible/roles/qinling/templates/qinling.conf.j2 +++ b/ansible/roles/qinling/templates/qinling.conf.j2 @@ -55,6 +55,12 @@ topics = notifications driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if qinling_policy_file is defined %} [oslo_policy] policy_file = {{ qinling_policy_file }} diff --git a/ansible/roles/rabbitmq/defaults/main.yml b/ansible/roles/rabbitmq/defaults/main.yml index 8c3553a040c5f5969be48b35482d296f283546aa..1d93ca5491440b0e87901586cb382b405e650c14 100644 --- a/ansible/roles/rabbitmq/defaults/main.yml +++ b/ansible/roles/rabbitmq/defaults/main.yml @@ -72,3 +72,5 @@ rabbitmq_cluster_name: "openstack" rabbitmq_hostname: "{{ ansible_hostname }}" rabbitmq_pid_file: "/var/lib/rabbitmq/mnesia/rabbitmq.pid" rabbitmq_server_additional_erl_args: "" +# Dict of TLS options for RabbitMQ. Keys will be prefixed with 'ssl_options.'. +rabbitmq_tls_options: {} diff --git a/ansible/roles/rabbitmq/handlers/main.yml b/ansible/roles/rabbitmq/handlers/main.yml index 515126e0bf5be3583fbf766878237a2efdef12c8..d3cb4d717df9b0ef1e05d5347dba8ab8cebaade4 100644 --- a/ansible/roles/rabbitmq/handlers/main.yml +++ b/ansible/roles/rabbitmq/handlers/main.yml @@ -17,6 +17,7 @@ - inventory_hostname == groups[service.group]|first notify: - Waiting for rabbitmq to start on first node + listen: Restart rabbitmq container - name: Waiting for rabbitmq to start on first node vars: @@ -43,3 +44,4 @@ when: - kolla_action != "config" - inventory_hostname != groups[service.group]|first + listen: Restart rabbitmq container diff --git a/ansible/roles/rabbitmq/tasks/check-containers.yml b/ansible/roles/rabbitmq/tasks/check-containers.yml index 7cb590b5b96be086399bc00bc6bdf062e0ccfbf3..0ff847b49f700a3d0f9b42b26d9be2c82a5c0789 100644 --- a/ansible/roles/rabbitmq/tasks/check-containers.yml +++ b/ansible/roles/rabbitmq/tasks/check-containers.yml @@ -14,5 +14,4 @@ - item.value.enabled | bool with_dict: "{{ rabbitmq_services }}" notify: - - Restart rabbitmq container (first node) - - Restart rabbitmq container (rest of nodes) + - Restart rabbitmq container diff --git a/ansible/roles/rabbitmq/tasks/config.yml b/ansible/roles/rabbitmq/tasks/config.yml index 25a977b6c51f9532cefc4f67cc5876230c0401c8..9e9f4f221303e2e58be030b98fc5bff9c5c5f7d6 100644 --- a/ansible/roles/rabbitmq/tasks/config.yml +++ b/ansible/roles/rabbitmq/tasks/config.yml @@ -23,8 +23,7 @@ - item.value.enabled | bool with_dict: "{{ rabbitmq_services }}" notify: - - Restart rabbitmq container (first node) - - Restart rabbitmq container (rest of nodes) + - Restart rabbitmq container - name: Copying over rabbitmq-env.conf become: true @@ -42,9 +41,7 @@ - inventory_hostname in groups[service.group] - service.enabled | bool notify: - - Restart rabbitmq container (first node) - - Restart rabbitmq container (rest of nodes) - + - Restart rabbitmq container - name: Copying over rabbitmq.conf become: true @@ -62,8 +59,7 @@ - inventory_hostname in groups[service.group] - service.enabled | bool notify: - - Restart rabbitmq container (first node) - - Restart rabbitmq container (rest of nodes) + - Restart rabbitmq container - name: Copying over erl_inetrc become: true @@ -81,8 +77,7 @@ - inventory_hostname in groups[service.group] - service.enabled | bool notify: - - Restart rabbitmq container (first node) - - Restart rabbitmq container (rest of nodes) + - Restart rabbitmq container - name: Copying over definitions.json become: true @@ -100,8 +95,10 @@ - inventory_hostname in groups[service.group] - service.enabled | bool notify: - - Restart rabbitmq container (first node) - - Restart rabbitmq container (rest of nodes) + - Restart rabbitmq container + +- include_tasks: copy-certs.yml + when: rabbitmq_enable_tls | bool - import_tasks: check-containers.yml when: kolla_action != "config" diff --git a/ansible/roles/rabbitmq/tasks/copy-certs.yml b/ansible/roles/rabbitmq/tasks/copy-certs.yml new file mode 100644 index 0000000000000000000000000000000000000000..f3c84a49ababc45877913894fbd568d0d24112e9 --- /dev/null +++ b/ansible/roles/rabbitmq/tasks/copy-certs.yml @@ -0,0 +1,52 @@ +--- +- name: Copying over extra CA certificates + become: true + vars: + service: "{{ rabbitmq_services['rabbitmq'] }}" + copy: + src: "{{ kolla_certificates_dir }}/ca/" + dest: "{{ node_config_directory }}/{{ project_name }}/ca-certificates" + mode: "0644" + when: + - kolla_copy_ca_into_containers | bool + - service | service_enabled_and_mapped_to_host + notify: + - Restart rabbitmq container + +- name: Copying over TLS certificate + become: true + vars: + service: "{{ rabbitmq_services['rabbitmq'] }}" + copy: + src: "{{ item }}" + dest: "{{ node_config_directory }}/{{ project_name }}/{{ project_name }}-cert.pem" + mode: "0644" + with_first_found: + - files: + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/{{ project_name }}-cert.pem" + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-cert.pem" + - "{{ kolla_certificates_dir }}/{{ project_name }}-cert.pem" + skip: true + when: + - service | service_enabled_and_mapped_to_host + notify: + - Restart rabbitmq container + +- name: Copying over TLS key + become: true + vars: + service: "{{ rabbitmq_services['rabbitmq'] }}" + copy: + src: "{{ item }}" + dest: "{{ node_config_directory }}/{{ project_name }}/{{ project_name }}-key.pem" + mode: "0600" + with_first_found: + - files: + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/{{ project_name }}-key.pem" + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-key.pem" + - "{{ kolla_certificates_dir }}/{{ project_name }}-key.pem" + skip: true + when: + - service | service_enabled_and_mapped_to_host + notify: + - Restart rabbitmq container diff --git a/ansible/roles/rabbitmq/tasks/precheck.yml b/ansible/roles/rabbitmq/tasks/precheck.yml index a7baf2afa422c9871ccac5293f1c3985585dbf86..3dc37bc88f5e8fc1f982d4f9937403205dbeafe2 100644 --- a/ansible/roles/rabbitmq/tasks/precheck.yml +++ b/ansible/roles/rabbitmq/tasks/precheck.yml @@ -74,6 +74,32 @@ when: - not item.1 is match('^'+('api' | kolla_address(item.0.item))+'\\b') +- name: Check if TLS certificate exists for RabbitMQ + vars: + cert: "{{ query('first_found', paths, errors='ignore') }}" + paths: + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/rabbitmq-cert.pem" + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-cert.pem" + - "{{ kolla_certificates_dir }}/rabbitmq-cert.pem" + fail: + msg: No TLS certificate provided for RabbitMQ. + when: + - rabbitmq_enable_tls | bool + - cert | length == 0 + +- name: Check if TLS key exists for RabbitMQ + vars: + key: "{{ query('first_found', paths, errors='ignore') }}" + paths: + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/rabbitmq-key.pem" + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-key.pem" + - "{{ kolla_certificates_dir }}/rabbitmq-key.pem" + fail: + msg: No TLS key provided for RabbitMQ. + when: + - rabbitmq_enable_tls | bool + - key | length == 0 + - name: Checking free port for outward RabbitMQ wait_for: host: "{{ api_interface_address }}" @@ -137,3 +163,31 @@ when: - enable_outward_rabbitmq | bool - not item.1 is match('^'+('api' | kolla_address(item.0.item))+'\\b') + +- name: Check if TLS certificate exists for outward RabbitMQ + vars: + cert: "{{ query('first_found', paths, errors='ignore') }}" + paths: + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/outward_rabbitmq-cert.pem" + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-cert.pem" + - "{{ kolla_certificates_dir }}/outward_rabbitmq-cert.pem" + fail: + msg: No TLS certificate provided for outward RabbitMQ. + when: + - enable_outward_rabbitmq | bool + - rabbitmq_enable_tls | bool + - cert | length == 0 + +- name: Check if TLS key exists for outward RabbitMQ + vars: + key: "{{ query('first_found', paths, errors='ignore') }}" + paths: + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/outward_rabbitmq-key.pem" + - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-key.pem" + - "{{ kolla_certificates_dir }}/outward_rabbitmq-key.pem" + fail: + msg: No TLS key provided for outward RabbitMQ. + when: + - enable_outward_rabbitmq | bool + - rabbitmq_enable_tls | bool + - key | length == 0 diff --git a/ansible/roles/rabbitmq/templates/rabbitmq.conf.j2 b/ansible/roles/rabbitmq/templates/rabbitmq.conf.j2 index f897499dac2ec345824f9dfe49eac988add76956..25ec6b46f354e2f117435739e65b367d4cb3a22e 100644 --- a/ansible/roles/rabbitmq/templates/rabbitmq.conf.j2 +++ b/ansible/roles/rabbitmq/templates/rabbitmq.conf.j2 @@ -1,6 +1,11 @@ # NOTE(yoctozepto): rabbitmq uses the raw format (e.g. fd::) of IPv6 address; # despite specifying port via colon, the url format (e.g. [fd::]) is not accepted +{% if rabbitmq_enable_tls | bool %} +listeners.tcp = none +listeners.ssl.1 = {{ api_interface_address }}:{{ role_rabbitmq_port }} +{% else %} listeners.tcp.1 = {{ api_interface_address }}:{{ role_rabbitmq_port }} +{% endif %} {# NOTE: to avoid split-brain #} cluster_partition_handling = pause_minority @@ -12,3 +17,12 @@ cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config {% for host in groups[role_rabbitmq_groups] %} cluster_formation.classic_config.nodes.{{ loop.index0 }} = rabbit@{{ hostvars[host]['ansible_hostname'] }} {% endfor %} + +{% if rabbitmq_enable_tls | bool %} +# https://www.rabbitmq.com/ssl.html +ssl_options.certfile = /etc/rabbitmq/certs/{{ project_name }}-cert.pem +ssl_options.keyfile = /etc/rabbitmq/certs/{{ project_name }}-key.pem +{% for key, value in rabbitmq_tls_options.items() %} +ssl_options.{{ key }} = {{ value }} +{% endfor %} +{% endif %} diff --git a/ansible/roles/rabbitmq/templates/rabbitmq.json.j2 b/ansible/roles/rabbitmq/templates/rabbitmq.json.j2 index 91e67e15b44b8903c6fbbac722880b96f3f0cee2..d93df3ad18b5402cac1d22db4dc797fa34fae30f 100644 --- a/ansible/roles/rabbitmq/templates/rabbitmq.json.j2 +++ b/ansible/roles/rabbitmq/templates/rabbitmq.json.j2 @@ -24,7 +24,19 @@ "dest": "/etc/rabbitmq/definitions.json", "owner": "rabbitmq", "perm": "0600" - } + }{% if rabbitmq_enable_tls | bool %}, + { + "source": "{{ container_config_directory }}/{{ project_name }}-cert.pem", + "dest": "/etc/rabbitmq/certs/{{ project_name }}-cert.pem", + "owner": "rabbitmq", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/{{ project_name }}-key.pem", + "dest": "/etc/rabbitmq/certs/{{ project_name }}-key.pem", + "owner": "rabbitmq", + "perm": "0600" + }{% endif %} ], "permissions": [ { diff --git a/ansible/roles/sahara/templates/sahara.conf.j2 b/ansible/roles/sahara/templates/sahara.conf.j2 index 9b4c15661fcd61307b30f09e4c5c87c24ce52524..c982e375e8ea7a4c583dda29d70b5618719cb0a7 100644 --- a/ansible/roles/sahara/templates/sahara.conf.j2 +++ b/ansible/roles/sahara/templates/sahara.conf.j2 @@ -38,6 +38,12 @@ topics = {{ sahara_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if sahara_policy_file is defined %} [oslo_policy] policy_file = {{ sahara_policy_file }} diff --git a/ansible/roles/searchlight/templates/searchlight.conf.j2 b/ansible/roles/searchlight/templates/searchlight.conf.j2 index e1ea68cfed0c1e0af1c0ce5a009c942ff2838fef..1c51fbcc619fa1e5831d98ad657f3232d9e69ed3 100644 --- a/ansible/roles/searchlight/templates/searchlight.conf.j2 +++ b/ansible/roles/searchlight/templates/searchlight.conf.j2 @@ -44,6 +44,11 @@ topics = {{ searchlight_enabled_notification_topics | map(attribute='name') | jo driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} {% if searchlight_policy_file is defined %} [oslo_policy] diff --git a/ansible/roles/senlin/templates/senlin.conf.j2 b/ansible/roles/senlin/templates/senlin.conf.j2 index 2764bf07d31934a4165d1fdf0287a9436b52a3c0..5879a8f2225da459d981424612deee28f42154e5 100644 --- a/ansible/roles/senlin/templates/senlin.conf.j2 +++ b/ansible/roles/senlin/templates/senlin.conf.j2 @@ -66,6 +66,12 @@ topics = {{ senlin_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if senlin_policy_file is defined %} [oslo_policy] policy_file = {{ senlin_policy_file }} diff --git a/ansible/roles/solum/templates/solum.conf.j2 b/ansible/roles/solum/templates/solum.conf.j2 index 02d46ecc9e684c3d80dbdd7f43df9c3055b5190b..e4d3c4647ad92263692c670e0212627c94babca3 100644 --- a/ansible/roles/solum/templates/solum.conf.j2 +++ b/ansible/roles/solum/templates/solum.conf.j2 @@ -61,3 +61,9 @@ memcached_servers = {% for host in groups['memcached'] %}{{ 'api' | kolla_addres [oslo_messaging_notifications] transport_url = {{ notify_transport_url }} + +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} diff --git a/ansible/roles/tacker/templates/tacker.conf.j2 b/ansible/roles/tacker/templates/tacker.conf.j2 index c76b83bd201009c8d4484d151413df508a467867..4f8928755512cb1e58252ce2b107d0ed53fab52f 100644 --- a/ansible/roles/tacker/templates/tacker.conf.j2 +++ b/ansible/roles/tacker/templates/tacker.conf.j2 @@ -66,6 +66,12 @@ topics = {{ tacker_enabled_notification_topics | map(attribute='name') | join(', driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if tacker_policy_file is defined %} [oslo_policy] policy_file = {{ tacker_policy_file }} diff --git a/ansible/roles/trove/templates/trove-conductor.conf.j2 b/ansible/roles/trove/templates/trove-conductor.conf.j2 index 42247a3b03d112ab23fb4d4447339eeac435d99c..6aaf468563ca38ef1204d194b1c39d308718132f 100644 --- a/ansible/roles/trove/templates/trove-conductor.conf.j2 +++ b/ansible/roles/trove/templates/trove-conductor.conf.j2 @@ -25,6 +25,12 @@ topics = {{ trove_enabled_notification_topics | map(attribute='name') | join(',' driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [database] connection = mysql+pymysql://{{ trove_database_user }}:{{ trove_database_password }}@{{ trove_database_address }}/{{ trove_database_name }} connection_recycle_time = {{ database_connection_recycle_time }} diff --git a/ansible/roles/trove/templates/trove-taskmanager.conf.j2 b/ansible/roles/trove/templates/trove-taskmanager.conf.j2 index 9c4d4ac49824eb957ec6fb88e0876663073b6908..c578bbf8ec6433d1f9df4bd7a0d2d01353b4b6e1 100644 --- a/ansible/roles/trove/templates/trove-taskmanager.conf.j2 +++ b/ansible/roles/trove/templates/trove-taskmanager.conf.j2 @@ -48,6 +48,11 @@ topics = {{ trove_enabled_notification_topics | map(attribute='name') | join(',' driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} {% if enable_osprofiler | bool %} [profiler] diff --git a/ansible/roles/trove/templates/trove.conf.j2 b/ansible/roles/trove/templates/trove.conf.j2 index 3bb9199aa6b357661fa33eb02d1a7e81c9553809..e642ed2687ce1df5461fa64846e1542d6ad8614f 100644 --- a/ansible/roles/trove/templates/trove.conf.j2 +++ b/ansible/roles/trove/templates/trove.conf.j2 @@ -55,6 +55,12 @@ topics = {{ trove_enabled_notification_topics | map(attribute='name') | join(',' driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if enable_osprofiler | bool %} [profiler] enabled = true diff --git a/ansible/roles/vitrage/templates/vitrage.conf.j2 b/ansible/roles/vitrage/templates/vitrage.conf.j2 index 12cf804956574433f788719ba97840d4db479ce5..e007c03cd0c6f4880b9114fe0bde8eb7be99477d 100644 --- a/ansible/roles/vitrage/templates/vitrage.conf.j2 +++ b/ansible/roles/vitrage/templates/vitrage.conf.j2 @@ -72,6 +72,12 @@ topics = {{ vitrage_enabled_notification_topics | map(attribute='name') | join(' driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + [oslo_concurrency] lock_path = /var/lib/vitrage/tmp diff --git a/ansible/roles/watcher/templates/watcher.conf.j2 b/ansible/roles/watcher/templates/watcher.conf.j2 index 33178edd47ac567042809c5d5df21e2d4cdf8aa7..3f655da1dc4694d95007ab0a85cd92979ab63fc0 100644 --- a/ansible/roles/watcher/templates/watcher.conf.j2 +++ b/ansible/roles/watcher/templates/watcher.conf.j2 @@ -57,6 +57,12 @@ topics = {{ watcher_enabled_notification_topics | map(attribute='name') | join(' driver = noop {% endif %} +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} + {% if watcher_policy_file is defined %} [oslo_policy] policy_file = {{ watcher_policy_file }} diff --git a/ansible/roles/zun/templates/zun.conf.j2 b/ansible/roles/zun/templates/zun.conf.j2 index a3358c51c59148b55e6783cf45d7b53fe6dfae5b..4600a48229236476e9cf5f3886d24e246877887d 100644 --- a/ansible/roles/zun/templates/zun.conf.j2 +++ b/ansible/roles/zun/templates/zun.conf.j2 @@ -127,3 +127,9 @@ docker_remote_api_port = 2375 [cni_daemon] cni_daemon_port = {{ zun_cni_daemon_port }} + +{% if om_enable_rabbitmq_tls | bool %} +[oslo_messaging_rabbit] +ssl = true +ssl_ca_file = {{ om_rabbitmq_cacert }} +{% endif %} diff --git a/doc/source/admin/advanced-configuration.rst b/doc/source/admin/advanced-configuration.rst index d228c833453ca33dca11be8663f7b557fabc449d..82f28654a39ac004631003b49c97356179f51615 100644 --- a/doc/source/admin/advanced-configuration.rst +++ b/doc/source/admin/advanced-configuration.rst @@ -69,6 +69,8 @@ RabbitMQ doesn't work with IP address, hence the IP address of ``api_interface`` should be resolvable by hostnames to make sure that all RabbitMQ Cluster hosts can resolve each others hostname beforehand. +.. _tls-configuration: + TLS Configuration ~~~~~~~~~~~~~~~~~ diff --git a/doc/source/conf.py b/doc/source/conf.py index f10c47e994903df60a06a45ce58d9dae7cc13e38..b7b15c4b7d7d16b561df7380d2315b1b8518dc36 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -98,6 +98,7 @@ openstack_projects = [ 'neutron', 'nova', 'octavia', + 'oslo.messaging', 'oslotest', 'swift', ] diff --git a/doc/source/reference/message-queues/rabbitmq.rst b/doc/source/reference/message-queues/rabbitmq.rst index 1457327ce046d918f128401895b678c203f66196..916df309c819fd83b49e679055879221895f8f10 100644 --- a/doc/source/reference/message-queues/rabbitmq.rst +++ b/doc/source/reference/message-queues/rabbitmq.rst @@ -8,6 +8,81 @@ RabbitMQ is a message broker written in Erlang. It is currently the default provider of message queues in Kolla Ansible deployments. +TLS encryption +~~~~~~~~~~~~~~ + +There are a number of channels to consider when securing RabbitMQ +communication. Kolla Ansible currently supports TLS encryption of the +following: + +* client-server traffic, typically between OpenStack services using the + :oslo.messaging-doc:`oslo.messaging </>` library and RabbitMQ +* RabbitMQ Management API and UI (frontend connection to HAProxy only) + +Encryption of the following channels is not currently supported: + +* RabbitMQ cluster traffic between RabbitMQ server nodes +* RabbitMQ CLI communication with RabbitMQ server nodes +* RabbitMQ Management API and UI (backend connection from HAProxy to RabbitMQ) + +Client-server +------------- + +Encryption of client-server traffic is enabled by setting +``rabbitmq_enable_tls`` to ``true``. Additionally, certificates and keys must +be available in the following paths (in priority order): + +Certificates: + +* ``"{{ kolla_certificates_dir }}/{{ inventory_hostname }}/rabbitmq-cert.pem"`` +* ``"{{ kolla_certificates_dir }}/{{ inventory_hostname }}-cert.pem"`` +* ``"{{ kolla_certificates_dir }}/rabbitmq-cert.pem"`` + +Keys: + +* ``"{{ kolla_certificates_dir }}/{{ inventory_hostname }}/rabbitmq-key.pem"`` +* ``"{{ kolla_certificates_dir }}/{{ inventory_hostname }}-key.pem"`` +* ``"{{ kolla_certificates_dir }}/rabbitmq-key.pem"`` + +The default for ``kolla_certificates_dir`` is ``/etc/kolla/certificates``. + +The certificates must be valid for the IP address of the host running RabbitMQ +on the API network. + +Additional TLS configuration options may be passed to RabbitMQ via +``rabbitmq_tls_options``. This should be a dict, and the keys will be prefixed +with ``ssl_options.``. For example: + +.. code-block:: yaml + + rabbitmq_tls_options: + ciphers.1: ECDHE-ECDSA-AES256-GCM-SHA384 + ciphers.2: ECDHE-RSA-AES256-GCM-SHA384 + ciphers.3: ECDHE-ECDSA-AES256-SHA384 + honor_cipher_order: true + honor_ecc_order: true + +Details on configuration of RabbitMQ for TLS can be found in the `RabbitMQ +documentation <https://www.rabbitmq.com/ssl.html>`__. + +When ``om_rabbitmq_enable_tls`` is ``true`` (it defaults to the value of +``rabbitmq_enable_tls``), applicable OpenStack services will be configured to +use oslo.messaging with TLS enabled. The CA certificate is configured via +``om_rabbitmq_cacert`` (it defaults to ``rabbitmq_cacert``, which points to the +system's trusted CA certificate bundle for TLS). Note that there is currently +no support for using client certificates. + +For testing purposes, Kolla Ansible provides the ``kolla-ansible certificates`` +command, which will generate self-signed certificates for RabbitMQ if +``rabbitmq_enable_tls`` is ``true``. + +Management API and UI +--------------------- + +The management API and UI are accessed via HAProxy, exposed only on the +internal VIP. As such, traffic to this endpoint is encrypted when +``kolla_enable_tls_internal`` is ``true``. See :ref:`tls-configuration`. + Passing arguments to RabbitMQ server's Erlang VM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml index 34c2ae69eb709112f8265be1fa2006e703ff6115..f1b5336b3e0db50a6c3f234aa37210e269e0af8d 100644 --- a/etc/kolla/globals.yml +++ b/etc/kolla/globals.yml @@ -84,6 +84,10 @@ #om_rpc_port: "{{ qdrouterd_port }}" #om_rpc_group: "qdrouterd" +# Whether to enable TLS for oslo.messaging communication with RabbitMQ. +#om_enable_rabbitmq_tls: "{{ rabbitmq_enable_tls | bool }}" +# CA certificate bundle in containers using oslo.messaging with RabbitMQ TLS. +#om_rabbitmq_cacert: "{{ rabbitmq_cacert }}" ############################## # Neutron - Networking Options @@ -373,6 +377,10 @@ # These are appended to args already provided by Kolla Ansible # to configure IPv6 in RabbitMQ server. #rabbitmq_server_additional_erl_args: "" +# Whether to enable TLS encryption for RabbitMQ client-server communication. +#rabbitmq_enable_tls: "no" +# CA certificate bundle in RabbitMQ container. +#rabbitmq_cacert: "/etc/ssl/certs/{{ 'ca-certificates.crt' if kolla_base_distro in ['debian', 'ubuntu'] else 'ca-bundle.trust.crt' }}" ################# # MariaDB options diff --git a/releasenotes/notes/rabbitmq-tls-78ea3fddf67267f2.yaml b/releasenotes/notes/rabbitmq-tls-78ea3fddf67267f2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f8bced3bac35994a295c5f5f2d08f1424f20fb5b --- /dev/null +++ b/releasenotes/notes/rabbitmq-tls-78ea3fddf67267f2.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Adds support for TLS encryption of RabbitMQ client-server communication. + See `blueprint + <https://blueprints.launchpad.net/kolla-ansible/+spec/message-queue-ssl-support>`__ + for details. diff --git a/tests/templates/globals-default.j2 b/tests/templates/globals-default.j2 index 2740ab1ef5ae6287f2e74aa91cb7e3733a55fbf1..bf4364d913bac9c73fcce118a51a65d4cf59883d 100644 --- a/tests/templates/globals-default.j2 +++ b/tests/templates/globals-default.j2 @@ -134,6 +134,7 @@ openstack_cacert: "/etc/ssl/certs/ca-certificates.crt" openstack_cacert: "/etc/pki/tls/certs/ca-bundle.crt" {% endif %} kolla_admin_openrc_cacert: "{% raw %}{{ kolla_certificates_dir }}{% endraw %}/ca/root.crt" +rabbitmq_enable_tls: "yes" {% endif %} {% if scenario == 'linuxbridge' %}