From 80d0c00d54bc1c7cde03d205145c56a2f4e28519 Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Tue, 11 Sep 2018 11:20:54 +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. This adds support to configure ndb related qemu.conf parameters. Since libvirt >= 4.5 is required ::nova::compute::libvirt::version checks the OS version to map the libvirt version we can expect and only configured the nbd parameter then. Change-Id: Ifa5cf08d5104a62c9c094e3585de33e19e265110 Related-Bug: 1793093 --- manifests/compute/libvirt/qemu.pp | 57 +++++-- manifests/compute/libvirt/version.pp | 43 +++++ ..._qemu_nbd_parameters-f8b975e695d6efd9.yaml | 11 ++ .../classes/nova_compute_libvirt_qemu_spec.rb | 149 ++++++++++++++++-- 4 files changed, 237 insertions(+), 23 deletions(-) create mode 100644 manifests/compute/libvirt/version.pp create mode 100644 releasenotes/notes/add_qemu_nbd_parameters-f8b975e695d6efd9.yaml diff --git a/manifests/compute/libvirt/qemu.pp b/manifests/compute/libvirt/qemu.pp index 5400e2c23..da20afb81 100644 --- a/manifests/compute/libvirt/qemu.pp +++ b/manifests/compute/libvirt/qemu.pp @@ -33,6 +33,15 @@ # NOTE: big files will be stored here # Defaults to undef. # +# [*nbd_tls*] +# (optional) Enables TLS for nbd connections. +# Defaults to false. +# +# [*libvirt_version*] +# (optional) installed libvirt version. Default is automatic detected depending +# of the used OS installed via ::nova::compute::libvirt::version::default . +# Defaults to ::nova::compute::libvirt::version::default +# class nova::compute::libvirt::qemu( $configure_qemu = false, $group = undef, @@ -40,8 +49,10 @@ class nova::compute::libvirt::qemu( $max_processes = 4096, $vnc_tls = false, $vnc_tls_verify = true, - $memory_backing_dir = undef -){ + $memory_backing_dir = undef, + $nbd_tls = false, + $libvirt_version = $::nova::compute::libvirt::version::default, +) inherits nova::compute::libvirt::version { include ::nova::deps require ::nova::compute::libvirt @@ -63,11 +74,17 @@ class nova::compute::libvirt::qemu( $vnc_tls_verify_value = 0 } + if $nbd_tls { + $nbd_tls_value = 1 + } else { + $nbd_tls_value = 0 + } + $augues_changes_default = [ "set max_files ${max_files}", "set max_processes ${max_processes}", "set vnc_tls ${vnc_tls_value}", - "set vnc_tls_x509_verify ${vnc_tls_verify_value}" + "set vnc_tls_x509_verify ${vnc_tls_verify_value}", ] if $group and !empty($group) { $augues_group_changes = ["set group ${group}"] @@ -79,7 +96,13 @@ class nova::compute::libvirt::qemu( } else { $augues_memory_backing_dir_changes = [] } - $augues_changes = concat($augues_changes_default, $augues_group_changes, $augues_memory_backing_dir_changes) + if versioncmp($libvirt_version, '4.5') >= 0 { + $augues_nbd_tls_changes = ["set nbd_tls ${nbd_tls_value}"] + } else { + $augues_nbd_tls_changes = [] + } + + $augues_changes = concat($augues_changes_default, $augues_group_changes, $augues_memory_backing_dir_changes, $augues_nbd_tls_changes) augeas { 'qemu-conf-limits': context => '/files/etc/libvirt/qemu.conf', @@ -87,16 +110,26 @@ class nova::compute::libvirt::qemu( tag => 'qemu-conf-augeas', } } else { + + $augues_changes_default = [ + 'rm max_files', + 'rm max_processes', + 'rm group', + 'rm vnc_tls', + 'rm vnc_tls_x509_verify', + 'rm memory_backing_dir', + ] + if versioncmp($libvirt_version, '4.5') >= 0 { + $augues_nbd_tls_changes = ['rm nbd_tls'] + } else { + $augues_nbd_tls_changes = [] + } + + $augues_changes = concat($augues_changes_default, $augues_nbd_tls_changes) + augeas { 'qemu-conf-limits': context => '/files/etc/libvirt/qemu.conf', - changes => [ - 'rm max_files', - 'rm max_processes', - 'rm group', - 'rm vnc_tls', - 'rm vnc_tls_x509_verify', - 'rm memory_backing_dir' - ], + changes => $augues_changes, tag => 'qemu-conf-augeas', } } diff --git a/manifests/compute/libvirt/version.pp b/manifests/compute/libvirt/version.pp new file mode 100644 index 000000000..caaf48902 --- /dev/null +++ b/manifests/compute/libvirt/version.pp @@ -0,0 +1,43 @@ +# Class: nova::compute::libvirt::version +# +# Try to detect the version by OS +# Right now this is only used by nova::compute::libvirt::qemu and the +# interesting version is with which release there will be libvirt 4.5 +# or higher. +# +class nova::compute::libvirt::version { + # This will be 7.5 or 7.6 on RedHat, 9 on Debian, 18.10 or cosmic on Ubuntu, etc. + case $facts['os']['family'] { + 'RedHat': { + case $facts['os']['name'] { + 'RedHat': { + if versioncmp($facts['os']['release']['full'], '7.6') >= 0 { + $default = '4.5' + } else { + $default = '3.9' + } + } + 'Fedora': { + if versioncmp($facts['os']['release']['full'], '29') >= 0 { + $default = '4.5' + } else { + $default = '3.9' + } + } + default: { + $default = '3.9' + } + } + } + 'Debian': { + if versioncmp($facts['os']['release']['full'], '18.10') >= 0 { + $default = '4.6' + } else { + $default = '4.0' + } + } + default: { + fail("Class['nova::compute::libvirt::version']: Unsupported osfamily: ${::osfamily}") + } + } +} diff --git a/releasenotes/notes/add_qemu_nbd_parameters-f8b975e695d6efd9.yaml b/releasenotes/notes/add_qemu_nbd_parameters-f8b975e695d6efd9.yaml new file mode 100644 index 000000000..341ecfe29 --- /dev/null +++ b/releasenotes/notes/add_qemu_nbd_parameters-f8b975e695d6efd9.yaml @@ -0,0 +1,11 @@ +--- +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. This adds support to configure ndb related + qemu.conf parameters. diff --git a/spec/classes/nova_compute_libvirt_qemu_spec.rb b/spec/classes/nova_compute_libvirt_qemu_spec.rb index 3d35e674f..9292bd855 100644 --- a/spec/classes/nova_compute_libvirt_qemu_spec.rb +++ b/spec/classes/nova_compute_libvirt_qemu_spec.rb @@ -13,24 +13,79 @@ describe 'nova::compute::libvirt::qemu' do context 'when not configuring qemu' do let :params do { - :configure_qemu => false + :configure_qemu => false, + :libvirt_version => '3.9', } end it { is_expected.to contain_augeas('qemu-conf-limits').with({ :context => '/files/etc/libvirt/qemu.conf', - :changes => [ "rm max_files", "rm max_processes", "rm group", "rm vnc_tls", "rm vnc_tls_x509_verify", "rm memory_backing_dir" ], + :changes => [ + "rm max_files", + "rm max_processes", + "rm group", + "rm vnc_tls", + "rm vnc_tls_x509_verify", + "rm memory_backing_dir", + ], + }).that_notifies('Service[libvirt]') } + end + + context 'when not configuring qemu with libvirt >= 4.5' do + let :params do + { + :configure_qemu => false, + :libvirt_version => '4.5', + } + end + it { is_expected.to contain_augeas('qemu-conf-limits').with({ + :context => '/files/etc/libvirt/qemu.conf', + :changes => [ + "rm max_files", + "rm max_processes", + "rm group", + "rm vnc_tls", + "rm vnc_tls_x509_verify", + "rm memory_backing_dir", + "rm nbd_tls", + ], }).that_notifies('Service[libvirt]') } end context 'when configuring qemu by default' do let :params do { - :configure_qemu => true + :configure_qemu => true, + :libvirt_version => '3.9', } end it { is_expected.to contain_augeas('qemu-conf-limits').with({ :context => '/files/etc/libvirt/qemu.conf', - :changes => [ "set max_files 1024", "set max_processes 4096", "set vnc_tls 0", "set vnc_tls_x509_verify 0" ], + :changes => [ + "set max_files 1024", + "set max_processes 4096", + "set vnc_tls 0", + "set vnc_tls_x509_verify 0", + ], + :tag => 'qemu-conf-augeas', + }).that_notifies('Service[libvirt]') } + end + + context 'when configuring qemu by default with libvirt >= 4.5' do + let :params do + { + :configure_qemu => true, + :libvirt_version => '4.5', + } + end + it { is_expected.to contain_augeas('qemu-conf-limits').with({ + :context => '/files/etc/libvirt/qemu.conf', + :changes => [ + "set max_files 1024", + "set max_processes 4096", + "set vnc_tls 0", + "set vnc_tls_x509_verify 0", + "set nbd_tls 0", + ], :tag => 'qemu-conf-augeas', }).that_notifies('Service[libvirt]') } end @@ -41,11 +96,39 @@ describe 'nova::compute::libvirt::qemu' do :configure_qemu => true, :max_files => 32768, :max_processes => 131072, + :libvirt_version => '3.9', } end it { is_expected.to contain_augeas('qemu-conf-limits').with({ :context => '/files/etc/libvirt/qemu.conf', - :changes => [ "set max_files 32768", "set max_processes 131072", "set vnc_tls 0", "set vnc_tls_x509_verify 0" ], + :changes => [ + "set max_files 32768", + "set max_processes 131072", + "set vnc_tls 0", + "set vnc_tls_x509_verify 0", + ], + :tag => 'qemu-conf-augeas', + }).that_notifies('Service[libvirt]') } + end + + context 'when configuring qemu with overridden parameters with libvirt >= 4.5' do + let :params do + { + :configure_qemu => true, + :max_files => 32768, + :max_processes => 131072, + :libvirt_version => '4.5', + } + end + it { is_expected.to contain_augeas('qemu-conf-limits').with({ + :context => '/files/etc/libvirt/qemu.conf', + :changes => [ + "set max_files 32768", + "set max_processes 131072", + "set vnc_tls 0", + "set vnc_tls_x509_verify 0", + "set nbd_tls 0", + ], :tag => 'qemu-conf-augeas', }).that_notifies('Service[libvirt]') } end @@ -57,7 +140,8 @@ describe 'nova::compute::libvirt::qemu' do :group => 'openvswitch', :max_files => 32768, :max_processes => 131072, - :memory_backing_dir => '/tmp' + :memory_backing_dir => '/tmp', + :libvirt_version => '3.9', } end it { is_expected.to contain_augeas('qemu-conf-limits').with({ @@ -68,7 +152,7 @@ describe 'nova::compute::libvirt::qemu' do "set vnc_tls 0", "set vnc_tls_x509_verify 0", "set group openvswitch", - "set memory_backing_dir /tmp" + "set memory_backing_dir /tmp", ], :tag => 'qemu-conf-augeas', }).that_notifies('Service[libvirt]') } @@ -78,7 +162,8 @@ describe 'nova::compute::libvirt::qemu' do let :params do { :configure_qemu => true, - :vnc_tls => true + :vnc_tls => true, + :libvirt_version => '3.9', } end it { is_expected.to contain_augeas('qemu-conf-limits').with({ @@ -87,7 +172,7 @@ describe 'nova::compute::libvirt::qemu' do "set max_files 1024", "set max_processes 4096", "set vnc_tls 1", - "set vnc_tls_x509_verify 1" + "set vnc_tls_x509_verify 1", ], :tag => 'qemu-conf-augeas', }).that_notifies('Service[libvirt]') } @@ -98,7 +183,8 @@ describe 'nova::compute::libvirt::qemu' do { :configure_qemu => true, :vnc_tls => true, - :vnc_tls_verify => false + :vnc_tls_verify => false, + :libvirt_version => '3.9', } end it { is_expected.to contain_augeas('qemu-conf-limits').with({ @@ -107,7 +193,48 @@ describe 'nova::compute::libvirt::qemu' do "set max_files 1024", "set max_processes 4096", "set vnc_tls 1", - "set vnc_tls_x509_verify 0" + "set vnc_tls_x509_verify 0", + ], + :tag => 'qemu-conf-augeas', + }).that_notifies('Service[libvirt]') } + end + + context 'when configuring qemu with nbd_tls and libvirt < 4.5' do + let :params do + { + :configure_qemu => true, + :nbd_tls => true, + :libvirt_version => '3.9', + } + end + it { is_expected.to contain_augeas('qemu-conf-limits').with({ + :context => '/files/etc/libvirt/qemu.conf', + :changes => [ + "set max_files 1024", + "set max_processes 4096", + "set vnc_tls 0", + "set vnc_tls_x509_verify 0", + ], + :tag => 'qemu-conf-augeas', + }).that_notifies('Service[libvirt]') } + end + + context 'when configuring qemu with nbd_tls and libvirt >= 4.5' do + let :params do + { + :configure_qemu => true, + :nbd_tls => true, + :libvirt_version => '4.5', + } + end + it { is_expected.to contain_augeas('qemu-conf-limits').with({ + :context => '/files/etc/libvirt/qemu.conf', + :changes => [ + "set max_files 1024", + "set max_processes 4096", + "set vnc_tls 0", + "set vnc_tls_x509_verify 0", + "set nbd_tls 1", ], :tag => 'qemu-conf-augeas', }).that_notifies('Service[libvirt]') }