Add support for VNC TLS

Adds parameters to configure TLS for the nova novnc-proxy to libvirt/qemu
now the support has landed in nova (bp/websocket-proxy-to-host-security).

Change-Id: I24a9841ba04c95df27599b4d7ac2da8416e751e5
This commit is contained in:
Oliver Walsh 2018-01-19 10:04:51 +00:00
parent c5771feb7c
commit 0bb477d765
5 changed files with 245 additions and 58 deletions

View File

@ -20,11 +20,21 @@
# (optional) Maximum number of processes that can be run by qemu user.
# Defaults to 4096.
#
# [*vnc_tls*]
# (optional) Enables TLS for vnc connections.
# Defaults to false.
#
# [*vnc_tls_verify*]
# (optional) Enables TLS client cert verification when vnc_tls is enabled.
# Defaults to true.
#
class nova::compute::libvirt::qemu(
$configure_qemu = false,
$group = undef,
$max_files = 1024,
$max_processes = 4096,
$vnc_tls = false,
$vnc_tls_verify = true
){
include ::nova::deps
@ -39,9 +49,19 @@ class nova::compute::libvirt::qemu(
if $configure_qemu {
if $vnc_tls {
$vnc_tls_value = 1
$vnc_tls_verify_value = $vnc_tls_verify ? { true => 1, false => 0 }
} else {
$vnc_tls_value = 0
$vnc_tls_verify_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}"
]
if $group and !empty($group) {
$augues_group_changes = ["set group ${group}"]
@ -62,6 +82,8 @@ class nova::compute::libvirt::qemu(
'rm max_files',
'rm max_processes',
'rm group',
'rm vnc_tls',
'rm vnc_tls_x509_verify'
],
tag => 'qemu-conf-augeas',
}

View File

@ -33,6 +33,34 @@
# proxy server
# Defaults to '/vnc_auto.html'
#
# [*allow_noauth*]
# (optional) Whether connections to unauthenticated/unencrypted VNC servers
# are permitted.
# Defaults to true
#
# [*allow_vencrypt*]
# (optional) Whether connections to VNC servers supporting vencrypt are
# permitted.
# Defaults to false
#
# [*vencrypt_key*]
# (optional) path to the private key to use when connecting to VNC servers
# supporting vencrypt
# Required when allow_vencrypt is true.
# Defaults to undef
#
# [*vencrypt_cert*]
# (optional) path to the certifiate to use when connecting to VNC servers
# supporting vencrypt
# Required when allow_vencrypt is true.
# Defaults to undef
#
# [*vencrypt_ca*]
# (optional) path to the certificate authority cert to use when connecting
# to VNC servers that supporting vencrypt
# Required when allow_vencrypt is true.
# Defaults to undef
#
class nova::vncproxy(
$enabled = true,
$manage_service = true,
@ -40,15 +68,45 @@ class nova::vncproxy(
$host = '0.0.0.0',
$port = '6080',
$vncproxy_path = '/vnc_auto.html',
$ensure_package = 'present'
$ensure_package = 'present',
$allow_noauth = true,
$allow_vencrypt = false,
$vencrypt_key = undef,
$vencrypt_cert = undef,
$vencrypt_ca = undef,
) {
include ::nova::deps
include ::nova::params
if (!$allow_noauth and !$allow_vencrypt) {
fail('Either allow_noauth or allow_vencrypt must be true')
}
if $allow_vencrypt {
if (!$vencrypt_ca or !$vencrypt_cert or !$vencrypt_key) {
fail('vencrypt_ca/cert/key params are required when allow_vencrypt is true')
}
nova_config {
'vnc/vencrypt_ca_certs': value => $vencrypt_ca;
'vnc/vencrypt_client_cert': value => $vencrypt_cert;
'vnc/vencrypt_client_key': value => $vencrypt_key;
}
if $allow_noauth {
$auth_schemes = 'vencrypt,none'
} else {
$auth_schemes = 'vencrypt'
}
} else {
$auth_schemes = 'none'
}
nova_config {
'vnc/novncproxy_host': value => $host;
'vnc/novncproxy_port': value => $port;
'vnc/auth_schemes': value => $auth_schemes;
}
nova::generic_service { 'vncproxy':

View File

@ -0,0 +1,14 @@
---
features:
- |
Add parameters to configure TLS for nova novncproxy to/from libvirt/qemu:
* ``nova::vncproxy::allow_noauth``
* ``nova::vncproxy::allow_vencrypt``
* ``nova::vncproxy::vencrypt_key``
* ``nova::vncproxy::vencrypt_cert``
* ``nova::vncproxy::vencrypt_ca``
* ``nova::compute::libvirt::qemu::vnc_tls``
* ``nova::compute::libvirt::qemu::vnc_tls_verify``
More info is available in the `nova vnc-proxy documentation <https://docs.openstack.org/nova/queens/admin/remote-console-access.html#vnc-proxy-security>`_.

View File

@ -18,7 +18,7 @@ describe 'nova::compute::libvirt::qemu' do
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" ],
:changes => [ "rm max_files", "rm max_processes", "rm group", "rm vnc_tls", "rm vnc_tls_x509_verify" ],
}).that_notifies('Service[libvirt]') }
end
@ -30,7 +30,7 @@ describe 'nova::compute::libvirt::qemu' do
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" ],
: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
@ -45,7 +45,7 @@ describe 'nova::compute::libvirt::qemu' do
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" ],
: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
@ -64,11 +64,53 @@ describe 'nova::compute::libvirt::qemu' do
:changes => [
"set max_files 32768",
"set max_processes 131072",
"set vnc_tls 0",
"set vnc_tls_x509_verify 0",
"set group openvswitch"
],
:tag => 'qemu-conf-augeas',
}).that_notifies('Service[libvirt]') }
end
context 'when configuring qemu with vnc_tls' do
let :params do
{
:configure_qemu => true,
:vnc_tls => true
}
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 1",
"set vnc_tls_x509_verify 1"
],
:tag => 'qemu-conf-augeas',
}).that_notifies('Service[libvirt]') }
end
context 'when configuring qemu without vnc_tls_verify' do
let :params do
{
:configure_qemu => true,
:vnc_tls => true,
:vnc_tls_verify => false
}
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 1",
"set vnc_tls_x509_verify 0"
],
:tag => 'qemu-conf-augeas',
}).that_notifies('Service[libvirt]') }
end
end
on_supported_os({

View File

@ -2,26 +2,24 @@ require 'spec_helper'
describe 'nova::vncproxy' do
let :pre_condition do
'include nova'
end
shared_examples 'nova_vnc_proxy' do
let :pre_condition do
'include nova'
end
context 'with default parameters' do
describe 'on debian platforms' do
let :facts do
@default_facts.merge({ :osfamily => 'Debian' })
end
it { is_expected.to contain_nova_config('vnc/novncproxy_host').with(:value => '0.0.0.0') }
it { is_expected.to contain_nova_config('vnc/novncproxy_port').with(:value => '6080') }
it { is_expected.to contain_nova_config('vnc/auth_schemes').with(:value => 'none') }
it { is_expected.to contain_package('nova-vncproxy').with(
:name => 'nova-novncproxy',
:name => platform_params[:nova_vncproxy_package],
:ensure => 'present'
) }
it { is_expected.to contain_service('nova-vncproxy').with(
:name => 'nova-novncproxy',
:name => platform_params[:nova_vncproxy_service],
:hasstatus => true,
:ensure => 'running'
)}
@ -44,55 +42,108 @@ describe 'nova::vncproxy' do
)}
end
end
end
describe 'on debian OS' do
let :facts do
@default_facts.merge({
:osfamily => 'Debian',
:operatingsystem => 'Debian',
:operatingsystemmajrelease => '9',
:os_package_type => 'debian'
})
context 'with vencrypt' do
let :params do
{
:allow_vencrypt => true,
:vencrypt_key => '/foo.key',
:vencrypt_cert => '/bar.pem',
:vencrypt_ca => '/baz.pem'
}
end
it { is_expected.to contain_package('nova-vncproxy').with(
:name => "nova-consoleproxy",
:ensure => 'present'
)}
it { is_expected.to contain_service('nova-vncproxy').with(
:name => 'nova-novncproxy',
:hasstatus => true,
:ensure => 'running'
)}
end
describe 'on Ubuntu OS with Debian packages' do
let :facts do
@default_facts.merge({
:osfamily => 'Debian',
:operatingsystem => 'Ubuntu',
:os_package_type => 'debian'
})
end
it { is_expected.to contain_package('nova-vncproxy').with(
:name => "nova-consoleproxy",
:ensure => 'present'
)}
it { is_expected.to contain_service('nova-vncproxy').with(
:name => 'nova-novncproxy',
:hasstatus => true,
:ensure => 'running'
)}
end
describe 'on Redhatish platforms' do
let :facts do
@default_facts.merge({ :osfamily => 'Redhat' })
it { is_expected.to contain_nova_config('vnc/auth_schemes').with(:value => 'vencrypt,none') }
it { is_expected.to contain_nova_config('vnc/vencrypt_client_key').with(:value => '/foo.key')}
it { is_expected.to contain_nova_config('vnc/vencrypt_client_cert').with(:value => '/bar.pem')}
it { is_expected.to contain_nova_config('vnc/vencrypt_ca_certs').with(:value => '/baz.pem')}
end
it { is_expected.to compile.with_all_deps }
context 'with vencrypt without noauth' do
let :params do
{
:allow_vencrypt => true,
:allow_noauth => false,
:vencrypt_key => '/foo.key',
:vencrypt_cert => '/bar.pem',
:vencrypt_ca => '/baz.pem'
}
end
it { is_expected.to contain_nova_config('vnc/auth_schemes').with(:value => 'vencrypt') }
it { is_expected.to contain_nova_config('vnc/vencrypt_client_key').with(:value => '/foo.key')}
it { is_expected.to contain_nova_config('vnc/vencrypt_client_cert').with(:value => '/bar.pem')}
it { is_expected.to contain_nova_config('vnc/vencrypt_ca_certs').with(:value => '/baz.pem')}
end
context 'with no auth method set' do
let :params do
{
:allow_vencrypt => false,
:allow_noauth => false,
}
end
it_raises 'a Puppet::Error', /Either allow_noauth or allow_vencrypt must be true/
end
context 'with vencrypt missing ca' do
let :params do
{
:allow_vencrypt => true,
:allow_noauth => false,
:vencrypt_key => '/foo.key',
:vencrypt_cert => '/bar.pem',
}
end
it_raises 'a Puppet::Error', /vencrypt_ca\/cert\/key params are required when allow_vencrypt is true/
end
context 'with vencrypt missing key' do
let :params do
{
:allow_vencrypt => true,
:allow_noauth => false,
:vencrypt_cert => '/bar.pem',
:vencrypt_ca => '/baz.pem'
}
end
it_raises 'a Puppet::Error', /vencrypt_ca\/cert\/key params are required when allow_vencrypt is true/
end
context 'with vencrypt missing cert' do
let :params do
{
:allow_vencrypt => true,
:allow_noauth => false,
:vencrypt_key => '/foo.key',
:vencrypt_ca => '/baz.pem'
}
end
it_raises 'a Puppet::Error', /vencrypt_ca\/cert\/key params are required when allow_vencrypt is true/
end
end
on_supported_os({
:supported_os => OSDefaults.get_supported_os
}).each do |os,facts|
context "on #{os}" do
let (:facts) do
facts.merge!(OSDefaults.get_facts())
end
let (:platform_params) do
case facts[:osfamily]
when 'Debian'
{ :nova_vncproxy_package => 'nova-novncproxy',
:nova_vncproxy_service => 'nova-novncproxy' }
when 'RedHat'
{ :nova_vncproxy_package => 'openstack-nova-novncproxy',
:nova_vncproxy_service => 'openstack-nova-novncproxy' }
end
end
it_behaves_like 'nova_vnc_proxy'
end
end
end