Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ group :development do
gem "puppet-module-win-dev-r#{minor_version}", '~> 0.4', require: false, platforms: [:mswin, :mingw, :x64_mingw]
end
group :system_tests do
gem "puppet-module-posix-system-r#{minor_version}", require: false, platforms: [:ruby]
gem "puppet-module-win-system-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw]
gem "puppet-module-posix-system-r#{minor_version}", '~> 0.5', require: false, platforms: [:ruby]
gem "puppet-module-win-system-r#{minor_version}", '~> 0.5', require: false, platforms: [:mswin, :mingw, :x64_mingw]
gem "nokogiri", require: false, platforms: [:ruby]
gem "serverspec", require: false, platforms: [:ruby]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/type/puppetdb_conn_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
end

newparam(:use_ssl) do
desc 'Whether the connection will be attemped using https'
desc 'Whether the connection will be attempted using https'
defaultto true
end

Expand Down
36 changes: 26 additions & 10 deletions manifests/database/postgresql.pp
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# Class for creating the PuppetDB postgresql database. See README.md for more
# information.
class puppetdb::database::postgresql(
$listen_addresses = $puppetdb::params::database_host,
$database_name = $puppetdb::params::database_name,
$database_username = $puppetdb::params::database_username,
$database_password = $puppetdb::params::database_password,
$database_port = $puppetdb::params::database_port,
$manage_database = $puppetdb::params::manage_database,
$manage_server = $puppetdb::params::manage_dbserver,
$manage_package_repo = $puppetdb::params::manage_pg_repo,
$postgres_version = $puppetdb::params::postgres_version,
$listen_addresses = $puppetdb::params::database_host,
$database_name = $puppetdb::params::database_name,
$database_username = $puppetdb::params::database_username,
$database_password = $puppetdb::params::database_password,
$database_port = $puppetdb::params::database_port,
$manage_database = $puppetdb::params::manage_database,
$manage_server = $puppetdb::params::manage_dbserver,
$manage_package_repo = $puppetdb::params::manage_pg_repo,
$postgres_version = $puppetdb::params::postgres_version,
$postgresql_ssl_on = $puppetdb::params::postgresql_ssl_on,
$postgresql_ssl_key_path = $puppetdb::params::postgresql_ssl_key_path,
$postgresql_ssl_cert_path = $puppetdb::params::postgresql_ssl_cert_path,
$postgresql_ssl_ca_cert_path = $puppetdb::params::postgresql_ssl_ca_cert_path
) inherits puppetdb::params {

if $manage_server {
Expand All @@ -24,6 +28,18 @@
port => scanf($database_port, '%i')[0],
}

# configure PostgreSQL communication with Puppet Agent SSL certificates if
# postgresql_ssl_on is set to true
if $postgresql_ssl_on {
class { 'puppetdb::database::ssl_configuration':
database_name => $database_name,
database_username => $database_username,
postgresql_ssl_key_path => $postgresql_ssl_key_path,
postgresql_ssl_cert_path => $postgresql_ssl_cert_path,
postgresql_ssl_ca_cert_path => $postgresql_ssl_ca_cert_path
}
}

# Only install pg_trgm extension, if database it is actually managed by the module
if $manage_database {

Expand All @@ -45,4 +61,4 @@
grant => 'all',
}
}
}
}
80 changes: 80 additions & 0 deletions manifests/database/ssl_configuration.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Class for configuring SSL connection for the PuppetDB postgresql database. See README.md for more
# information.
class puppetdb::database::ssl_configuration(
$database_name = $puppetdb::params::database_name,
$database_username = $puppetdb::params::database_username,
$postgresql_ssl_key_path = $puppetdb::params::postgresql_ssl_key_path,
$postgresql_ssl_cert_path = $puppetdb::params::postgresql_ssl_cert_path,
$postgresql_ssl_ca_cert_path = $puppetdb::params::postgresql_ssl_ca_cert_path
) inherits puppetdb::params {

file {'postgres private key':
ensure => present,
path => "${postgresql::server::datadir}/server.key",
source => $postgresql_ssl_key_path,
owner => 'postgres',
mode => '0600',
require => Package['postgresql-server'],
}

file {'postgres public key':
ensure => present,
path => "${postgresql::server::datadir}/server.crt",
source => $postgresql_ssl_cert_path,
owner => 'postgres',
mode => '0600',
require => Package['postgresql-server'],
}

postgresql::server::config_entry {'ssl':
ensure => present,
value => 'on',
require => [File['postgres private key'], File['postgres public key']]
}

postgresql::server::config_entry {'ssl_cert_file':
ensure => present,
value => "${postgresql::server::datadir}/server.crt",
require => [File['postgres private key'], File['postgres public key']]
}

postgresql::server::config_entry {'ssl_key_file':
ensure => present,
value => "${postgresql::server::datadir}/server.key",
require => [File['postgres private key'], File['postgres public key']]
}

postgresql::server::config_entry {'ssl_ca_file':
ensure => present,
value => $postgresql_ssl_ca_cert_path,
require => [File['postgres private key'], File['postgres public key']]
}

$identity_map_key = "${database_name}-${database_username}-map"

postgresql::server::pg_hba_rule { "Allow certificate mapped connections to ${database_name} as ${database_username} (ipv4)":
type => 'hostssl',
database => $database_name,
user => $database_username,
address => '0.0.0.0/0',
auth_method => 'cert',
order => 0,
auth_option => "map=${identity_map_key} clientcert=1"
}

postgresql::server::pg_hba_rule { "Allow certificate mapped connections to ${database_name} as ${database_username} (ipv6)":
type => 'hostssl',
database => $database_name,
user => $database_username,
address => '::0/0',
auth_method => 'cert',
order => 0,
auth_option => "map=${identity_map_key} clientcert=1"
}

postgresql::server::pg_ident_rule {"Map the SSL certificate of the server as a ${database_username} user":
map_name => $identity_map_key,
system_username => $::fqdn,
database_username => $database_username,
}
}
9 changes: 9 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@
$ssl_set_cert_paths = $puppetdb::params::ssl_set_cert_paths,
$ssl_cert_path = $puppetdb::params::ssl_cert_path,
$ssl_key_path = $puppetdb::params::ssl_key_path,
$ssl_key_pk8_path = $puppetdb::params::ssl_key_pk8_path,
$ssl_ca_cert_path = $puppetdb::params::ssl_ca_cert_path,
$ssl_deploy_certs = $puppetdb::params::ssl_deploy_certs,
$ssl_key = $puppetdb::params::ssl_key,
$ssl_cert = $puppetdb::params::ssl_cert,
$ssl_ca_cert = $puppetdb::params::ssl_ca_cert,
$ssl_protocols = $puppetdb::params::ssl_protocols,
$postgresql_ssl_on = $puppetdb::params::postgresql_ssl_on,
$postgresql_ssl_folder = $puppetdb::params::postgresql_ssl_folder,
$postgresql_ssl_cert_path = $puppetdb::params::postgresql_ssl_cert_path,
$postgresql_ssl_key_path = $puppetdb::params::postgresql_ssl_key_path,
$postgresql_ssl_ca_cert_path = $puppetdb::params::postgresql_ssl_ca_cert_path,
$cipher_suites = $puppetdb::params::cipher_suites,
$migrate = $puppetdb::params::migrate,
$manage_dbserver = $puppetdb::params::manage_dbserver,
Expand Down Expand Up @@ -98,12 +104,14 @@
ssl_set_cert_paths => $ssl_set_cert_paths,
ssl_cert_path => $ssl_cert_path,
ssl_key_path => $ssl_key_path,
ssl_key_pk8_path => $ssl_key_pk8_path,
ssl_ca_cert_path => $ssl_ca_cert_path,
ssl_deploy_certs => $ssl_deploy_certs,
ssl_key => $ssl_key,
ssl_cert => $ssl_cert,
ssl_ca_cert => $ssl_ca_cert,
ssl_protocols => $ssl_protocols,
postgresql_ssl_on => $postgresql_ssl_on,
cipher_suites => $cipher_suites,
migrate => $migrate,
database => $database,
Expand Down Expand Up @@ -183,6 +191,7 @@
manage_database => $manage_database,
manage_package_repo => $manage_package_repo,
postgres_version => $postgres_version,
postgresql_ssl_on => $postgresql_ssl_on,
before => $database_before
}
}
Expand Down
11 changes: 11 additions & 0 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@
$cleanup_timer_interval = "*-*-* ${fqdn_rand(24)}:${fqdn_rand(60)}:00"
$dlo_max_age = 90

