Giter Site home page Giter Site logo

certmgr's Introduction

certmgr

Build Status godoc

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

  • Ensures certificates are present.
  • Renews certificates before they expire.
  • Triggering a service reload or restart on certificate updates.

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:

  • / just contains certmgr start time and current address.
  • /metrics is the Prometheus endpoint (see the Metrics section).

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:

  • dir: this specifies the directory containing the certificate specs
  • svcmgr: this specifies the service manager to use for restarting or reloading services. This can be systemd (using systemctl), sysv (using service), circus (using circusctl), openrc (using rc-service), dummy (no restart/reload behavior), or command (see the command svcmgr section for details of how to use this).
  • before: optional: this is the default duration before a certificate expiry that certmgr starts attempting to renew PKI. This defaults to 72 hours.
  • interval: optional: this is the default for how often certmgr will check certificate expirations and update PKI material on disk upon any changes (if necessary). This defaults to one hour.
  • interval_splay: optional: this is used to vary the interval period. A random time between 0 and this value is added to interval if specified. This defaults to 0.
  • initial_splay: if specified, a random sleep period between 0 and this value is used for the initial sleep after startup of a spec. This provides a way to ensure that if a fleet of certmgr are restarted at the same time, their period of wakeup is randomized to avoid said fleet waking up and doing interval checks at the same time for a given spec. This defaults to 0.
  • metrics_address: specifies the address for the Prometheus HTTP endpoint.
  • metrics_port: specifies the port for the Prometheus HTTP endpoint.
  • take_actions_only_if_running: boolean, if true, only fire a spec's action if the service is actually running. If this is set to false (the default for historical reasons), this can lead to certmgr starting a downed service when PKI expiry occurs.

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:

  • service: this is optional, and names the service that the action should be applied to.
  • action: this is optional, and may be one of "restart", "reload", or "nop".
  • svcmgr: this is optional, and defaults to whatever the global config defines. This allows fine-grained control for specifying the svcmgr per cert. If you're using this in a raw certificate definition, you likely want the 'command' svcmgr- see that section for details of how to use it.
  • request: a CFSSL certificate request (see below). If this is specified, a certificate and private_key field is required.
  • private_key and certificate: file specifications (see below) for the private key and certificate. Both must be specified- as must request- if you wish to manage a certificate/key pair.
  • authority: contains the CFSSL CA configuration (see below).
  • before: optional: this is the default duration before a certificate expiry that certmgr starts attempting to renew PKI. This defaults to the managers default, which defaults to 72 hours if unspecified.
  • interval: optional: this is the default for how often certmgr will check certificate expirations and update PKI material on disk upon any changes (if necessary). This defaults to the managers default, which defaults to one hour if unspecified.
  • interval_splay: optional: this is used to vary the interval period. A random time between 0 and this value is added to interval if specified. This defaults to the managers default, which defaults to 0 if unspecified.
  • initial_splay: if specified, a random sleep period between 0 and this value is used for the initial sleep after startup of a spec. This provides a way to ensure that if a fleet of certmgr are restarted at the same time, their period of wakeup is randomized to avoid said fleet waking up and doing interval checks at the same time for a given spec. This defaults to the managers default, which defaults to 0 if unspecified.
  • take_actions_only_if_running: boolean, if true, only fire a spec's action if the service is actually running. If this is set to false (the default for historical reasons), this can lead to certmgr starting a downed service when PKI expiry occurs.
  • key_usages: optional: An array of strings defining what this key should be used for. Certmgr will consider a cert invalid if it does not contain these key usages. Possible values are from cfssl's ExtKeyUsage map

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:

  • path: this is required, and is the path to store the file.
  • owner: this is optional; if it's not provided, the current user is used.
  • group: this is optional; if it's not provided, the primary group of the current user is used.
  • mode: this is optional; if it's not provided, "0644" will be used. It should be a numeric file mode.

CFSSL certificate requests have the following fields:

  • CN: this contains the common name for the certificate.
  • hosts: this is a list of SANs and/or IP addresses for the certificate.
  • key: this is optional; it should contain an "algo" of either "rsa" or "ecdsa" and a "size" appropriate for the chosen algorithm. Recommendations are "rsa" and 2048 or "ecdsa" and 256. The default is "ecdsa" and 256.
  • names: contains PKIX name information, including the "C" (country), "ST" (state), "L" (locality/city), "O" (organisation), and "OU" (organisational unit) fields.

