Using Caddy to keep certificates renewed

You can use Caddy as an automated certificate manager to keep certificates renewed without having to run an HTTPS server [1]. This way, the certificates can be used by other programs that need them.

Caddy’s tls app can be configured without the need for an HTTP server. It can keep certificates renewed. Without additional configuration, assets (certificates, keys, and metadata) are stored in a data directory on the local file system at a location dependent upon your OS.

The simplest form is to just list the domain names you want to automate certificates for:

{
	"apps": {
		"tls": {
			"certificates": {
				"automate": [
					"example.com",
					"example.net"
				]
			}
		}
	}
}

However, we recommend specifying an email address so the CA can contact you if anything goes wrong:

{
	"apps": {
		"tls": {
			"certificates": {
				"automate": [
					"example.com",
					"example.net"
				]
			},
			"automation": {
				"policies": [
					{
						"issuers": [{
							"module": "acme",
							"email": "you@yours.com"
						}]
					}
				]
			}
		}
	}
}

If you need certificates provisioned through the DNS challenge for internal certificates or to be shared across services for common usage, the following config can serve as the basis for such use case and may be extended:

{
  "apps": {
    "tls": {
      "certificates": {
        "automate": [
          "*.example.com"
        ]
      },
      "automation": {
        "policies": [
          {
            "issuers": [
              {
                "module": "acme",
                "challenges": {
                  "dns": {
                    "provider": {
                      "name": "cloudflare",
                      "api_token": "YOUR_CLOUDFLARE_API_TOKEN"
                    }
                  }
                }
              }
            ]
          }
        ]
      }
    }
  }
}

If you’re just setting up your server for the first time, you should use a staging endpoint for testing. Set the ca field of the ACME issuer to Let’s Encrypt’s staging endpoint so you don’t get rate limited.

Internal-only certificates

Caddy can also be a certificate authority that is trusted only locally or internally. With it, you can get certificates for any subject because no validation occurs. This can be slightly dangerous if you start trusting this CA certificate everywhere and if your private key is stolen/leaked, so make sure not to share it, mkay?

Using it is very easy:

{
	"apps": {
		"tls": {
			"certificates": {
				"automate": [
					"*.example.com",
					"example.test",
					"localhost",
					"127.0.0.1",
					"::1"
				]
			},
			"automation": {
				"policies": [
					{
						"issuers": [{"module": "internal"}]
					}
				]
			}
		}
	}
}

[1]: Solving the ACME challenges may require use of the HTTP and/or HTTPS ports. If they are used by another program, you will need to configure the DNS challenge or ensure that the other program can solve the ACME challenges…

6 Likes

A post was split to a new topic: Can the TLS app be configured with the Caddyfile?

A post was split to a new topic: Managing certificates for Jellyfin server

A post was split to a new topic: Recommended editor for JSON?

A post was split to a new topic: Can I run my own CA with Caddy?

A post was split to a new topic: “Certificate issuer is unknown” error on internal sites

This is quite cool, I like the idea of using this to provide resiliency against CA failure - is there any way to discover the latest certificate issued irrespective of issuer? In the same way which caddy would use when serving a tls site?

At the moment if I were to use the certificates caddy has renewed i’d need to look into the CA specific directory for the presence of the certificate and work out which one is newer?

1 Like

Good question, and I think that needs to be more flushed out. Caddy doesn’t currently have a way of integrating hooks into it’s cert maintenance, but that would probably be the best/easiest way to do this. It’s been on my list but there hasn’t been much demand for it yet.

@danpoltawski I’ve been working on integrating event dispatching/subscribing to Caddy, but it’s not ready yet.

You can follow this issue which covers your question:

2 Likes

Thanks, that would be really useful :slight_smile:

1 Like

This is a great feature, but it seems it’s currently not working properly.

The certificate files are created with 600 permissions belonging to the caddy user, so they cannot be read from other applications. It seems the permissions are currently not configurable.

That is correct, because private keys are sensitive. The administration of your system is up to you – how you run Caddy is up to you, etc.

I have added

{
  events {
    on certificate_obtained exec /etc/caddy/set_permissions.sh {event.data.domain}
  }
}

to my Caddyfile (and replaced the binary with one that has the exec plugin). I think Caddy renews certificates 2 of the 3 months in, right? At that time I’ll know if it works. :bulb:

1 Like

Yeah, Caddy will start attempting to renew after two-thirds of the cert’s lifetime has passed, so with a 90 day certificate, this is after 60 days.

1 Like

5 posts were split to a new topic: Manage certs for MQTT server

A post was split to a new topic: When will config changes be reflected in certificates stored on disk?

A post was split to a new topic: Events in JSON configs