Add octavia::certificates::client_ca and data

This patch adds two new parameters client_ca and
client_ca_data.

When setting up a development or testing Octavia setup
there is no real issue to using the same CA for both
the client and server part (client_ca and ca_certificate, server_ca).

However when you have a production environment you want to separate
the client_ca and ca_certificate/server_ca into to separate CAs.

This is because otherwise if one amphora is compromised it could use
its certificate to access all other amphoras.

This change is backward compatible since by setting the default value
for client_ca to undef the pick() function will select the
ca_certificate value by default.

Change-Id: I41de310daab5bf1bc623819df40dea61b852ffc9
This commit is contained in:
Tobias Urdin 2018-08-31 17:51:41 +02:00
parent e1531c3bcb
commit 2b83ae20f2
3 changed files with 96 additions and 1 deletions

View File

@ -32,6 +32,12 @@
# (Optional) CA password used to sign certificates
# Defaults to $::os_service_default
#
# [*client_ca*]
# (Optional) Path to the client CA certificate.
# This option is not needed unless you want to separate the
# ca_certificate/server_ca and the client_ca.
# Defaults to undef
#
# [*client_cert*]
# (Optional) Path for client certificate used to connect to amphorae.
# Defaults to $::os_service_default
@ -44,6 +50,12 @@
# (Optional) CA private key for signing certificates
# Defaults to undef
#
# [*client_ca_data*]
# (Optional) Client CA certificate.
# You must specify the client_ca parameter where to place this CA
# if you give the data here.
# Defaults to undef
#
# [*client_cert_data*]
# (Optional) Client certificate used for connecting to amphorae
# Defaults to undef
@ -64,9 +76,11 @@ class octavia::certificates (
$ca_certificate = $::os_service_default,
$ca_private_key = $::os_service_default,
$ca_private_key_passphrase = $::os_service_default,
$client_ca = undef,
$client_cert = $::os_service_default,
$ca_certificate_data = undef,
$ca_private_key_data = undef,
$client_ca_data = undef,
$client_cert_data = undef,
$file_permission_owner = 'octavia',
$file_permission_group = 'octavia'
@ -74,6 +88,8 @@ class octavia::certificates (
include ::octavia::deps
$client_ca_real = pick($client_ca, $ca_certificate)
octavia_config {
'certificates/cert_generator' : value => $cert_generator;
'certificates/cert_manager' : value => $cert_manager;
@ -82,7 +98,7 @@ class octavia::certificates (
'certificates/ca_certificate' : value => $ca_certificate;
'certificates/ca_private_key' : value => $ca_private_key;
'certificates/ca_private_key_passphrase' : value => $ca_private_key_passphrase;
'controller_worker/client_ca' : value => $ca_certificate;
'controller_worker/client_ca' : value => $client_ca_real;
'haproxy_amphora/client_cert' : value => $client_cert;
'haproxy_amphora/server_ca' : value => $ca_certificate;
}
@ -127,6 +143,22 @@ class octavia::certificates (
replace => true
}
}
if $client_ca and $client_ca_data {
ensure_resource('file', dirname($client_ca), {
ensure => directory,
owner => $file_permission_owner,
group => $file_permission_group,
mode => '0755'
})
file { $client_ca:
ensure => file,
content => $client_ca_data,
group => $file_permission_owner,
owner => $file_permission_group,
mode => '0755',
replace => true
}
}
if $client_cert_data {
if is_service_default($client_cert) {
fail('You must provide a path for storing the client certificate')

View File

@ -0,0 +1,6 @@
features:
- |
Added new parameter client_ca and client_data_data to octavia::certificates.
These can be used to separate the ca_certificate/server_ca and client_ca used
which is something you want to do in production environment to avoid a compromised
Amphora being able to connect to the other running amphoras.

View File

@ -206,6 +206,63 @@ describe 'octavia::certificates' do
end
end
context 'with ca_certificate and client_ca being different' do
let :params do
{
:ca_certificate => '/etc/octavia/ca.pem',
:client_ca => '/etc/octavia/client_ca.pem'
}
end
it 'should configure certificates' do
is_expected.to contain_octavia_config('certificates/ca_certificate').with_value('/etc/octavia/ca.pem')
is_expected.to contain_octavia_config('controller_worker/client_ca').with_value('/etc/octavia/client_ca.pem')
end
it 'should not populate certificate file' do
is_expected.not_to contain_file('/etc/octavia/client_ca.pem')
is_expected.not_to contain_file('/etc/octavia')
end
end
context 'with ca_certificate and client_ca being different and populate files' do
let :params do
{
:ca_certificate => '/etc/octavia/ca.pem',
:client_ca => '/etc/octavia/client_ca.pem',
:ca_certificate_data => 'my_ca_certificate',
:client_ca_data => 'my_client_ca'
}
end
it 'should configure certificates' do
is_expected.to contain_octavia_config('certificates/ca_certificate').with_value('/etc/octavia/ca.pem')
is_expected.to contain_octavia_config('controller_worker/client_ca').with_value('/etc/octavia/client_ca.pem')
end
it 'populates certificate files' do
is_expected.to contain_file('/etc/octavia/ca.pem').with({
'ensure' => 'file',
'owner' => 'octavia',
'group' => 'octavia',
'mode' => '0755',
})
is_expected.to contain_file('/etc/octavia/ca.pem').with_content('my_ca_certificate')
is_expected.to contain_file('/etc/octavia/client_ca.pem').with({
'ensure' => 'file',
'owner' => 'octavia',
'group' => 'octavia',
'mode' => '0755',
})
is_expected.to contain_file('/etc/octavia/client_ca.pem').with_content('my_client_ca')
is_expected.to contain_file('/etc/octavia').with({
'ensure' => 'directory',
'owner' => 'octavia',
'group' => 'octavia',
'mode' => '0755',
})
end
end
end
on_supported_os({