# certificats used for PostgreSQL SSL configuration. Puppet certificates are used
$postgresql_ssl_on = false
$postgresql_ssl_folder = "${puppet_confdir}/ssl"
Comment thread
austb marked this conversation as resolved.
$postgresql_ssl_cert_path = "${postgresql_ssl_folder}/certs/${trusted['certname']}.pem"
$postgresql_ssl_key_path = "${postgresql_ssl_folder}/private_keys/${trusted['certname']}.pem"
$postgresql_ssl_ca_cert_path = "${postgresql_ssl_folder}/certs/ca.pem"

# certificats used for Jetty configuration
$ssl_set_cert_paths = false
$ssl_cert_path = "${ssl_dir}/public.pem"
$ssl_key_path = "${ssl_dir}/private.pem"
Expand All @@ -189,6 +197,9 @@
$ssl_cert = undef
$ssl_ca_cert = undef

# certificate used by PuppetDB SSL Configuration
$ssl_key_pk8_path = regsubst($ssl_key_path, '.pem', '.pk8')

$certificate_whitelist_file = "${etcdir}/certificate-whitelist"
# the default is free access for now
$certificate_whitelist = [ ]
Expand Down
30 changes: 30 additions & 0 deletions manifests/server.pp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
Boolean $ssl_set_cert_paths = $puppetdb::params::ssl_set_cert_paths,
Stdlib::Absolutepath $ssl_cert_path = $puppetdb::params::ssl_cert_path,
Stdlib::Absolutepath $ssl_key_path = $puppetdb::params::ssl_key_path,
Stdlib::Absolutepath $ssl_key_pk8_path = $puppetdb::params::ssl_key_pk8_path,
Stdlib::Absolutepath $ssl_ca_cert_path = $puppetdb::params::ssl_ca_cert_path,
Boolean $ssl_deploy_certs = $puppetdb::params::ssl_deploy_certs,
$ssl_key = $puppetdb::params::ssl_key,
$ssl_cert = $puppetdb::params::ssl_cert,
$ssl_ca_cert = $puppetdb::params::ssl_ca_cert,
$ssl_protocols = $puppetdb::params::ssl_protocols,
$postgresql_ssl_on = $puppetdb::params::postgresql_ssl_on,
$cipher_suites = $puppetdb::params::cipher_suites,
$migrate = $puppetdb::params::migrate,
$database = $puppetdb::params::database,
Expand Down Expand Up @@ -168,6 +170,10 @@
database_password => $database_password,
database_name => $database_name,
manage_db_password => $manage_db_password,
postgresql_ssl_on => $postgresql_ssl_on,
ssl_key_pk8_path => $ssl_key_pk8_path,
ssl_cert_path => $ssl_cert_path,
ssl_ca_cert_path => $ssl_ca_cert_path,
database_max_pool_size => $database_max_pool_size,
jdbc_ssl_properties => $jdbc_ssl_properties,
database_validate => $database_validate,
Expand Down Expand Up @@ -197,6 +203,10 @@
database_password => $read_database_password,
database_name => $read_database_name,
manage_db_password => $manage_read_db_password,
postgresql_ssl_on => $postgresql_ssl_on,
ssl_key_pk8_path => $ssl_key_pk8_path,
ssl_cert_path => $ssl_cert_path,
ssl_ca_cert_path => $ssl_ca_cert_path,
jdbc_ssl_properties => $read_database_jdbc_ssl_properties,
database_validate => $read_database_validate,
log_slow_statements => $read_log_slow_statements,
Expand Down Expand Up @@ -241,6 +251,26 @@
}
}