The CA specification contains the following fields:

  • remote: the CA to use. If not provided, the default remote from the config file is used.
  • auth_key: the authentication key used to request a certificate.
  • auth_key_file: optional, if defined read the auth_key from this. If auth_key and auth_key_file is defined, auth_key is used.
  • label: the CA to use for the certificate.
  • profile: the CA profile that should be used.
  • file: if this is included, the CA certificate will be saved here. It follows the same file specification format above. Use this if you want to save your CA cert to disk.
  • root_ca: optionally, a path to a certificate to trust as CA for the cfssl API server certificate. Usable if the "remote" is tls enabled and configured with a self-signed certificate. By default, the system root CA chain is trusted.

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:

  • CERTMGR_CA_PATH: if CA was configured for the spec, this is the path to the CA ondisk that was changed.
  • CERTMGR_CERT_PATH: This is the path to the cert that was written.
  • CERTMGR_KEY_PATH: This is the path to the key that was written.

Subcommands

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

  • check: validates the configuration file and all the certificate specs available in the certificate spec directory. Note that if you wish to operate on just one spec, you can use -d /path/to/that/spec to accomplish it.
  • clean: removes all of the certificates and private keys specified by the certificate specs. Note that if you wish to operate on just one spec, you can use -d /path/to/that/spec to accomplish it.
  • ensure: attempts to load all certificate specs, and ensure that the TLS key pairs they identify exist, are valid, and that they are up-to-date. Note that if you wish to operate on just one spec, you can use -d /path/to/that/spec to accomplish this.
  • genconfig: generates a default configuration file and ensures the default service directory exists.
  • version: prints certificate manager's version, the version of Go it was built with, and shows the current configuration.

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.

certmgr's People

Contributors

akamac avatar anita-tenjarla avatar cbroglie avatar dependabot[bot] avatar dqminh avatar ferringb avatar haraldnordgren avatar jbampton avatar jmunson avatar jordiclariana avatar kisom avatar mrueg avatar nataliescottdavidson avatar terinjokes avatar thekuwayama avatar willbuckner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

certmgr's Issues

Feature: Certmgr as an in-process supervisor

Problem:
Currently it's difficult to use certmgr as an in-process supervisor.

Use case:
I am a go library that doesn't want to require my customers to configure Certmgr with cert.Spec JSON files, instead letting them pass in configuration via function parameters.

Potential Solution:

  1. Remove the checked-in vendor directory. This causes type issues when using certmgr as a library.
  2. Expose the svcmgr.Manager interface on Manager (either within the Manager struct or via a constructor). This will enable users of certmgr to pass in their own svcmgr.Manager implementations, enabling users to restart/reload their process as needed.
  3. Don't require cert.Spec to exist on the filesystem. Currently the Load() function initializes the renew channel. This makes it impossible to configure certmgr without writing a Spec to the filesystem, which is cumbersome from a library perspective.

docs: building and readme outdated

hey there,

i did playing around with certmgr and cfssl to build internal CA for my homelab, and my first impression is : wow, what great toolset!
but i got a bit confusing while reading docs and making own experience with certmgr.

Can anybody explain how to build the binary of certmgr with go tools?! i am using golang 1.18.2.
go get is deprecated and replaced by go install. but go install github.com/cloudflare/certmgr/cmd/...@latest only build version 1.6.5 how to see here.

since i am using the newest version, the "ca" key in my specs.json works fine and a deprecated info will show if i use the "ca" setting under "authority" like here:

certmgr/README.md

Lines 152 to 156 in 4af0d77

"file": {
"path": "/etc/myservice/ca.pem",
"owner": "www-data",
"group": "www-data"
},

so is there a reason why it still in readme.md at the newest version?!
it confused me while get started with this really nice peace of application.

i think the docs thing is not much important, but how to build can help me and other people a lot. hoping for a short explanation.

Chris

cert: no CA file provided, won't write to disk

After successfully configured cfssl serve I configured certmgr like this:

{
    "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",
        "mode": "0600"
    },
    "certificate": {
        "path": "/home/kyle/tmp/certmgr/certs/test1.pem"
    },
    "authority": {
        "remote": "localhost:8888",
        "auth_key": "0123456789ABCDEF0123456789ABCDEF",
        "profile": "server"
    }
}

