dehydrated
Version information
This version is compatible with:
- Puppet Enterprise 2018.1.x, 2017.3.x, 2017.2.x, 2017.1.x, 2016.5.x, 2016.4.x
- Puppet >= 4.7.0 < 6.0.0
- , , , , , , , ,
Start using this module
Add this module to your Puppetfile:
mod 'bzed-dehydrated', '0.1.5'
Learn more about managing modules with a PuppetfileDocumentation
dehydrated
Centralized CSR signing using Let’s Encrypt™ - keeping your keys safe on the host they belong to.
Table of Contents
- Description
- Setup - The basics of getting started with dehydrated
- Usage - Configuration options and additional functionality
- Migrating from bzed-letsencrypt
- Limitations - OS compatibility, etc.
- Development - Guide for contributing to the module
Description
bzed-dehydrated creates private keys and CSRs, transfers the CSR to a central host (for example your puppetmaster) where it is signed using the well known dehydrated https://github.com/lukas2511/dehydrated
Signed certificates are shipped back to the requesting host.
You need to provide an appropriate hook script for dehydrated. The default is to use the DNS-01 challenge, but if your hook supports it you could also create the necessary files for http-01.
Let’s Encrypt is a trademark of the Internet Security Research Group. All rights reserved.
Deprecation of bzed-letsencrypt
With the release of bzed-dehydrated my old module bzed-letsencrypt will be depricated. Renaming the module to avoid trademark related troubles is one of the reasons for a new module, the other is that I did not want to break the API for all users of the old module. If there is enough interest I'll change bzed-letsencrypt to become a wrapper around the new module, but with all the new features and options I don't think that makes much sense. So I'm sorry for the extra trouble of migrating an existing installation (to make it easier, see below), but I hope that the extra amount of flexibility and less hacks in the code make it worth to migrate.
Setup
What dehydrated affects
dehydrated needs to use facter to retrieve the signed certificates and other data from your central signing hosts if you are not using a puppet master host to handle it. Although only certificates which need to be renewed are transferred, it is unknown how well this approach scales if you plan to request lots of certificates. Using a (designated) puppet master is the better option.
Setup Requirements
You need to ensure that exported ressources are working and pluginsync is enabled.
Beginning with dehydrated
Basic things you need:
- a host with internet access, preferable a puppet master. This will be known as dehydrated_host now.
- a working hook script for dehydrated, for exampes and documentation see lukas2511/dehydrated
- bzed-dehydrated installed as dehydrated module in your Puppet environment. You will also need recent versions of puppetlabs-stdlib, puppetlabs-concat, puppetlabs-vcsrepo. For puppet >= 6.0 you'll also need puppetlabs-cron_core.
- I'd assume at least puppet version 4.8. Not tested or developed for older version.
- Working exportable ressources. Make sure your puppetdb is working well, this module heavily depends on it.
Usage
This only describes the very basic usage. Almost all things are configurable, see the reference for details. So for a basic setup, the following steps should give you a running setup.
- Do a basic setup of your dehydrated_host:
class { 'dehydrated' : dehydrated_host => 'your.dehydrated.host.example.com', }
- As example we'll use the dehydrated hook for Cloudflare®. Take socram8888/dehydrated-hook-cloudflare and on your dehydrated_host install it into /opt/dehydrated/hooks.d/dns-01.sh
- Add the hook configuration to your config from above: class { 'dehydrated' : dehydrated_host => 'your.dehydrated.host.example.com', dehydrated_environment => { 'CF_EMAIL' => 'your@email.address', 'CF_KEY' => 'your-long-Cloudflare-api-key', } }
- On the host that needs a new certificate, add this to your puppet code: class { 'dehydrated' : dehydrated_host => 'your.dehydrated.host.example.com', challengetype => 'dns-01', } ::dehydrated::certificate { 'my-https-host.example.com' : subject_alternative_names => [ 'example.com', 'host2.example.com' ], }
- Wait.... it will take a few puppet runs until your certificate will appear. The certificates will be requestd by a cronjob, not directly from puppet. Otherwise puppet runs will take way too much time.
Using hiera
To use hiera, make sure you include your dehdrated class somewhere. As default configuration for all hosts setup the defaults, in this case we are using dehydrated in the way to be compatible to the old bzed-letsencrypt setup:
dehydrated::dehydrated_host: 'my.dehydrated.host'
dehydrated::base_dir: '/etc/letsencrypt'
dehydrated::group: 'letsencrypt'
dehydrated::letsencrypt_ca: 'v2-production'
dehydrated::challengetype: 'dns-01'
dehydrated::dehydrated_hook: 'tophosting_hook.py'
dehydrated::dehydrated_domain_validation_hook: 'domain_validation_hook.sh'
And to request certificates:
dehydrated::certificates:
- "*.subdomain.example.com"
- "subdomain.example.com"
- - "san.example.com"
- [ "second_domain.san.example.com", "third_domain.san.example.com" ]
With the yaml snippet above you'd request the following certificates:
- wildcard certificate *.subdomain.example.com
- "normal" certificate subdomain.example.com
- SAN certificate san.example.com with second_domain.san.example.com and third_domain.san.example.com as subject alternative names.
Monitoring & debugging
- usual Puppet debugging rules apply >:-)
- you'll find the output and errors from the last cronjob run in /opt/dehydrated/status.json. Unfortunately proper logging and maybe a better error handling is not implemented yet. Pull requests are welcome :-)
- monitoring the cronjob results is possible by using check_statusfile. On Debian and derivates
this is available in the nagios-plugins-contrib package. Or find the source here: check_statusfile
# /usr/lib/nagios/plugins/check_statusfile /opt/dehydrated/monitoring.status dehydrated certificates: OK: 2, FAILED: 1 foo.example.com (from bar.example.com): OCSP update failed
Migrating from bzed-letsencrypt
If you were using the bzed-letsencrypt module before, I'd suggest to use the following settings on the hosts that request certificates:
class { 'dehydrated' :
group => 'letsencrypt',
base_dir => '/etc/letsencrypt',
}
Migrating the files on the dehydrated_host (former letsencrypt_host) is a harder task and not implemented. A new setup or manual migration is preferred.
Reference
An html version of the reference is available here: https://bzed.github.io/bzed-dehydrated/ There is also a markdown version in REFERENCE.md
Monitoring
The cron-triggered dehydrated worker creates a status file in a format compatible with check_statusfile, which is - in Debian and derivates - packaged in the nagios-plugins-contrib package. If you ar enot using Debian you can retrieve the source code here: check_statusfile
Limitations
Don't forget that Let’s Encrypt limits apply! Also: this code might not work for your use-case out of the box, please test it properly against the Let’s Encrypt testing CA instead of running into the limit for failed authorizations and blaiming me for it ;)
Development
Please use the github issue tracker and send pull requests. Make sure that your pull requests keep travis happy!
For a release:
-
Update gh_pages:
bundle exec rake strings:gh_pages:update
-
Update REFERENCE.md:
puppet strings generate --format markdown --out REFERENCE.md
-
Create changelog:
bundle exec rake changelog
-
Release:
pdk build
-
Bump version number: bump/change the version in metadata.json.
Reference
Table of Contents
Classes
Public Classes
dehydrated
: Base class to define necessary variables and include setup classes.dehydrated::params
:dehydrated::setup::dehydrated_host
:
Private Classes
dehydrated::setup
: Setup required files and folders. Don't include/call this class.
Defined types
Public Defined types
dehydrated::certificate
: Creates key & csr and deploys the certificate.
Private Defined types
dehydrated::certificate::collect
: A short summary of the purpose of this defined type.dehydrated::certificate::csr
: Creates a key file with CSRdehydrated::certificate::deploy
: Deploy collected certificate and CA files.dehydrated::certificate::dh
: Create the DH params file.dehydrated::certificate::request
: Prepare everything to request a certifificate for our CSRs.dehydrated::certificate::transfer
: Transfer crt/ca/ocsp files.
Resource types
dehydrated_csr
: CSRs for dehydrateddehydrated_dhparam
: DH params for dehydrateddehydrated_key
: Create a private key for dehydrated.
Functions
Classes
dehydrated
Base class to setup the letsencrypt certificate handling with dehydrated.
Examples
# should be sufficient in most cases.
include dehydrated
# if you are "upgrading" from bzed-letsencrypt,
# you might want to use these options to stay
# compatible with the old group/directory:
class { 'dehydrated' :
group => 'letsencrypt',
base_dir => '/etc/letsencrypt',
}
Parameters
The following parameters are available in the dehydrated
class.
base_dir
Data type: Stdlib::Absolutepath
The base directory where keys/csr/certs are stored. Defaults to:
- on $::os['family']=='Debian': /etc/dehydrated
- on other Linux/Unix systems: /etc/pki/dehydrated
- on windows: C:\LE_certs.
Default value: $::dehydrated::params::base_dir
crt_dir
Data type: Stdlib::Absolutepath
The directory where certificates are stored. Defaults to ${base_dir}/certs
Default value: join([$base_dir, 'certs'], $::dehydrated::params::path_seperator)
csr_dir
Data type: Stdlib::Absolutepath
The directory where CSRs are stored. Defaults to ${base_dir}/csr
Default value: join([$base_dir, 'csr'], $::dehydrated::params::path_seperator)
key_dir
Data type: Stdlib::Absolutepath
The directory where pricate keys are stored. Defaults to ${base_dir}/private
Default value: join([$base_dir, 'private'], $::dehydrated::params::path_seperator)
user
Data type: String
The user who owns the files in /etc/dehydrated.
Default value: $::dehydrated::params::user
group
Data type: Optional[String]
The group which owns the files in /etc/dehydrated. If you have a non-root process which needs to access private keys, add its user to this group.
Default value: $::dehydrated::params::group
dehydrated_user
Data type: Optional[String]
User to run the dehydrated script as. Only used on the host that actually requests certificates.
Default value: $::dehydrated::params::dehydrated_user
dehydrated_group
Data type: Optional[String]
Group to run the dehydrated script as. Only used on the host that actually requests certificates.
Default value: $::dehydrated::params::dehydrated_group
letsencrypt_ca
Data type: String
Let’s Encrypt CA to use. Defaults to v2-production. See the letsencrypt_cas parameter for a way to specify your own Let’s Encrypt / ACME compatible CA. This configures the default CA to use, but You can actually define different CAs for each certificate, see the ::dehydrated::certificate define for details.
Default value: $::dehydrated::params::letsencrypt_ca
letsencrypt_cas
Data type: Hash
Hash with the definitions of the official testing and production Let’s Encrypt CAs this puppet module was tested against.
Default value: $::dehydrated::params::letsencrypt_cas
dh_param_size
Data type: Integer[768]
Default size of the DH params we should generate. Defaults to 2048.
Default value: $::dehydrated::params::dh_param_size
challengetype
Data type: Dehydrated::Challengetype
Default challengetype to use. Defaults to 'dns-01'. You can specify a different challengetype for each certificate, see ::dehydrated::certificate.
Default value: $::dehydrated::params::challengetype
algorithm
Data type: Dehydrated::Algorithm
Default algorithm / elliptic-curve you want to use. Supported: rsa, secp384r1, prime256v1. Defaults to rsa. You can specify a different algorithm for each certificate, see ::dehydrated::certificate.
Default value: $::dehydrated::params::algorithm
dehydrated_base_dir
Data type: Stdlib::Absolutepath
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host. Path where the dehydrated script and configurations/csrs are being stored. Defaults to '/opt/dehydrated'.
Default value: $::dehydrated::params::dehydrated_base_dir
dehydrated_git_dir
Data type: Stdlib::Absolutepath
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host. Path where the dehydrated script is being checkout out into using git. Defaults to ${dehydrated_base_dir}/dehydrated.
Default value: "${dehydrated_base_dir}/dehydrated"
dehydrated_git_tag
Data type: String
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host. Version of the dehydrated script we want to use. Change it on your own risk.
Default value: $::dehydrated::params::dehydrated_git_tag
dehydrated_git_url
Data type: Dehydrated::GitUrl
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host. Git url to clone dehydrated from. If you have an internal mirror/version, you can override the default github url here.
Default value: $::dehydrated::params::dehydrated_git_url
dehydrated_host
Data type: Stdlib::Fqdn
Default setting for the host you want to request the certificates on. Required on that host, on all others it is used as default for certificates requested via ::dehydrated::certificate. You can specify a different dehydrated_host on each certificate if you want to. If $facts['fqdn'] == $::dehydrated::dehydrated_host, dehydrated will be installed and the certificate request cronjob will be setup.
Default value: $::dehydrated::params::dehydrated_host
dehydrated_requests_dir
Data type: Stdlib::Absolutepath
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host. Path where requests that need to be handled are being stored.
Default value: "${dehydrated_base_dir}/requests"
dehydrated_hooks_dir
Data type: Stdlib::Absolutepath
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host.
Default value: "${dehydrated_base_dir}/hooks"
dehydrated_requests_config
Data type: Stdlib::Absolutepath
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host.
Default value: "${dehydrated_base_dir}/requests.json"
dehydrated_wellknown_dir
Data type: Stdlib::Absolutepath
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host.
Default value: "${dehydrated_base_dir}/acme-challenges"
dehydrated_alpncert_dir
Data type: Stdlib::Absolutepath
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host.
Default value: "${dehydrated_base_dir}/alpn-certs"
dehydrated_host_packages
Data type: Array
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host.
Default value: $::dehydrated::params::dehydrated_host_packages
dehydrated_environment
Data type: Hash
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host.
Default value: $::dehydrated::params::dehydrated_environment
dehydrated_domain_validation_hook
Data type: Optional[Dehydrated::Hook]
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host.
Default value: $::dehydrated::params::dehydrated_domain_validation_hook
dehydrated_hook
Data type: Dehydrated::Hook
Only used if $facts['fqdn'] == $::dehydrated::dehydrated_host. Name of the hook script dehydrated will use to validate the authorization request. The hook script must live in the $dehydrated_hooks_dir directory.
Default value: "${challengetype}.sh"
dehydrated_contact_email
Data type: Optional[Dehydrated::Email]
Contact email address for created accounts. We'll create one account for each puppet host.
Default value: $::dehydrated::params::dehydrated_contact_email
dehydrated_status_file
Data type: Stdlib::Absolutepath
File the dehydrated job runner will dump its status into. Pretty printed JSON.
Default value: "${dehydrated_base_dir}/status.json"
dehydrated_monitoring_status_file
Data type: Stdlib::Absolutepath
Status file for monitoring with check_statusfile, see README.md for details.
Default value: "${dehydrated_base_dir}/monitoring.status"
manage_user
Data type: Boolean
Create $dehydrated_user/$dehydrated_group and $user/$group if necessary.
Default value: $::dehydrated::params::manage_user
manage_packages
Data type: Boolean
Install required packages using ensure_packages? Should be safe to leave enabled in most cases.
Default value: $::dehydrated::params::manage_packages
pki_packages
Data type: Array
Required packages to create /etc/pki. Not really used yet.
Default value: $::dehydrated::params::pki_packages
packages
Data type: Array
The list of packages we actually need to install to make this module work properly. You are free to modify this list if you need to.
Default value: $::dehydrated::params::packages
certificates
Data type: Array[Variant[Dehydrated::DN, Tuple[Dehydrated::DN, Array[Dehydrated::DN]]]]
Default value: []
dehydrated::params
The dehydrated::params class.
dehydrated::setup::dehydrated_host
The dehydrated::setup::dehydrated_host class.
Defined types
dehydrated::certificate
Triggers key and csr generation and installs the certificate
Examples
dehydrated::certificate { 'test.example.com': }
Parameters
The following parameters are available in the dehydrated::certificate
defined type.
dn
Data type: Dehydrated::DN
Default value: $name
base_filename
Data type: String
Default value: regsubst($dn, '^*', 'wildcard')
subject_alternative_names
Data type: Array[Dehydrated::DN]
Default value: []
challengetype
Data type: Dehydrated::Challengetype
Default value: $::dehydrated::challengetype
algorithm
Data type: Dehydrated::Algorithm
Default value: $::dehydrated::algorithm
dh_param_size
Data type: Integer[768]
Default value: $::dehydrated::dh_param_size
dehydrated_host
Data type: Stdlib::Fqdn
Default value: $::dehydrated::dehydrated_host
dehydrated_environment
Data type: Hash
Default value: $::dehydrated::dehydrated_environment
dehydrated_hook
Data type: Dehydrated::Hook
Default value: $::dehydrated::dehydrated_hook
letsencrypt_ca
Data type: String
Default value: $::dehydrated::letsencrypt_ca
dehydrated_domain_validation_hook
Data type: Optional[Dehydrated::Hook]
Default value: $::dehydrated::dehydrated_domain_validation_hook
key_password
Data type: Optional[String]
Default value: undef
Resource types
dehydrated_csr
CSRs for dehydrated
Properties
The following properties are available in the dehydrated_csr
type.
ensure
Valid values: present, absent
The basic property that the resource should be in.
Default value: present
Parameters
The following parameters are available in the dehydrated_csr
type.
path
force
Valid values: true
, false
Whether to replace the certificate if the private key or CommonName/SANs mismatches
Default value: false
password
The optional password for the private key
private_key
algorithm
Valid values: prime256v1, secp384r1, rsa
The algorithm to use, supported: rsa, secp384r1, prime256v1
Default value: rsa
common_name
The common name for the csr
digest
Digest used while signing the CSR, defaults to SHA512
Default value: SHA512
subject_alternative_names
SANs to request
Default value: []
country
country part of the certificate name
locality
locality part of the certificate name
organization
locality part of the certificate name
state
state part of the certificate name
organizational_unit
organizational_unit part of the certificate name
email_address
emailAddress part of the certificate name
dehydrated_dhparam
DH params for dehydrated
Properties
The following properties are available in the dehydrated_dhparam
type.
ensure
Valid values: present, absent
The basic property that the resource should be in.
Default value: present
Parameters
The following parameters are available in the dehydrated_dhparam
type.
path
size
The key size
Default value: 2048
dehydrated_key
Create a private key for dehydrated.
Properties
The following properties are available in the dehydrated_key
type.
ensure
Valid values: present, absent
The basic property that the resource should be in.
Default value: present
Parameters
The following parameters are available in the dehydrated_key
type.
path
Key location, must be absolute.
algorithm
Valid values: prime256v1, secp384r1, rsa
Algorithm to use for Key generation, supported: prime256v1, secp384r1, rsa
Default value: rsa
password
The optional password for the key
size
The key size, used for RSA only.
Default value: 2048
Functions
dehydrated::file
Type: Ruby 4.x API
The dehydrated::file function.
dehydrated::file(String $files, Optional[String] *$more_files)
The dehydrated::file function.
Returns: Any
files
Data type: String
*more_files
Data type: Optional[String]
Types in this module release
Change log
All notable changes to this project will be documented in this file. The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
0.1.5 (2018-11-13)
0.1.4 (2018-11-02)
0.1.3 (2018-10-18)
0.1.2 (2018-10-17)
0.1.1 (2018-10-15)
0.1.0 (2018-10-14)
* This Changelog was automatically generated by github_changelog_generator
Dependencies
- puppetlabs-stdlib (>= 4.25.1)
- puppetlabs-concat (>= 4.1.0)
- puppetlabs-vcsrepo (>= 2.3.0)
- puppetlabs-cron_core (>= 1.0.0)