if $postgresql_ssl_on {
exec { $ssl_key_pk8_path:
path => [ '/opt/puppetlabs/puppet/bin', $facts['path'] ],
command => "openssl pkcs8 -topk8 -inform PEM -outform DER -in ${ssl_key_path} -out ${ssl_key_pk8_path} -nocrypt",
# Generate a .pk8 key if one doesn't exist or is older than the .pem input.
# NOTE: bash file time checks, like -ot, can't always discern sub-second
# differences.
onlyif => "test ! -e '${ssl_key_pk8_path}' -o '${ssl_key_pk8_path}' -ot '${ssl_key_path}'",
before => File[$ssl_key_pk8_path]
}

file { $ssl_key_pk8_path:
ensure => present,
owner => $puppetdb_user,
group => $puppetdb_group,
mode => '0600',
notify => Service[$puppetdb_service]
}
}

class { 'puppetdb::server::jetty':
listen_address => $listen_address,
listen_port => $listen_port,
Expand Down
22 changes: 21 additions & 1 deletion manifests/server/database.pp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
$puppetdb_group = $puppetdb::params::puppetdb_group,
$database_max_pool_size = $puppetdb::params::database_max_pool_size,
$migrate = $puppetdb::params::migrate,
$postgresql_ssl_on = $puppetdb::params::postgresql_ssl_on,
$ssl_cert_path = $puppetdb::params::ssl_cert_path,
$ssl_key_pk8_path = $puppetdb::params::ssl_key_pk8_path,
$ssl_ca_cert_path = $puppetdb::params::ssl_ca_cert_path
) inherits puppetdb::params {

if str2bool($database_validate) {
Expand Down Expand Up @@ -85,7 +89,23 @@
$database_suffix = ''
}

$subname = "//${database_host}:${database_port}/${database_name}${database_suffix}"
$subname_default = "//${database_host}:${database_port}/${database_name}${database_suffix}"
Comment thread
austb marked this conversation as resolved.

if $postgresql_ssl_on and !empty($jdbc_ssl_properties)
{
fail("Variables 'postgresql_ssl_on' and 'jdbc_ssl_properties' can not be used at the same time!")
}

if $postgresql_ssl_on {
$subname = @("EOT"/L)
${subname_default}?\
ssl=true&sslfactory=org.postgresql.ssl.LibPQFactory&\
sslmode=verify-full&sslrootcert=${ssl_ca_cert_path}&\
sslkey=${ssl_key_pk8_path}&sslcert=${ssl_cert_path}\
| EOT
} else {
$subname = $subname_default
}

##Only setup for postgres
ini_setting {'puppetdb_psdatabase_username':
Expand Down
22 changes: 21 additions & 1 deletion manifests/server/read_database.pp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
$puppetdb_user = $puppetdb::params::puppetdb_user,
$puppetdb_group = $puppetdb::params::puppetdb_group,
$database_max_pool_size = $puppetdb::params::read_database_max_pool_size,
$postgresql_ssl_on = $puppetdb::params::postgresql_ssl_on,
$ssl_cert_path = $puppetdb::params::ssl_cert_path,
$ssl_key_pk8_path = $puppetdb::params::ssl_key_pk8_path,
$ssl_ca_cert_path = $puppetdb::params::ssl_ca_cert_path
) inherits puppetdb::params {

# Only add the read database configuration if database host is defined.
Expand Down Expand Up @@ -73,7 +77,23 @@
$database_suffix = ''
}

$subname = "//${database_host}:${database_port}/${database_name}${database_suffix}"
$subname_default = "//${database_host}:${database_port}/${database_name}${database_suffix}"

if $postgresql_ssl_on and !empty($jdbc_ssl_properties)
{
fail("Variables 'postgresql_ssl_on' and 'jdbc_ssl_properties' can not be used at the same time!")
}

if $postgresql_ssl_on {
$subname = @("EOT"/L)
${subname_default}?\
ssl=true&sslfactory=org.postgresql.ssl.LibPQFactory&\
sslmode=verify-full&sslrootcert=${ssl_ca_cert_path}&\
sslkey=${ssl_key_pk8_path}&sslcert=${ssl_cert_path}\
| EOT
} else {
$subname = $subname_default
}

ini_setting { 'puppetdb_read_database_username':
setting => 'username',
Expand Down
32 changes: 32 additions & 0 deletions spec/acceptance/basic_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,38 @@ class { 'puppetdb::master::config': puppetdb_port => '8080', puppetdb_server =>
end
end

describe 'single node with ssl' do
ssl_config = <<-EOS
class { 'puppetdb': postgresql_ssl_on => true,
database_listen_address => '0.0.0.0',
database_host => $facts['fqdn'],}
EOS

it 'make sure it runs without error' do
apply_manifest(ssl_config, catch_errors: true)
apply_manifest(ssl_config, catch_changes: true)
end

change_password = <<-EOS
ini_setting { "puppetdb password":
ensure => present,
path => '/etc/puppetlabs/puppetdb/conf.d/database.ini',
section => 'database',
setting => 'password',
value => 'random_password',
notify => Service[puppetdb]
}

service { 'puppetdb':
ensure => 'running',
}
EOS
it 'make sure it starts with wrong password' do
apply_manifest(change_password, catch_errors: true)
apply_manifest(change_password, catch_changes: true)
end
end

describe 'enabling report processor' do
pp = <<-EOS
class { 'puppetdb': disable_ssl => true, } ->
Expand Down
Loading