All settings are correct, but when I try to exec this ./certmgr-linux-amd64-v1.4.2 check I get this message:

2017/11/09 15:28:21 [INFO] certmgr: loading from config file /etc/certmgr/certmgr.yaml
2017/11/09 15:28:21 [INFO] manager: loading certificates from/etc/certmgr.d
2017/11/09 15:28:21 [INFO] manager: loading spec from /etc/certmgr.d/test.json
2017/11/09 15:28:21 [INFO] cert: no CA file provided, won't write to disk
2017/11/09 15:28:21 [INFO] manager: watching 1 certificates
OK

After searching the code for cert: no CA file provided, won't write to disk I figured out that I have to include a "file": "<something>" in the authority section, but when I do I always get a format error:

Failed: json: cannot unmarshal string into Go struct field CA.file of type cert.File

This is not documented and I can't figure out what value should I set there. Is that really necessary?

should include instructions for starting cfssl serve

It's clear from the readme that this is meant to be used with cfssl. We should have a quick note for someone new who to startup cfssl's API in a way that has reasonable defaults: ie, requires an auth_key and knows about profiles.

"Lookup requires cgo" error when testing the README specs example

When following the README.md and trying it with the specs provided it fails with this error:

# ./certmgr-linux-amd64-v1.4.2 check
2017/11/09 11:54:41 [INFO] certmgr: loading from config file /etc/certmgr/certmgr.yaml
2017/11/09 11:54:41 [INFO] manager: loading certificates from/etc/certmgr.d
2017/11/09 11:54:41 [INFO] manager: loading spec from /etc/certmgr.d/test.json
Failed: user: Lookup requires cgo

Steps to reproduce on a Ubuntu Server 16.04:

-----
dir: /etc/certmgr.d
svcmgr: systemd
before: 72h
interval: 1h
metrics_address: localhost
metrics_port: "8080"

-----
certmgr: creating certificate spec directory /etc/certmgr.d
  • Create /etc/certmgr.d/test.json and paste example certificate spec from the README.md
  • Run ./certmgr-linux-amd64-v1.4.2 check and get the error:
2017/11/09 12:00:25 [INFO] certmgr: loading from config file /etc/certmgr/certmgr.yaml
2017/11/09 12:00:25 [INFO] manager: loading certificates from/etc/certmgr.d
2017/11/09 12:00:25 [INFO] manager: loading spec from /etc/certmgr.d/test.json
Failed: user: Lookup requires cgo

If I remove any reference to "owner" : "www-data" and "group" : "www-data" from specs file, it works.

spec as yaml broken

hey,

i wanted to provide my specs as yaml. according to spec.rst and release changelog since 2.0.0 it is supported for spec files, too.
i have testet with the binary from release 3.0.3. and an own builded binary from source.
with binary from 1.6.5 it works, but without 'ca' key in the global section like shown in example json from readme.

my yaml:

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: "/opt/pki/www_yaml.key"
  owner: www-data
  group: www-data
  mode: "0600"
certificate:
  path: "/opt/pki/test1_yaml.pem"
  owner: www-data
  group: www-data
ca:
  path: "/opt/pki/ca_yaml.pem"
  owner: www-data
  group: www-data
authority:
  remote: ca.example.net:8888
  auth_key: "012345678012345678"
  label: www_ca
  profile: three-month

and the error output:

root@sslca:/etc/certmgr.d# /opt/certmgr check
INFO[0000] certmgr: loading from config file /etc/certmgr/certmgr.yaml 
INFO[0000] manager: loading certificates from /etc/certmgr.d 
INFO[0000] manager: loading spec from /etc/certmgr.d/nginx.yaml 
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc020460348 stack=[0xc020460000, 0xc040460000]
fatal error: stack overflow

runtime stack:
runtime.throw({0xafe312?, 0xfd3260?})
	/usr/local/go/src/runtime/panic.go:992 +0x71
runtime.newstack()
	/usr/local/go/src/runtime/stack.go:1101 +0x5cc
runtime.morestack()
	/usr/local/go/src/runtime/asm_amd64.s:547 +0x8b

