Skip to content
/ leach Public

Let's Encrypt Automated Certificate Handler

License

Notifications You must be signed in to change notification settings

jlindsey/leach

Repository files navigation

FOSSA Status

Leach

Let's Encrypt Automated Certificate Handler.

Automated, Consul-driven service for LetsEncrypt certificate requests and renewals.

This tool only supports the LE-specific ACME "v1" API (see golang/go#21081 for further information).

Setup

To bootstrap the tool, a config key needs to be added to Consul's KV store. The {PREFIX} in the list below is customizable with the CONSUL_PREFIX env var or flag and by default is leach.

{PREFIX}/conf must be a JSON doc like so:

{
    "email": "mailto:[email protected]",
    "ident": {
        "country": ["US"],
        "province": ["Virginia"],
        "locality": ["Arlington"],
        "organization": ["My Org"],
        "organizational_unit": ["My Dept"]
    },
    "dns_config": {
        "default": {
             // ...
        }
    }
}

Where email is the address to register with LetsEncrypt, and ident is the default CSR Subject identification info. The dns_config object is explained lower down. This will allow the service to start up and generate a new LetsEncrypt account (storing the info in {PREFIX}/auth).

See below for additional configuration options and their defaults. The three JSON keys above are the minimum to get a working setup.

Once the {PREFIX}/auth key is created in Consul (after the first successful authentication), you should copy this data to a secure backup.

Cert Management

To request a cert and bring it under management, simply create a new (empty) key under {PREFIX}/sites:

$ curl --request PUT http://$CONSUL_ADDR/v1/kv/$CONSUL_PREFIX/sites/www.example.com

This key by itself tells Leach to manage the specified domain's cert with default options: it will request if it's missing from its storage, and renew it on a schedule.

You can also set a sites/ key's value to a JSON document that overrides and customizes the options used. Any options available in the main {PREFIX}/conf key are avilable to be overridden here, with the exception of email.

Once requested and acquired, certs and private keys are stored in {PREFIX}/pki as www.example.com-cert.pem and www.example.com-key.pem. This is to allow easy compatibility with Fabio's Cert Stores.

Revocation

To revoke an issued cert, create a new empty key under {PREFIX}/revoke:

$ curl --request PUT http://$CONSUL_ADDR/v1/kv/$CONSUL_PREFIX/revoke/www.example.com

This will request a certificate revocation from LE upstream, delete the stored private key and cert keys under {PREFIX}/pki, and then delete the triggering key from {PREFIX}/revoke that you just created to prevent a loop. If an entry for this cert still exists under {PREFIX}/sites, Leach will attempt to aquire another.

If you want to go scorched-earth, you can set the {PREFIX}/rev to a JSON document of {"purge": true}:

$ curl --request PUT --data '{"purge": true}' http://$CONSUL_ADDR/v1/kv/$CONSUL_PREFIX/rev/www.example.com

This will do everything as described above, but will also delete the entry under {PREFIX}/sites and revoke the cached LE authorization for the domain.

Configuration

The following configuration variables are available to be set in the {PREFIX}/conf key and overridden in sites/ unless otherwise noted. Defaults are shown below. Options with a * are required and have no default.

{
    // Email address to register with LE. Note that it must begin with the `mailto:`.
    "email": "mailto:*",

    // CSR Subject values for requesting certs. All keys below are required and must be arrays.
    "ident": {
        "country": [*],
        "province": [*],
        "locality": [*],
        "organization": [*],
        "organizational_unit": [*]
    },

    // Configuration for the supported DNS providers used for LE auth checks.
    "dns_config": {
        // See "DNS Providers" section below for specifics.
        "default": *
    },

    // Renew a cert when it has this many days until expiration.
    "renew": 30,

    // Additional names to request on this cert, making it a SAN cert (sites/ only).
    "extra_names": [],

    // DNS provider to use for this cert instead of the deafult (sites/ only).
    "dns_provider": ""
}

DNS Providers

The following DNS provider backends are included and supported. Pull requests to add more are welcome.

Multiple providers of a given type are allowed, but their names (the keys for the config dicts) must be unique. There must be exactly one default provider.

AWS Route53

{
    "dns_config": {
        "default": {
            // AWS Provider
            "provider": "aws",

            // AWS Access Key ID
            "access_key_id": *,

            // AWS Secret Access Key
            "secret_access_key": *,

            // Route53 Managed Domain ID
            "domain_id": *
        }
    }
}

DigitalOcean

{
    "dns_config": {
        "default": {
            // DigitalOcean Provider
            "provider": "digitalocean",

            // DO API token with access to the hosted DNS zone
            "token": *,

            // Name of the zone defined in the DO control panel
            "zone": *
        }
    }
}

Infoblox

{
    "dns_config": {
        "default": {
            // Infoblox Provider
            "provider": "infoblox",

            // Base URL of your Infoblox WAPI endpoint (should include the /wapi/<version> path) 
            "url": *,

            // Username for basic auth
            "username": *,

            // Password for basic auth
            "password": *,

            // DNS view(s) to manage records in
            // (see: https://docs.infoblox.com/display/NAG8/Chapter+18+DNS+Views)
            "views": [*]
        }
    }
}

Web Interface

A simple web interface for viewing the status of the tool is enabled by setting the --bind flag (or BIND env var) to an address and port such as 0.0.0.0:8080. The interface is opt-in, you must set this option to enable it.

A simple health-check endpoint is available at /healthz, which will return HTTP 200 when healthy, 500 on error, and 503 when shutting down or starting up.

Development

Leach is written in Go and requires version >=1.11 for Go modules support.

You will need a local Consul instance to develop against, which can be launched with Docker like so:

$ docker run --name consul -d -p 8500:8500 --rm consul

This runs Consul in dev mode and does not persist data to disk, so all data will be lost on a restart of the service. A convenience script is provided in scripts/bootstrap_consul.sh to preload with some data for testing and development. This script requires curl and envsubst to be installed and on your PATH.

You should also set the ACME_URL variable to the URL of the LE Staging Servers, which keeps you from being throttled and wasting your domain rate limit on dev and testing.

License

FOSSA Status