Skip to content

Latest commit

 

History

History
107 lines (77 loc) · 3.5 KB

README.md

File metadata and controls

107 lines (77 loc) · 3.5 KB

layer-lets-encrypt

Operation

General information for operating charms built with layer:lets-encrypt.

Requirements

Let's Encrypt registration will only work in deployments that meet the following criteria:

  • Placement onto a machine with a public IPv4 address. IPv6 might work (Let's Encrypt supports it), but this is unconfirmed.
    • Container placement will not work. Containers aren't typically publicly route-able.
    • Private networks will not work. For private TLS, I recommend using layer:tls-client with easyrsa.
  • Registered DNS "A" record for the above public address.
    • Must be a domain name allowed by Let's Encrypt. Some, such as *.amazonaws.com dynamic addresses, are not allowed.
  • Must be exposed (juju expose) so that Let's Encrypt can reach it for registration.

Configuration

This layer adds a config option fqdn to config.yaml. When set, this layer will attempt to register the hostname with Let's Encrypt. Only set fqdn:

  • After the DNS "A" record has been established for the unit's public IP address.
  • The registered domain name has had time to propagate.
  • The application has been juju exposed.

A contact-email config option may also be set, for receiving email from Let's Encrypt regarding certification of the domain name.

Development

Include layer:lets-encrypt in your web application charms to automatically obtain TLS certificates from Let's Encrypt.

Once the application is registered with Let's Encrypt, the reactive state lets-encrypt.registered will be set. Then, in your charm, you may obtain the path to the certificates and keys with charms.layer.lets_encrypt.live().

Using with layer:nginx

Configure layer:lets-encrypt to restart nginx during registration:

options:
  lets-encrypt:
    service-name: nginx

Use the obtained certificates in your charm layer. For example:

from charmhelpers.core import hookenv
from charms.layer import lets_encrypt

...

@when('nginx.available', 'lets-encrypt.registered')
@when_not('myapp.web.configured')
def configure_webserver():
    status_set('maintenance', 'Configuring website')
	fqdn = config().get('fqdn')
    live = lets_encrypt.live()
    configure_site('myapp', 'myapp.nginx.tmpl',
                   key_path=live['privkey'],
                   crt_path=live['fullchain'], fqdn=fqdn)
    host.service_restart('nginx')
    status_set('active', 'Website available: https://%s' % fqdn)

You'll want to use the fqdn for server_name in your nginx site config.

Let's Encrypt registration may be disabled by setting the lets-encrypt.disable state. If you know your charm isn't ready to register, or doesn't need it -- maybe it's being TLS terminated by a front end -- please set this to avoid wasting Let's Encrypt resources.

Caveats

The configured service-name will be temporarily stopped while Let's Encrypt registers with the "standalone" method.

This layer is only supported on xenial. If deployed on earlier series, this layer does nothing.

This layer requires agreement to the ISRG Let's Encrypt terms of service in order to deploy, because registration is done non-interactively in the charm.

TODOs

Some things could be improved:

  • Support for automatic renewals, or even manual renewals with an action.
  • Better rate-limiting of the registration retries.
  • Not attempting to register if not exposed (can this be detected?).
  • Not attempting to register if FQDN isn't ready, or is incorrect.
  • Non-interrupting methods like webroot.

License

See LICENSE.layer-lets-encrypt for details.