This puppet module allows you to request and manage certificates using certmonger.
certmonger::request_ipa_cert { 'server-crt':
certfile => '/etc/pki/tls/certs/server.crt',
keyfile => '/etc/pki/tls/private/server.key',
}
Note: there is no need to use the certmonger
class, it gets included by the define and has no parameters of its own.
certfile
(required; String) - Full path of certificate to be managed by certmonger. e.g./path/to/certificate.crt
keyfile
(required; String) - Full path to private key file to be managed by certmonger. e.g./path/to/key.pem
keysize
(optional; String) - Generate keys with a specific keysize in bits. e.g.4096
hostname
(optional; String) - Hostname to use (appears in subject field of cert). e.g.webserver.example.com
principal
(optional; String) - IPA service principal certmonger should use when requesting cert. e.g.HTTP/webserver.example.com
.dns
(optional; String or Array) - DNS subjectAltNames to be present in the certificate request. Can be a string (use commas or spaces to separate values) or an array. e.g.ssl.example.com webserver01.example.com
e.g.ssl.example.com, webserver01.example.com
e.g.["ssl.example.com","webserver01.example.com"]
eku
(optional; String or Array) - Extended Key Usage attributes to be present in the certificate request. Can be a string (use commas or spaces to separate values) or an array. e.g.id-kp-clientAuth id-kp-serverAuth
e.g.id-kp-clientAuth, id-kp-serverAuth
e.g.["id-kp-clientAuth","id-kp-serverAuth"]
usage
(optional; String or Array) - Key Usage attributes to be present in the certificate request. Can be a string (use commas or spaces to separate values) or an array. e.g.digitalSignature nonRepudiation keyEncipherment
e.g.digitalSignature, nonRepudiation, keyEncipherment
e.g.["digitalSignature", "nonRepudiation", "keyEncipherment"]
presavecmd
(optional; String) - Command certmonger should run before saving the certificatepostsavecmd
(optional; String) - Command certmonger should run after saving the certificatekey_size
(optional; String) - Size for the key used to generate the certificatecacertfile
(optional; String) - Ask certmonger to save the CA's certificate to this path. eg./path/to/ca.crt
profile
(optional; String) - Ask the CA to process request using the named profile. e.g.caIPAserviceCert
issuer
(optional; String) - Ask the CA to process the request using the named issuer. e.g.ca-puppet
issuerdn
(optional; String) - If a specific issuer is needed, provide the issuer DN. e.g.CN=Puppet CA
- Submits a certificate request to an IPA server for a new certificate via
ipa-getcert
utility
- Changing the location of a
certfile
orkeyfile
can't be done usingipa-getcert resubmit
, which means this module will take a more aggressive approach, i.e. it will stop tracking the existing cert, delete the key/certfile and submit a brand new request. If the new request fails, bad luck, the old files are gone.
A notable limitation of ipa-getcert
is that the postsavecmd
can only take a single command. This means changing file ownership/modes and restarting services requires the use of a separate helper utility. This module includes a creatively named script called change-perms-restart
, which gets installed by the certmonger
class as /usr/local/bin/change-perms-restart
. Usage is as follows:
/usr/local/bin/change-perms-restart [-R] [ -r 'service1 service2' ] [ -t 'service3 service4' ] [ -T 'TIMESPEC' ] [ -s facility.severity ] owner:group:modes:/path/to/file [ ... ]
-R change ownership/group/modes recursively (e.g. when specifying a folder)
-r space separated list of services to reload via systemctl
-t space separated list of services to restart via systemctl
-T systemd oncalendar timespec. If specified, will delay the restart using a one-time systemd timer via systemd-run.
-s log output (if any) to syslog with specified facility/severity
For example: change-perms-restart -R -s daemon.notice -r 'httpd rsyslog' -t 'postfix postgresql' -T '02:00:00' root:pkiuser:0644:/etc/pki/tls/certs/localhost.crt root:pkiuser:0600:/etc/pki/tls/private/localhost.key
- The current state is determined by calling a custom shell script (supplied). Not ideal, I know.
- Only supports file-based certificates (i.e. no support for NSSDB).
- Does not manage the nickname, IP address, email, etc features.
- Only manages subject, dns (subjectAltNames), key usage, eku, principal, issuer, pre/post save commands.
- Only manages the principal if it appears in the issued certificate - which depends on your CA profile.
- Once a certificate is issued, this module can't manage the profile because it doesn't appear in the issued certificate.
- This module won't re-generate keys if you set or change
keysize
of an existing certificate. - This module won't resubmit the request if the only thing changed is the
cacertfile
parameter. - Subject is hardcoded to
CN=$hostname
. - Only works if being run on a system already joined to an IPA domain, and only works against IPA CAs.
- If you specify a hostname and don't specify a principal, this module will assume you want
host/$hostname
. This is needed becauseipa-getcert
requires a principal if being passed a subject. - If you don't specify an optional parameter (eg, if you dont supply
$dns
), this module will not touch that parameter of the existing request, even if the request has a value for that parameter present. - The
title
ornamevar
of the define doesn't get used - everything revolves aroundcertfile
. - This module won't fix SELinux AVC denials: make sure certmonger can read/write to the location of
certfile
andkeyfile
. - This module won't attempt to add service principals in IPA if they don't exist. You may need to do this manually.
- Certmonger needs to manage
keyfile
andcertfile
, which means you shouldn't create them yourself, but you can change their ownership/permissions once they've been created (e.g. viapostsavecmd
or via a file resource in another puppet manifest). See example below on how to use the suppliedchange-perms-restart
script to achieve this and restart httpd as one command. - Tested only on CentOS 7.
certmonger::request_ipa_cert {'webserver-certificate':
hostname => "${fqdn}",
principal => "HTTP/${fqdn}",
keyfile => "/etc/pki/tls/private/server.key",
certfile => "/etc/pki/tls/certs/server.crt",
dns => ['vhost1.example.com','vhost2.example.com'],
postsavecmd => "/usr/local/bin/change-perms-restart -s daemon.notice -r httpd root:pkiuser:0640:/etc/pki/tls/private/server.key root:pkiuser:0644:/etc/pki/tls/certs/server.crt",
}
This will create a certificate request with the given hostname (which will be used in the subject as the CN) and the given principal. It will use the key specified by 'keyfile'. And if it succeeds it will track the certificate where 'certfile' specifies the resource to do so.
certmonger_certificate { 'my-cert':
ensure => 'present',
ca => 'IPA'
certfile => '/path/to/certs/my-cert.pem',
keyfile => '/path/to/certs/my-key.pem',
key_size => '3076',
hostname => 'hostname.example.com'
principal => 'HTTP/hostname.example.com',
}
If the certificate already exists it will simply take the values and add it to the resource catalog. However, you can tell the provider to resubmit the certificate if it already exists. This is done by setting the 'force_resubmit' flag. Currently the aforementioned flag is needed if the parameters for the request have changed and you wish to resubmit it.
If, for some reason, the CA rejects your request, you can still see the certificate resource, and the status will reflect the rejection. So, when viewing the resource, you'll see the following:
certmonger_certificate { 'my-cert':
ensure => 'present',
ca => 'local'
certbackend => 'FILE',
certfile => '/path/to/certs/my-cert.pem',
key_size => 'KEY_SIZE_VALUE',
keybackend => 'FILE',
keyfile => '/path/to/certs/my-key.pem',
status => 'CA_REJECTED',
}
The default behavior is to throw an error if the CA rejects the request. But errors can be ignored with the 'ignore_ca_errors' parameter.
One can also automatically stop tracking the certificate request if it's rejected by the CA. This is done by setting the 'cleanup_on_error' flag.
- The native type/provider isn't as mature as the defined type, which means its parameters/properties are likely change in a non-backward compatible way.
- The defined type is very mature - its parameters are unlikely to change, and if they do, those changes will be backward-compatible.
- If you're using IPA and are having trouble with the native type/provider, try switching to the defined type.
- Fork it
- Create a topic branch
- Make your changes
- Submit a PR
This module is brought to you by Salted Signal - a Melbourne-based cloud automation, DevSecOps, security and compliance company.
Honorable mentions go out to:
- Rob Crittenden for his work on https://github.com/rcritten/puppet-certmonger, which was used as inspiration for this module.
- Juan Antonio Osorio for his work on the certmonger type/provider and setting up rpsec tests/travis-ci integration.
- Alex J Fisher for fixing rubocop violations
- Ewoud Kohl van Wijngaarden for implementing Puppet 4 types and contributing tests for the defined type.