cloudflare / certmgr

Automated certificate management using a CFSSL CA.
BSD 2-Clause "Simplified" License
218 stars 40 forks source link

certmgr

Build Status godoc

certmgr is a tool for managing certificates using CFSSL. It does the following:

It operates on certificate specs, which are JSON files containing the information needed to generate a certificate.

At regular intervals, certmgr will check that the parameters set in a certificate spec match the PKI material on disk. certmgr will take actions as needed in ensuring and regenerating PKI material as needed. If there's an error, a material refresh will happen at a later time.

When run without any subcommands, certmgr will start monitoring certificates. The configuration and specifications can be validated using the check subcommand.

If you want to further understand the package logic, take a look at the godocs.

Note: certmgr requires Go 1.11 or later due to cfssl dependency.

Web server

When appropriately configured, certmgr will start a web server that has the following endpoints:

Metrics

Prometheus is used to collect some useful certmgr metrics. You can find them in the godoc.

certmgr.yaml

The configuration file must be a YAML file; it is expected to be in /etc/certmgr/certmgr.yaml. The location can be changed using the -f flag.

An example certmgr.yaml file is:

dir: /etc/certmgr.d
default_remote: ca.example.net:8888
svcmgr: systemd
before: 72h
interval: 30m

metrics_port: 8080
metrics_address: localhost

This contains all of the currently available parameters:

PKI Specs

A spec is used to manage PKI material for a consuming app. A spec does not have to request a certificate/key, and does not have to request a CA; it must request at least one of those two modes, however.

Said another way; you can use this to maintain a CA on disk. You can use this to maintain certificate/key pair signed by the given authority; you can do both modes if you wish, but one must be specified by the spec.

An example spec that writes both a CA and certificate key pair defined in JSON:

{
    "service": "nginx",
    "action": "restart",
    "request": {
        "CN": "www.example.net",
        "hosts": [
            "example.net",
            "www.example.net"
        ],
        "key": {
            "algo": "ecdsa",
            "size": 521
        },
        "names": [
            {
                "C": "US",
                "ST": "CA",
                "L": "San Francisco",
                "O": "Example, LLC"
            }
        ]
    },
    "private_key": {
        "path": "/etc/ssl/private/www.key",
        "owner": "www-data",
        "group": "www-data",
        "mode": "0600"
    },
    "certificate": {
        "path": "/home/kyle/tmp/certmgr/certs/test1.pem",
        "owner": "www-data",
        "group": "www-data"
    },
    "ca": {
        "path": "/etc/myservice/ca.pem",
        "owner": "www-data",
        "group": "www-data"
    },
    "authority": {
        "remote": "ca.example.net:8888",
        "auth_key": "012345678012345678",
        "label": "www_ca",
        "profile": "three-month",
        "root_ca": "/etc/cfssl/api_server_ca.pem"
    }
}

And this is an example that writes just the CA to disk:

{
    "service": "nginx",
    "action": "restart",
    "authority": {
        "remote": "ca.example.net:8888",
        "auth_key": "012345678012345678",
        "label": "www_ca",
        "profile": "three-month",
        "file": {
            "path": "/etc/myservice/ca.pem",
            "owner": "www-data",
            "group": "www-data"
        },
        "root_ca": "/etc/cfssl/api_server_ca.pem"
    }
}

A certificate spec has the following fields:

Note: certmgr will throw a warning if svcmgr is dummy AND action is "nop" or undefined. This is because such a setup will not properly restart or reload a service upon certificate renewal, which will likely cause your service to crash. Running certmgr with the --strict flag will not even load a certificate spec with a dummy svcmgr and undefined/nop action configuration.

File specifications contain the following fields:

CFSSL certificate requests have the following fields:

The CA specification contains the following fields:

command svcmgr and how to use it

If the svcmgr is set to command, then action is interpreted as a shell snippet to invoke via bash -c. Bash is preferred since it allows parse checks to run. If Bash isn't available, parse checks are skipped and sh -c is used. If sh can't be found, then this svcmgr is disabled. The command svcmgr is useful in Marathon environments.

Environment variables are set as follows:

Subcommands

In addition to the certificate manager, there are a few utilities functions specified:

See also

The certmgr spec is included as SPEC.rst.

Contributing

To contribute, fork this repo and make your changes. Then, make a PR to this repo. A PR requires at least one approval from a repo admin and successful CI build.

Unit Testing

Unit tests can be written locally. This should be straightforward in a Linux environment. To run them in a non-Linux environment, have Docker up and run make test. This will spin up a container with your local build. From here you can go test -v ./... your files. This unconventional setup is because cfssl, the underlying logic of certmgr, uses cgo.