From 62861db22df6170123352b978eb9e7f472b67d6f Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Tue, 11 Sep 2018 11:15:42 +0200 Subject: [PATCH] Add support for native TLS encryption on NBD for disk migration The NBD protocol previously runs in clear text, offering no security protection for the data transferred, unless it is tunnelled over some external transport like SSH. Such tunnelling is inefficient and inconvenient to manage. Support for TLS to the NBD clients & servers provided by QEMU was added. In tls-everywhere use case we want to take advantage of this feature to create the certificates and configure qemu to use nbd tls. Related-bug: 1793093 Depends-On: Ifa5cf08d5104a62c9c094e3585de33e19e265110 Change-Id: I1db1b60be4907511f0ec0f5aa0f0a45e1c5d9b45 --- manifests/certmonger/ca/qemu.pp | 65 +++++++++++++ manifests/certmonger/qemu.pp | 91 +++++++++++++++++++ manifests/certmonger/qemu_dirs.pp | 41 +++++++++ manifests/certmonger/qemu_nbd_dirs.pp | 42 +++++++++ manifests/profile/base/certmonger_user.pp | 19 ++++ ...d_for_disk_migration-2e16003c4764a399.yaml | 12 +++ 6 files changed, 270 insertions(+) create mode 100644 manifests/certmonger/ca/qemu.pp create mode 100644 manifests/certmonger/qemu.pp create mode 100644 manifests/certmonger/qemu_dirs.pp create mode 100644 manifests/certmonger/qemu_nbd_dirs.pp create mode 100644 releasenotes/notes/nova_qemu_native_tls_encryption_on_nbd_for_disk_migration-2e16003c4764a399.yaml diff --git a/manifests/certmonger/ca/qemu.pp b/manifests/certmonger/ca/qemu.pp new file mode 100644 index 000000000..aa5ddb1b2 --- /dev/null +++ b/manifests/certmonger/ca/qemu.pp @@ -0,0 +1,65 @@ +# Copyright 2017 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Class: tripleo::certmonger::ca::qemu +# +# Sets the necessary file that will be used by qemu servers and +# clients. +# +# === Parameters: +# +# [*origin_ca_pem*] +# (Optional) Path to the CA certificate that qemu will use. This is not +# assumed automatically or uses the system CA bundle as is the case of other +# services because a limitation with the file sizes in GNU TLS, which qemu +# uses as a TLS backend. +# Defaults to undef +# +# [*certmonger_ca*] +# (Optional) The CA name that certmonger will use to generate qemu certificates. +# If this is not local or IPA then is assumed to be an IPA sub-CA and will be +# added to the certmonger CA list. +# Defaults to hiera('certmonger_ca_qemu', 'local'). +# +class tripleo::certmonger::ca::qemu( + $origin_ca_pem = undef, + $certmonger_ca = hiera('certmonger_ca_qemu', 'local'), +){ + if $origin_ca_pem { + $ensure_file = 'link' + } else { + $ensure_file = 'absent' + } + file { '/etc/pki/qemu/ca-cert.pem': + ensure => $ensure_file, + mode => '0644', + target => $origin_ca_pem, + } + + if ! ($certmonger_ca in [ 'local', 'IPA', 'ipa' ]) { + $wrapper_path = '/usr/libexec/certmonger/cm_ipa_subca_wrapper' + $ipa_helper_path = '/usr/libexec/certmonger/ipa-submit' + file { $wrapper_path: + source => 'puppet:///modules/tripleo/cm_ipa_subca_wrapper.py', + mode => '0755', + notify => Service['certmonger'] + } + -> exec { "Add ${certmonger_ca} IPA subCA to certmonger": + command => "getcert add-ca -c ${certmonger_ca} -e '${wrapper_path} ${certmonger_ca} ${ipa_helper_path}'", + path => ['/usr/bin', '/bin'], + unless => "getcert list-cas -c ${certmonger_ca} | grep '${wrapper_path} ${certmonger_ca}'", + notify => Service['certmonger'] + } + } +} diff --git a/manifests/certmonger/qemu.pp b/manifests/certmonger/qemu.pp new file mode 100644 index 000000000..8b1bfb485 --- /dev/null +++ b/manifests/certmonger/qemu.pp @@ -0,0 +1,91 @@ +# Copyright 2017 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Resource: tripleo::certmonger::qemu +# +# Request a certificate for quemu and do the necessary setup. +# +# === Parameters +# +# [*hostname*] +# The hostname of the node. this will be set in the CN of the certificate. +# +# [*service_certificate*] +# The path to the certificate that will be used for TLS in this service. +# +# [*service_key*] +# The path to the key that will be used for TLS in this service. +# +# [*certmonger_ca*] +# (Optional) The CA that certmonger will use to generate the certificates. +# Defaults to hiera('certmonger_ca', 'local'). +# +# [*file_owner*] +# (Optional) The user which the certificate and key files belong to. +# Defaults to 'root' +# +# [*postsave_cmd*] +# (Optional) Specifies the command to execute after requesting a certificate. +# If nothing is given, it will default to: "systemctl reload ${service name}" +# Defaults to undef. +# +# [*principal*] +# (Optional) The service principal that is set for the service in kerberos. +# Defaults to undef +# +# [*cacertfile*] +# (Optional) Specifies that path to write the CA cerftificate to. +# Defaults to undef +# +define tripleo::certmonger::qemu ( + $hostname, + $service_certificate, + $service_key, + $certmonger_ca = hiera('certmonger_ca_qemu', 'local'), + $cacertfile = undef, + $postsave_cmd = undef, + $principal = undef, +) { + include ::certmonger + include ::nova::params + + $postsave_cmd_real = pick($postsave_cmd, "systemctl reload ${::nova::params::libvirt_service_name}") + certmonger_certificate { $name : + ensure => 'present', + certfile => $service_certificate, + keyfile => $service_key, + hostname => $hostname, + dnsname => $hostname, + principal => $principal, + postsave_cmd => $postsave_cmd_real, + ca => $certmonger_ca_qemu, + cacertfile => $cacertfile, + wait => true, + tag => 'qemu-cert', + require => Class['::certmonger'], + } + + file { $service_certificate : + require => Certmonger_certificate[$name], + mode => '0644' + } + file { $service_key : + require => Certmonger_certificate[$name], + group => 'qemu', + mode => '0640' + } + + File[$service_certificate] ~> Service<| title == $::nova::params::libvirt_service_name |> + File[$service_key] ~> Service<| title == $::nova::params::libvirt_service_name |> +} diff --git a/manifests/certmonger/qemu_dirs.pp b/manifests/certmonger/qemu_dirs.pp new file mode 100644 index 000000000..1f46a0f7a --- /dev/null +++ b/manifests/certmonger/qemu_dirs.pp @@ -0,0 +1,41 @@ +# Copyright 2017 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Class: tripleo::certmonger::qemu_dirs +# +# Creates the necessary directories for qemu certificates and keys in the +# assigned locations if specified. It also assigns the correct SELinux tags. +# +# === Parameters: +# +# [*certificate_dir*] +# (Optional) Directory where qemu server certificates will be stored. If left +# unspecified, it won't be created. +# Defaults to undef +# +class tripleo::certmonger::qemu_dirs( + $certificate_dir = undef, +){ + + if $certificate_dir { + file { $certificate_dir : + ensure => 'directory', + selrole => 'object_r', + seltype => 'cert_t', + seluser => 'system_u', + } + File[$certificate_dir] ~> Certmonger_certificate<| tag == 'qemu-server-cert' |> + } + +} diff --git a/manifests/certmonger/qemu_nbd_dirs.pp b/manifests/certmonger/qemu_nbd_dirs.pp new file mode 100644 index 000000000..4ef2cc691 --- /dev/null +++ b/manifests/certmonger/qemu_nbd_dirs.pp @@ -0,0 +1,42 @@ +# Copyright 2017 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Class: tripleo::certmonger::qemu_nbd_dirs +# +# Creates the necessary directories for qemu nbd client certificates and keys +# in the assigned locations if specified. It also assigns the correct SELinux +# tags. +# +# === Parameters: +# +# [*certificate_dir*] +# (Optional) Directory where qemu-nbd's client certificates will be stored. +# If left unspecified, it won't be created. +# Defaults to undef +# +class tripleo::certmonger::qemu_nbd_dirs( + $certificate_dir = undef, +){ + + if $certificate_dir { + file { $certificate_dir : + ensure => 'directory', + selrole => 'object_r', + seltype => 'cert_t', + seluser => 'system_u', + } + File[$certificate_dir] ~> Certmonger_certificate<| tag == 'qemu-cert' |> + } + +} diff --git a/manifests/profile/base/certmonger_user.pp b/manifests/profile/base/certmonger_user.pp index f325bf83c..c5db97461 100644 --- a/manifests/profile/base/certmonger_user.pp +++ b/manifests/profile/base/certmonger_user.pp @@ -77,6 +77,16 @@ # certificate is renewed. # Defaults to undef # +# [*qemu_certificates_specs*] +# (Optional) The specifications to give to certmonger for the certificate(s) +# it will create. +# Defaults to hiera('qemu_certificates_specs', {}). +# +# [*qemu_postsave_cmd*] +# (Optional) If set, it overrides the default way to restart services when the +# certificate is renewed. +# Defaults to undef +# # [*mongodb_certificate_specs*] # (Optional) The specifications to give to certmonger for the certificate(s) # it will create. @@ -137,6 +147,8 @@ class tripleo::profile::base::certmonger_user ( $libvirt_postsave_cmd = undef, $libvirt_vnc_certificates_specs = hiera('libvirt_vnc_certificates_specs', {}), $libvirt_vnc_postsave_cmd = undef, + $qemu_certificates_specs = hiera('qemu_certificates_specs', {}), + $qemu_postsave_cmd = undef, $mongodb_certificate_specs = hiera('mongodb_certificate_specs',{}), $mysql_certificate_specs = hiera('tripleo::profile::base::database::mysql::certificate_specs', {}), $rabbitmq_certificate_specs = hiera('tripleo::profile::base::rabbitmq::certificate_specs', {}), @@ -170,6 +182,7 @@ class tripleo::profile::base::certmonger_user ( Certmonger_certificate<||> -> Class['::tripleo::certmonger::ca::crl'] include ::tripleo::certmonger::ca::libvirt include ::tripleo::certmonger::ca::libvirt_vnc + include ::tripleo::certmonger::ca::qemu unless empty($apache_certificates_specs) { include ::tripleo::certmonger::apache_dirs @@ -186,6 +199,12 @@ class tripleo::profile::base::certmonger_user ( ensure_resources('tripleo::certmonger::libvirt_vnc', $libvirt_vnc_certificates_specs, {'postsave_cmd' => $libvirt_vnc_postsave_cmd}) } + unless empty($qemu_certificates_specs) { + include ::tripleo::certmonger::qemu_dirs + include ::tripleo::certmonger::qemu_nbd_dirs + ensure_resources('tripleo::certmonger::qemu', $qemu_certificates_specs, + {'postsave_cmd' => $qemu_postsave_cmd}) + } unless empty($haproxy_certificates_specs) { include ::tripleo::certmonger::haproxy_dirs ensure_resources('tripleo::certmonger::haproxy', $haproxy_certificates_specs, diff --git a/releasenotes/notes/nova_qemu_native_tls_encryption_on_nbd_for_disk_migration-2e16003c4764a399.yaml b/releasenotes/notes/nova_qemu_native_tls_encryption_on_nbd_for_disk_migration-2e16003c4764a399.yaml new file mode 100644 index 000000000..282b7d40c --- /dev/null +++ b/releasenotes/notes/nova_qemu_native_tls_encryption_on_nbd_for_disk_migration-2e16003c4764a399.yaml @@ -0,0 +1,12 @@ +--- +features: + - | + Add support for native TLS encryption on NBD for disk migration + + The NBD protocol previously runs in clear text, offering no security + protection for the data transferred, unless it is tunnelled over some + external transport like SSH. Such tunnelling is inefficient and + inconvenient to manage. Support for TLS to the NBD clients & servers + provided by QEMU was added. In tls-everywhere use case we want to + take advantage of this feature to create the certificates and configure + qemu to use nbd tls.