goroutine 1 [running]:
reflect.Value.Elem({0xa7d700?, 0xc0003fe0d8?, 0x16?})
	/usr/local/go/src/reflect/value.go:1166 +0x1ba fp=0xc020460358 sp=0xc020460350 pc=0x49507a
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:308 +0x18d fp=0xc0204603e8 sp=0xc020460358 pc=0x7bad2d
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020460450 sp=0xc0204603e8 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc0204604f0 sp=0xc020460450 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020460518 sp=0xc0204604f0 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020460580 sp=0xc020460518 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020460610 sp=0xc020460580 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020460678 sp=0xc020460610 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020460718 sp=0xc020460678 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020460740 sp=0xc020460718 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc0204607a8 sp=0xc020460740 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020460838 sp=0xc0204607a8 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc0204608a0 sp=0xc020460838 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020460940 sp=0xc0204608a0 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020460968 sp=0xc020460940 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc0204609d0 sp=0xc020460968 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020460a60 sp=0xc0204609d0 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020460ac8 sp=0xc020460a60 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020460b68 sp=0xc020460ac8 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020460b90 sp=0xc020460b68 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020460bf8 sp=0xc020460b90 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020460c88 sp=0xc020460bf8 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020460cf0 sp=0xc020460c88 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020460d90 sp=0xc020460cf0 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020460db8 sp=0xc020460d90 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020460e20 sp=0xc020460db8 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x100?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020460eb0 sp=0xc020460e20 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020460f18 sp=0xc020460eb0 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020460fb8 sp=0xc020460f18 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020460fe0 sp=0xc020460fb8 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020461048 sp=0xc020460fe0 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc0204610d8 sp=0xc020461048 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020461140 sp=0xc0204610d8 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc0204611e0 sp=0xc020461140 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020461208 sp=0xc0204611e0 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020461270 sp=0xc020461208 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020461300 sp=0xc020461270 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020461368 sp=0xc020461300 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020461408 sp=0xc020461368 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020461430 sp=0xc020461408 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020461498 sp=0xc020461430 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020461528 sp=0xc020461498 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020461590 sp=0xc020461528 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020461630 sp=0xc020461590 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020461658 sp=0xc020461630 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc0204616c0 sp=0xc020461658 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020461750 sp=0xc0204616c0 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc0204617b8 sp=0xc020461750 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020461858 sp=0xc0204617b8 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020461880 sp=0xc020461858 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc0204618e8 sp=0xc020461880 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020461978 sp=0xc0204618e8 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc0204619e0 sp=0xc020461978 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020461a80 sp=0xc0204619e0 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020461aa8 sp=0xc020461a80 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020461b10 sp=0xc020461aa8 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020461ba0 sp=0xc020461b10 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020461c08 sp=0xc020461ba0 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020461ca8 sp=0xc020461c08 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020461cd0 sp=0xc020461ca8 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020461d38 sp=0xc020461cd0 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020461dc8 sp=0xc020461d38 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020461e30 sp=0xc020461dc8 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020461ed0 sp=0xc020461e30 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020461ef8 sp=0xc020461ed0 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020461f60 sp=0xc020461ef8 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020461ff0 sp=0xc020461f60 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020462058 sp=0xc020461ff0 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc0204620f8 sp=0xc020462058 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020462120 sp=0xc0204620f8 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020462188 sp=0xc020462120 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020462218 sp=0xc020462188 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020462280 sp=0xc020462218 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020462320 sp=0xc020462280 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020462348 sp=0xc020462320 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc0204623b0 sp=0xc020462348 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020462440 sp=0xc0204623b0 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc0204624a8 sp=0xc020462440 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020462548 sp=0xc0204624a8 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020462570 sp=0xc020462548 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc0204625d8 sp=0xc020462570 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020462668 sp=0xc0204625d8 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc0204626d0 sp=0xc020462668 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020462770 sp=0xc0204626d0 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020462798 sp=0xc020462770 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020462800 sp=0xc020462798 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020462890 sp=0xc020462800 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc0204628f8 sp=0xc020462890 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020462998 sp=0xc0204628f8 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc0204629c0 sp=0xc020462998 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020462a28 sp=0xc0204629c0 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020462ab8 sp=0xc020462a28 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020462b20 sp=0xc020462ab8 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020462bc0 sp=0xc020462b20 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020462be8 sp=0xc020462bc0 pc=0x9b324b
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00039e840, 0xc000401880, {0x7fa534b441f0, 0xc0003fe0d8})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:270 +0xa7 fp=0xc020462c50 sp=0xc020462be8 pc=0x7ba727
gopkg.in/yaml%2ev2.(*decoder).prepare(0x0?, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x0?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:313 +0x252 fp=0xc020462ce0 sp=0xc020462c50 pc=0x7badf2
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00039e840, 0xc000401880, {0xa7d700?, 0xc0003fe0d8?, 0x40f025?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:364 +0x105 fp=0xc020462d48 sp=0xc020462ce0 pc=0x7baf65
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler.func1({0xa7d700?, 0xc0003fe0d8?})
	/root/go/pkg/mod/gopkg.in/[email protected]/decode.go:272 +0x125 fp=0xc020462de8 sp=0xc020462d48 pc=0x7ba9e5
github.com/cloudflare/certmgr/certmgr/mgr.(*ParsableAuthority).UnmarshalYAML(0x0?, 0xa7d700?)
	/opt/certmgr-src/certmgr/mgr/file.go:67 +0x2b fp=0xc020462e10 sp=0xc020462de8 pc=0x9b324b
...additional frames elided...

maybe @ferringb @jmunson can help, because they did huge great work on this project in the past.

Chris

Build fails on riscv64 FreeBSD

The software is currently broken on riscv64 FreeBSD due to an outdated version of golang.org/x/sys. Please bump this dependency to version 0.5.0 to fix the breakage.

Support on Windows

Just wondering if there's any plans to support Windows (or if it's theoretically even possible). I did try cross compiling on go 1.12.5 without any luck but I'm not sure if that's a general incompatibility with that version of golang.

CI builds are broken after go modules

The CI builds are broken after the migration to Go modules.

$ travis_install_go_dependencies 1.12.x -v
Makefile detected

$ export SOURCE_DATE_EPOCH=$(git show -s --format=%ci ${TRAVIS_TAG:-${TRAVIS_COMMIT}})
The command "export SOURCE_DATE_EPOCH=$(git show -s --format=%ci ${TRAVIS_TAG:-${TRAVIS_COMMIT}})" exited with 0.

$ go get github.com/mitchellh/gox
go get: warning: modules disabled by GO111MODULE=auto in GOPATH/src;
	ignoring go.mod;
	see 'go help modules'
The command "go get github.com/mitchellh/gox" exited with 0.

$ GOFLAGS=-mod=vendor gox -output="{{.Dir}}-{{.OS}}-{{.Arch}}-${TRAVIS_TAG:-${TRAVIS_COMMIT}}" -os='darwin dragonfly freebsd linux netbsd openbsd solaris' -osarch='!dragonfly/386 !darwin/arm64 !darwin/arm !linux/mips !linux/mipsle' -gcflags="-trimpath=${GOPATH}" ./cmd/certmgr/...
Number of parallel builds: 1
The command "GOFLAGS=-mod=vendor gox -output="{{.Dir}}-{{.OS}}-{{.Arch}}-${TRAVIS_TAG:-${TRAVIS_COMMIT}}" -os='darwin dragonfly freebsd linux netbsd openbsd solaris' -osarch='!dragonfly/386 !darwin/arm64 !darwin/arm !linux/mips !linux/mipsle' -gcflags="-trimpath=${GOPATH}" ./cmd/certmgr/..." exited with 0.

$ for i in certmgr-*; do tar --mtime="${SOURCE_DATE_EPOCH}" --owner=0 --group=0 --numeric-owner -c $i | gzip -n - > $i.tar.gz; done
tar: certmgr-*: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
The command "for i in certmgr-*; do tar --mtime="${SOURCE_DATE_EPOCH}" --owner=0 --group=0 --numeric-owner -c $i | gzip -n - > $i.tar.gz; done" exited with 0.

$ shasum -a 512 certmgr-*.tar.gz | tee sha512sum.txt
627d38af59027d716d6c8f8be41c0d1b9855259f5887607ddfd7789593e4708c2a8e1f0565f0c3f4a59e558c404d03dbc427effce87bcf806172dd92bc4c862d  certmgr-*.tar.gz
The command "shasum -a 512 certmgr-*.tar.gz | tee sha512sum.txt" exited with 0.

support self-signed certificates

As noted in #51, If you run cfssl apiserver tls-enabled, it is currently not possible to use self-signed certificate, because certmgr will reject it.

The request is to support self-signed certificates, in order to support the use case described in NixOS/nixpkgs#45670 where certmgr is intended to support Kubernetes on NixOS.

Opening this as an issue to put the question of whether certmgr should support self-signed certs, and to expose that as a desirable goal for the above use case.

Incompatibility with cfssl/csr

Presumably since b8be2da, projects using both cfssl and certmgr seems to fail to build.

To reproduce:

  1. Create main.go with:
package main

import (
	"fmt"

	"github.com/cloudflare/certmgr/cert"
	"github.com/cloudflare/cfssl/csr"
)

func main() {
	c := csr.New()
	x := &cert.Spec{
		Request: c,
		Key:     &cert.File{},
		Cert:    &cert.File{},
	}
	fmt.Println(x)
}
  1. Run (1.12 -> 1.11 has the same issue):
docker run --rm -it -v $PWD:/go/src/mytest -w /go/src/mytest golang:1.12 go get -v
  1. Observe:
./main.go:13:3: cannot use c (type *"github.com/cloudflare/cfssl/csr".CertificateRequest) as type *"github.com/cloudflare/certmgr/vendor/github.com/cloudflare/cfssl/csr".CertificateRequest in field value
./main.go:15:3: cannot use cert.File literal (type *cert.File) as type *cert.CertificateFile in field value

certmgr should refresh the certificaficates if the spec changes

How to reproduce:

  • update the spec after the certificate has been issued

What to expect:

  • the certificate is regenerated with the new spec

Maybe comparing utime of the spec or certificate, or even having a method to force regeneration of a certificate ( so we can call it whenever the spec is changed ) would help.

Feature: Homebrew Install for macOS

Iโ€™m using a Mac mini as a web server for a few sites that are served through Cloudflare. I use Homebrew to manage most packages installed on this headless Mac. Iโ€™d appreciate it if certmgr could be installed via Homebrew, as it appears not to be there at the moment.

certmgr ensure doesn't regenerate key if algorithm or size changes

Just demonstrating the problem w/ the following stream of commands:

root@36ssds125:~/configs# grep -E '(algo|size)' /etc/certmgr.d/mysqld.json 
      "algo": "ecdsa",
      "size": 256
root@36ssds125:~/configs# md5sum /state/db/mysql-certs/mysqld.*
1e8b16a85830bba1a2b1530c22d362aa  /state/db/mysql-certs/mysqld.ca.crt
0398960b15741a176d1120fbe45ca23e  /state/db/mysql-certs/mysqld.cert
7a3068bdd0a16807fb568a02da392ec2  /state/db/mysql-certs/mysqld.key
root@36ssds125:~/configs# sed -i -e 's:ecdsa:rsa:' /etc/certmgr.d/mysqld.json 
root@36ssds125:~/configs# certmgr ensure
2018/08/14 22:52:12 [INFO] certmgr: loading from config file /etc/certmgr/certmgr.yaml
2018/08/14 22:52:12 [INFO] manager: loading certificates from /etc/certmgr.d
2018/08/14 22:52:12 [INFO] manager: loading spec from /etc/certmgr.d/mysqld.json
2018/08/14 22:52:12 [INFO] manager: watching 1 certificates
2018/08/14 22:52:12 [INFO] manager: ensuring all certificates exist and are ready (maximum 3 tries)
2018/08/14 22:52:12 [INFO] cert: existing CA certificate at /state/db/mysql-certs/mysqld.ca.crt is current
2018/08/14 22:52:12 [INFO] refreshing due to spec /etc/certmgr.d/mysqld.json having a newer mtime then /state/db/mysql-certs/mysqld.key
2018/08/14 22:52:12 [INFO] manager: processing certificate spec /etc/certmgr.d/mysqld.json on attempt 1
2018/08/14 22:52:12 [INFO] encoded CSR
2018/08/14 22:52:12 [INFO] manager: certificate spec /etc/certmgr.d/mysqld.json successfully processed
2018/08/14 22:52:12 [INFO] manager: certificate queue is clear
OK
root@36ssds125:~/configs# md5sum /state/db/mysql-certs/mysqld.*
1e8b16a85830bba1a2b1530c22d362aa  /state/db/mysql-certs/mysqld.ca.crt
7580bcd69192ef4b02790a3f23d2202a  /state/db/mysql-certs/mysqld.cert
7a3068bdd0a16807fb568a02da392ec2  /state/db/mysql-certs/mysqld.key

In this case, that should've also failed since the rsa size is 256- 2048 is minimal; it didn't catch this since it didn't catch that the algo changed. Either way, the algo was switched from ecc to rsa- it should've been regenerated (the cert was at least).

As for size detection, note the key md5sum in the following sequence:

root@36ssds125:~/configs# grep -E '(algo|size)' /etc/certmgr.d/mysqld.json 
      "algo": "rsa",
      "size": 2048
root@36ssds125:~/configs# certmgr ensure
2018/08/14 22:55:42 [INFO] certmgr: loading from config file /etc/certmgr/certmgr.yaml
2018/08/14 22:55:42 [INFO] manager: loading certificates from /etc/certmgr.d
2018/08/14 22:55:42 [INFO] manager: loading spec from /etc/certmgr.d/mysqld.json
2018/08/14 22:55:42 [INFO] manager: watching 1 certificates
2018/08/14 22:55:42 [INFO] manager: ensuring all certificates exist and are ready (maximum 3 tries)
2018/08/14 22:55:42 [INFO] cert: wrote CA certificate: /state/db/mysql-certs/mysqld.ca.crt
2018/08/14 22:55:42 [INFO] manager: processing certificate spec /etc/certmgr.d/mysqld.json on attempt 1
2018/08/14 22:55:42 [INFO] encoded CSR
2018/08/14 22:55:42 [INFO] manager: certificate spec /etc/certmgr.d/mysqld.json successfully processed
2018/08/14 22:55:42 [INFO] manager: certificate queue is clear
OK
root@36ssds125:~/configs# md5sum /state/db/mysql-certs/*
1e8b16a85830bba1a2b1530c22d362aa  /state/db/mysql-certs/mysqld.ca.crt
67aa768dcb312daeb017bc46907eeddd  /state/db/mysql-certs/mysqld.cert
922ff6815ad63400997ca860448bc977  /state/db/mysql-certs/mysqld.key
root@36ssds125:~/configs# sed -i -e 's:2048:4096:' /etc/certmgr.d/mysqld.json 
root@36ssds125:~/configs# certmgr ensure
2018/08/14 22:56:12 [INFO] certmgr: loading from config file /etc/certmgr/certmgr.yaml
2018/08/14 22:56:12 [INFO] manager: loading certificates from /etc/certmgr.d
2018/08/14 22:56:12 [INFO] manager: loading spec from /etc/certmgr.d/mysqld.json
2018/08/14 22:56:12 [INFO] manager: watching 1 certificates
2018/08/14 22:56:12 [INFO] manager: ensuring all certificates exist and are ready (maximum 3 tries)
2018/08/14 22:56:12 [INFO] cert: existing CA certificate at /state/db/mysql-certs/mysqld.ca.crt is current
2018/08/14 22:56:12 [INFO] refreshing due to spec /etc/certmgr.d/mysqld.json having a newer mtime then /state/db/mysql-certs/mysqld.key
2018/08/14 22:56:12 [INFO] manager: processing certificate spec /etc/certmgr.d/mysqld.json on attempt 1
2018/08/14 22:56:12 [INFO] encoded CSR
2018/08/14 22:56:12 [INFO] manager: certificate spec /etc/certmgr.d/mysqld.json successfully processed
2018/08/14 22:56:12 [INFO] manager: certificate queue is clear
OK
root@36ssds125:~/configs# md5sum /state/db/mysql-certs/*
1e8b16a85830bba1a2b1530c22d362aa  /state/db/mysql-certs/mysqld.ca.crt
9d6cfb8eb4f1b158d48ffe4bc8f69140  /state/db/mysql-certs/mysqld.cert
922ff6815ad63400997ca860448bc977  /state/db/mysql-certs/mysqld.key

cert changed, but the key didn't. That's also wrong.

Cut a new release

๐Ÿ‘‹ it has been three years since last release, 3.0.3, good to cut a new release. Thanks!

Make certmgr only look for *.json, *.yaml or *.yml files in certmgr.d dir

To avoid problems with temporal files, as when I'm editing some file in that directory:

# ./certmgr-linux-amd64-v1.4.2 
2017/11/09 15:40:33 [INFO] certmgr: loading from config file /etc/certmgr/certmgr.yaml
2017/11/09 15:40:33 [INFO] manager: loading certificates from/etc/certmgr.d
2017/11/09 15:40:33 [INFO] manager: loading spec from /etc/certmgr.d/.test.json.swp
2017/11/09 15:40:33 [FATAL] certmgr: cert: unrecognised spec file format for /etc/certmgr.d/.test.json.swp

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.