diff --git a/.gitignore b/.gitignore index 133e989c..26f3a7e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .vagrant *.swp *.swo +.*.sw? .bundle vendor/ @@ -12,5 +13,6 @@ Gemfile.lock .rbenv* .rvmrc* .ruby-version +.ruby-gemset spec/fixtures/ diff --git a/manifests/gutterball.pp b/manifests/gutterball.pp new file mode 100644 index 00000000..f28b4f77 --- /dev/null +++ b/manifests/gutterball.pp @@ -0,0 +1,92 @@ +# Constains certs specific configurations for gutterball +class certs::gutterball( + + $hostname = $::certs::node_fqdn, + $generate = $::certs::generate, + $regenerate = $::certs::regenerate, + $deploy = $::certs::deploy, + $pki_dir = $::certs::pki_dir, + $password_file = $::certs::gutterball_keystore_password_file, + $amqp_truststore = $::certs::gutterball_amqp_truststore, + $amqp_keystore = $::certs::gutterball_amqp_keystore, + $amqp_store_dir = $::certs::gutterball_amqp_store_dir, + +) inherits certs::params { + $keystore_alias = 'gutterball' + $ca_key = $::certs::ca_key + $ca = $::certs::ca_cert_stripped + $key = "${::certs::gutterball_certs_dir}/gutterball.key" + $cert = "${::certs::gutterball_certs_dir}/gutterball.crt" + + $gutterball_keystore_password = cache_data('gutterball_keystore_password', random_password(32)) + + $keypair= 'gutterball-certs' + + cert { $keypair: + ensure => present, + hostname => $hostname, + country => $::certs::country, + state => $::certs::state, + city => $::certs::sity, + org => 'gutterball', + org_unit => $::certs::org_unit, + expiration => $::certs::expiration, + ca => $::certs::default_ca, + generate => $generate, + regenerate => $regenerate, + deploy => $deploy, + password_file => $certs::ca_key_password_file, + } + if $deploy { + file { $certs::gutterball_certs_dir: + ensure => directory, + owner => 'tomcat', + group => $::certs::group, + mode => '0755', + } -> + Cert[$keypair] ~> + privkey { $key: + key_pair => Cert[$keypair] + } ~> + pubkey { $cert: + key_pair => Cert[$keypair] + } -> + file { $password_file: + ensure => file, + content => $gutterball_keystore_password, + owner => $certs::user, + group => $certs::group, + mode => '0440', + } ~> + certs::ssltools::certutil{ 'guterball-amqp-client': + nss_db_dir => $::certs::nss_db_dir, + client_cert => $cert, + } ~> + file { $amqp_store_dir: + ensure => directory, + owner => 'tomcat', + group => $::certs::group, + mode => '0750', + } ~> + certs::ssltools::keytool::import_ca { 'import CA into gutterball truststore': + keystore => $amqp_truststore, + password => $gutterball_keystore_password, + keystore_alias => $keystore_alias, + file => $ca + } ~> + certs::ssltools::keytool::import_keypair{ 'import client certificate into gutterball keystore': + keystore_alias => $keystore_alias, + keystore => $amqp_keystore, + keystore_password => $gutterball_keystore_password, + cert => $cert, + key => $key, + tmp_password_file => $password_file + } ~> + file { $amqp_keystore: + ensure => file, + owner => 'tomcat', + group => $::certs::group, + mode => '0640', + } + } +} diff --git a/manifests/params.pp b/manifests/params.pp index 267b58b6..757e8a5f 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -20,7 +20,6 @@ $custom_repo = false $ca_common_name = $::fqdn # we need fqdn as CA common name as candlepin uses it as a ssl cert - $generate = true $regenerate = false $regenerate_ca = false @@ -72,6 +71,12 @@ $candlepin_amqp_keystore = "${candlepin_amqp_store_dir}/candlepin.jks" $candlepin_qpid_exchange = 'event' + $gutterball_certs_dir = '/etc/gutterball/certs' + $gutterball_amqp_store_dir = "${gutterball_certs_dir}/amqp/" + $gutterball_amqp_truststore = "${gutterball_amqp_store_dir}/gutterball.truststore" + $gutterball_amqp_keystore = "${gutterball_amqp_store_dir}/gutterball.jks" + $gutterball_keystore_password_file = "${pki_dir}/keystore_password-file-gutterball" + $certs_tar = undef # Settings for uploading packages to Katello $katello_user = undef diff --git a/manifests/ssltools/certutil.pp b/manifests/ssltools/certutil.pp new file mode 100644 index 00000000..f5d3af07 --- /dev/null +++ b/manifests/ssltools/certutil.pp @@ -0,0 +1,18 @@ +# type to append cert to nssdb +define certs::ssltools::certutil($nss_db_dir, $client_cert, $cert_name=$title, $refreshonly = true) { + file { $client_cert: + ensure => present + } -> + exec { "delete ${cert_name}": + path => ['/bin', '/usr/bin'], + unless => "certutil -D -d ${nss_db_dir} -n '${cert_name}'", + onlyif => "certutil -L -d ${nss_db_dir} | grep '${cert_name}'", + refreshonly => $refreshonly, + } -> + exec { $cert_name: + path => ['/bin', '/usr/bin'], + command => "certutil -A -d '${nss_db_dir}' -n '${cert_name}' -t ',,' -a -i '${client_cert}'", + unless => "certutil -L -d ${nss_db_dir} | grep '${cert_name}'", + refreshonly => $refreshonly, + } +} diff --git a/manifests/ssltools/keytool/convert_pkcs12_to_jks.pp b/manifests/ssltools/keytool/convert_pkcs12_to_jks.pp new file mode 100644 index 00000000..e0365ce6 --- /dev/null +++ b/manifests/ssltools/keytool/convert_pkcs12_to_jks.pp @@ -0,0 +1,8 @@ +# Convert a pkcs12 key pair to a java keystore +define certs::ssltools::keytool::convert_pkcs12_to_jks( $keystore_alias, $dest_keystore, $src_keystore, $keystore_password, $src_keystore_password, $refreshonly = false){ + exec { $title: + command => "keytool -importkeystore -destkeystore ${dest_keystore} -srckeystore ${src_keystore} -srcstoretype pkcs12 -alias ${keystore_alias} -storepass ${keystore_password} -srcstorepass ${src_keystore_password} -noprompt", + path => ['/bin/', '/usr/bin'], + refreshonly => $refreshonly, + } +} diff --git a/manifests/ssltools/keytool/import_ca.pp b/manifests/ssltools/keytool/import_ca.pp new file mode 100644 index 00000000..9b698929 --- /dev/null +++ b/manifests/ssltools/keytool/import_ca.pp @@ -0,0 +1,8 @@ +# Imports a ca into a keystore +define certs::ssltools::keytool::import_ca($keystore, $password, $keystore_alias, $file){ + exec { $title: + command => "keytool -import -v -keystore ${keystore} -storepass ${password} -alias ${keystore_alias} -file ${file} -noprompt", + creates => $keystore, + path => ['/bin/', '/usr/bin'] + } +} diff --git a/manifests/ssltools/keytool/import_keypair.pp b/manifests/ssltools/keytool/import_keypair.pp new file mode 100644 index 00000000..28d67e53 --- /dev/null +++ b/manifests/ssltools/keytool/import_keypair.pp @@ -0,0 +1,30 @@ +# import a x509 keypair into a jks +define certs::ssltools::keytool::import_keypair($keystore_alias, $keystore, $keystore_password, $cert, $key, $tmp_password_file){ + # Stupid keytool doesn't allow you to import a keypair. You can only import a cert. Hence, we have to + # create the store as an PKCS12 and convert to JKS. See http://stackoverflow.com/a/8224863 + + $tmpkeystore = "/tmp/${keystore_alias}keystore.p12" + exec{ "[${title}] signal import if pair has not been imported": + command => 'echo importing keypair', + unless => "keytool -list -keystore ${keystore} -storepass ${keystore_password} -alias ${keystore_alias}", + path => ['/bin/', '/usr/bin'], + } ~> + certs::ssltools::openssl::pkcs12{ "[${title}] convert x509 cert and key to pkcs12": + cert_name => $keystore_alias, + ca_cert => $cert, + ca_name => 'root', + ca_key => $key, + keystore_out => $tmpkeystore, + password_out => $tmp_password_file, + password_in => $keystore_password, + refreshonly => true, + } -> + convert_pkcs12_to_jks{ "[${title}] convert tmp pkcs12 keystore to jks": + keystore_alias => $keystore_alias, + dest_keystore => $keystore, + src_keystore => $tmpkeystore, + keystore_password => $keystore_password, + src_keystore_password => $keystore_password, + refreshonly => true, + } +} diff --git a/manifests/ssltools/openssl/pkcs12.pp b/manifests/ssltools/openssl/pkcs12.pp new file mode 100644 index 00000000..5a40003d --- /dev/null +++ b/manifests/ssltools/openssl/pkcs12.pp @@ -0,0 +1,14 @@ +# type that coresponds the openssl pkcs12 subcommand +define certs::ssltools::openssl::pkcs12 ( $cert_name, $ca_cert, $ca_key, $ca_name, $keystore_out, $password_out, $password_in = undef, $refreshonly = false) { + $password_in_options = $password_in ? { + undef => '', + default => "-passin \"pass:${password_in}\"", + } + exec { $title: + command => "openssl pkcs12 -export -in ${ca_cert} -inkey ${ca_key} -out ${keystore_out} -name ${cert_name} -CAfile ${ca_cert} -caname ${ca_name} -password \"file:${password_out}\" ${password_in_options}", + creates => $keystore_out, + refreshonly => $refreshonly, + path => ['/bin/', '/usr/bin'], + logoutput => true, + } +}