Let's Encrypt is a non-profit certificate authority run by Internet Security Research Group that provides X.509 certificates for Transport Layer Security encryption at no charge.

Setting up Let's Encrypt on a project VM

Basic process is outlined in How To Secure Apache with Let's Encrypt on Ubuntu 18.04 .

Notes:

  1. You can specify up to 1,000 Apache httpd ServerAliases (subjectAltName in cert terms) to be included in the certificate. No wildcards are permitted.
  2. Make sure that the host names specified resolve to the host on which you are running Let's Encrypt. Note: not a proxy, but the actual host.
  3. It will ask you for an email address. I used private@whimsical.apache.org.
  4. It may or may not be able to update your httpd configuration automatically (it failed for me). But it doesn't really matter, since puppet will undo any changes. It also offered to put the configuration in a separate file, but don't do that as you want the configuration to be under puppet control.
  5. Four lines need to be added/updated to your puppet file, the ones starting with ssl: or ssl- in the puppet nodefile
  6. the certificate update cronjob should be puppetized too. See whimsy cron jobs for an example


Renewing Certbot certificates manually:

Certbot is a free, open source software tool for automatically using Let’s Encrypt certificates on manually-administrated websites to enable HTTPS.

Check for any potential errors:

~# certbot --apache renew --dry-run


Renew the Certificate:

~# certbot --apache renew


Configuring letsencrypt via puppet (mod_md):

mod_md manages common properties of domains for one or more virtual hosts.

TL;DR: See https://github.com/apache/infrastructure-p6/blob/production/data/nodes/nightlies-vm-he-fi.apache.org.yaml for a working setup.

Configuring mod_md for apache is ezpz.

Enable mod_ssl and mod_md manually in the node yaml first:


---
classes:
  - apache
  - apache::mod::ssl
  - other::classes::here

# mod_md is a special case, needs this declaration:
apache::mod:
  md: {}

# Now we need to declare a special mod_md global config:
apache::custom_config:
  mod_md:
    ensure: present
    filename: 'mod_md.conf'
    content: |
      MDCertificateAgreement accepted
      MDomain foo.apache.org   # Whatever the common denominator is


Then, in the SSL vhost, set SSL to false and don't specify keys/certs, but specify SSLEngine On.
We do this because we want SSL on, but don't want puppet to manage it at all:

  foo-ssl:
    vhost_name: '*'
    ensure: 'present'
    port: 443
    ssl: false
    servername: 'foo.apache.org'
    serveraliases:
      - 'foo-vm-he-fi.apache.org'
    serveradmin: 'users@infra.apache.org'
    docroot: '/x1/dist/'
    manage_docroot: false
    access_log_file: 'foo-access.log'
    error_log_file: 'foo-error.log'
    custom_fragment: |
      SSLEngine On

The serveradmin: section of the above vhost stanza is important to include as mod_md uses it as the email address when making the cert request. If you omit the email address, the certificate will not be requested and you will be stuck with a self-signed fallback cert.

httpd might need a manual stop/start after the first run, but will set up certs automatically then.