2018-12-10 13:15:26 +10:00
|
|
|
// Copyright 2015 Matthew Holt
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2018-12-12 04:46:55 +10:00
|
|
|
// Package certmagic automates the obtaining and renewal of TLS certificates,
|
|
|
|
// including TLS & HTTPS best practices such as robust OCSP stapling, caching,
|
|
|
|
// HTTP->HTTPS redirects, and more.
|
|
|
|
//
|
2018-12-12 08:48:47 +10:00
|
|
|
// Its high-level API serves your HTTP handlers over HTTPS if you simply give
|
2018-12-12 04:46:55 +10:00
|
|
|
// the domain name(s) and the http.Handler; CertMagic will create and run
|
|
|
|
// the HTTPS server for you, fully managing certificates during the lifetime
|
|
|
|
// of the server. Similarly, it can be used to start TLS listeners or return
|
|
|
|
// a ready-to-use tls.Config -- whatever layer you need TLS for, CertMagic
|
2018-12-12 08:48:47 +10:00
|
|
|
// makes it easy. See the HTTPS, Listen, and TLS functions for that.
|
2018-12-12 04:46:55 +10:00
|
|
|
//
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// If you need more control, create a Cache using NewCache() and then make
|
|
|
|
// a Config using New(). You can then call Manage() on the config. But if
|
|
|
|
// you use this lower-level API, you'll have to be sure to solve the HTTP
|
2018-12-12 04:46:55 +10:00
|
|
|
// and TLS-ALPN challenges yourself (unless you disabled them or use the
|
|
|
|
// DNS challenge) by using the provided Config.GetCertificate function
|
|
|
|
// in your tls.Config and/or Config.HTTPChallangeHandler in your HTTP
|
|
|
|
// handler.
|
|
|
|
//
|
|
|
|
// See the package's README for more instruction.
|
2018-12-10 13:15:26 +10:00
|
|
|
package certmagic
|
|
|
|
|
|
|
|
import (
|
2019-10-17 03:11:48 +10:00
|
|
|
"context"
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
"crypto"
|
2018-12-10 13:15:26 +10:00
|
|
|
"crypto/tls"
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
"crypto/x509"
|
2024-05-08 01:46:03 +10:00
|
|
|
"encoding/json"
|
2018-12-10 13:15:26 +10:00
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
2022-09-27 02:19:28 +10:00
|
|
|
"os"
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
"sort"
|
2018-12-10 13:15:26 +10:00
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
"time"
|
2022-09-27 02:19:28 +10:00
|
|
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"go.uber.org/zap/zapcore"
|
2018-12-10 13:15:26 +10:00
|
|
|
)
|
|
|
|
|
2018-12-10 17:26:09 +10:00
|
|
|
// HTTPS serves mux for all domainNames using the HTTP
|
|
|
|
// and HTTPS ports, redirecting all HTTP requests to HTTPS.
|
2022-03-08 05:26:52 +10:00
|
|
|
// It uses the Default config and a background context.
|
2018-12-10 13:15:26 +10:00
|
|
|
//
|
2018-12-18 05:22:46 +10:00
|
|
|
// This high-level convenience function is opinionated and
|
|
|
|
// applies sane defaults for production use, including
|
|
|
|
// timeouts for HTTP requests and responses. To allow very
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// long-lived connections, you should make your own
|
|
|
|
// http.Server values and use this package's Listen(), TLS(),
|
|
|
|
// or Config.TLSConfig() functions to customize to your needs.
|
|
|
|
// For example, servers which need to support large uploads or
|
|
|
|
// downloads with slow clients may need to use longer timeouts,
|
|
|
|
// thus this function is not suitable.
|
2018-12-18 05:22:46 +10:00
|
|
|
//
|
2018-12-10 13:15:26 +10:00
|
|
|
// Calling this function signifies your acceptance to
|
|
|
|
// the CA's Subscriber Agreement and/or Terms of Service.
|
|
|
|
func HTTPS(domainNames []string, mux http.Handler) error {
|
2022-03-08 05:26:52 +10:00
|
|
|
ctx := context.Background()
|
|
|
|
|
2018-12-10 13:15:26 +10:00
|
|
|
if mux == nil {
|
|
|
|
mux = http.DefaultServeMux
|
|
|
|
}
|
|
|
|
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
DefaultACME.Agreed = true
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
cfg := NewDefault()
|
|
|
|
|
2022-03-08 05:26:52 +10:00
|
|
|
err := cfg.ManageSync(ctx, domainNames)
|
2018-12-10 13:15:26 +10:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
httpWg.Add(1)
|
|
|
|
defer httpWg.Done()
|
|
|
|
|
|
|
|
// if we haven't made listeners yet, do so now,
|
|
|
|
// and clean them up when all servers are done
|
|
|
|
lnMu.Lock()
|
|
|
|
if httpLn == nil && httpsLn == nil {
|
|
|
|
httpLn, err = net.Listen("tcp", fmt.Sprintf(":%d", HTTPPort))
|
|
|
|
if err != nil {
|
|
|
|
lnMu.Unlock()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-09-15 04:10:52 +10:00
|
|
|
tlsConfig := cfg.TLSConfig()
|
|
|
|
tlsConfig.NextProtos = append([]string{"h2", "http/1.1"}, tlsConfig.NextProtos...)
|
|
|
|
|
|
|
|
httpsLn, err = tls.Listen("tcp", fmt.Sprintf(":%d", HTTPSPort), tlsConfig)
|
2018-12-10 13:15:26 +10:00
|
|
|
if err != nil {
|
|
|
|
httpLn.Close()
|
|
|
|
httpLn = nil
|
|
|
|
lnMu.Unlock()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
httpWg.Wait()
|
|
|
|
lnMu.Lock()
|
|
|
|
httpLn.Close()
|
|
|
|
httpsLn.Close()
|
|
|
|
lnMu.Unlock()
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
hln, hsln := httpLn, httpsLn
|
|
|
|
lnMu.Unlock()
|
|
|
|
|
2018-12-18 05:22:46 +10:00
|
|
|
// create HTTP/S servers that are configured
|
|
|
|
// with sane default timeouts and appropriate
|
|
|
|
// handlers (the HTTP server solves the HTTP
|
|
|
|
// challenge and issues redirects to HTTPS,
|
|
|
|
// while the HTTPS server simply serves the
|
|
|
|
// user's handler)
|
|
|
|
httpServer := &http.Server{
|
|
|
|
ReadHeaderTimeout: 5 * time.Second,
|
|
|
|
ReadTimeout: 5 * time.Second,
|
|
|
|
WriteTimeout: 5 * time.Second,
|
|
|
|
IdleTimeout: 5 * time.Second,
|
2022-03-08 05:26:52 +10:00
|
|
|
BaseContext: func(listener net.Listener) context.Context { return ctx },
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
}
|
2020-11-17 03:53:41 +10:00
|
|
|
if len(cfg.Issuers) > 0 {
|
2022-03-25 03:34:31 +10:00
|
|
|
if am, ok := cfg.Issuers[0].(*ACMEIssuer); ok {
|
2020-11-17 03:53:41 +10:00
|
|
|
httpServer.Handler = am.HTTPChallengeHandler(http.HandlerFunc(httpRedirectHandler))
|
|
|
|
}
|
2018-12-18 05:22:46 +10:00
|
|
|
}
|
|
|
|
httpsServer := &http.Server{
|
|
|
|
ReadHeaderTimeout: 10 * time.Second,
|
|
|
|
ReadTimeout: 30 * time.Second,
|
|
|
|
WriteTimeout: 2 * time.Minute,
|
|
|
|
IdleTimeout: 5 * time.Minute,
|
|
|
|
Handler: mux,
|
2022-03-08 05:26:52 +10:00
|
|
|
BaseContext: func(listener net.Listener) context.Context { return ctx },
|
2018-12-18 05:22:46 +10:00
|
|
|
}
|
2018-12-10 13:15:26 +10:00
|
|
|
|
|
|
|
log.Printf("%v Serving HTTP->HTTPS on %s and %s",
|
|
|
|
domainNames, hln.Addr(), hsln.Addr())
|
|
|
|
|
2018-12-18 05:22:46 +10:00
|
|
|
go httpServer.Serve(hln)
|
|
|
|
return httpsServer.Serve(hsln)
|
2018-12-10 13:15:26 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
func httpRedirectHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
toURL := "https://"
|
|
|
|
|
|
|
|
// since we redirect to the standard HTTPS port, we
|
|
|
|
// do not need to include it in the redirect URL
|
Rewrite HTTP and TLS-ALPN solvers; always use our own solvers
This solves several issues related to solving for multiple names
concurrently. The basic idea is that now we always use our own solvers,
which is actually much simpler. We just wrap them in a distributedSolver
which writes the keyAuth material to storage. Our solvers then proceed
to solve the challenges: either by allowing whatever is currently
listening on the challenge port to solve it, or by starting their own
servers. Our solvers keep track of how many challenges each solver is
answering, and the "last one out turns off the lights" so to speak.
Also, where we used to try dialing a port then listening if it was
available, now we just try listening, and if it fails, we make sure it
is in use by dialing it. I've added locking around this as well to
ensure that races for the socket, along with the counters, do not happen.
Overall, this is a much improved solver implementation that can handle
more use cases at a larger scale than before.
Also, a minor data race was revealed in user.go, which only happens in
some rare edge cases as far as I can tell, but I marked them with a TODO
so we can get around to fixing them later.
2020-02-06 10:23:13 +10:00
|
|
|
requestHost := hostOnly(r.Host)
|
2018-12-10 13:15:26 +10:00
|
|
|
|
|
|
|
toURL += requestHost
|
|
|
|
toURL += r.URL.RequestURI()
|
|
|
|
|
|
|
|
// get rid of this disgusting unencrypted HTTP connection 🤢
|
|
|
|
w.Header().Set("Connection", "close")
|
|
|
|
|
|
|
|
http.Redirect(w, r, toURL, http.StatusMovedPermanently)
|
|
|
|
}
|
|
|
|
|
|
|
|
// TLS enables management of certificates for domainNames
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// and returns a valid tls.Config. It uses the Default
|
|
|
|
// config.
|
2018-12-10 13:15:26 +10:00
|
|
|
//
|
|
|
|
// Because this is a convenience function that returns
|
|
|
|
// only a tls.Config, it does not assume HTTP is being
|
|
|
|
// served on the HTTP port, so the HTTP challenge is
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// disabled (no HTTPChallengeHandler is necessary). The
|
|
|
|
// package variable Default is modified so that the
|
|
|
|
// HTTP challenge is disabled.
|
2018-12-10 13:15:26 +10:00
|
|
|
//
|
|
|
|
// Calling this function signifies your acceptance to
|
|
|
|
// the CA's Subscriber Agreement and/or Terms of Service.
|
|
|
|
func TLS(domainNames []string) (*tls.Config, error) {
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
DefaultACME.Agreed = true
|
|
|
|
DefaultACME.DisableHTTPChallenge = true
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
cfg := NewDefault()
|
2021-09-24 06:35:51 +10:00
|
|
|
return cfg.TLSConfig(), cfg.ManageSync(context.Background(), domainNames)
|
2018-12-10 13:15:26 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Listen manages certificates for domainName and returns a
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// TLS listener. It uses the Default config.
|
2018-12-10 13:15:26 +10:00
|
|
|
//
|
|
|
|
// Because this convenience function returns only a TLS-enabled
|
|
|
|
// listener and does not presume HTTP is also being served,
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// the HTTP challenge will be disabled. The package variable
|
|
|
|
// Default is modified so that the HTTP challenge is disabled.
|
2018-12-10 13:15:26 +10:00
|
|
|
//
|
|
|
|
// Calling this function signifies your acceptance to
|
|
|
|
// the CA's Subscriber Agreement and/or Terms of Service.
|
|
|
|
func Listen(domainNames []string) (net.Listener, error) {
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
DefaultACME.Agreed = true
|
|
|
|
DefaultACME.DisableHTTPChallenge = true
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
cfg := NewDefault()
|
2021-09-24 06:35:51 +10:00
|
|
|
err := cfg.ManageSync(context.Background(), domainNames)
|
2018-12-10 13:15:26 +10:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return tls.Listen("tcp", fmt.Sprintf(":%d", HTTPSPort), cfg.TLSConfig())
|
|
|
|
}
|
|
|
|
|
2019-10-16 16:19:57 +10:00
|
|
|
// ManageSync obtains certificates for domainNames and keeps them
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// renewed using the Default config.
|
|
|
|
//
|
|
|
|
// This is a slightly lower-level function; you will need to
|
|
|
|
// wire up support for the ACME challenges yourself. You can
|
|
|
|
// obtain a Config to help you do that by calling NewDefault().
|
2018-12-10 13:15:26 +10:00
|
|
|
//
|
|
|
|
// You will need to ensure that you use a TLS config that gets
|
|
|
|
// certificates from this Config and that the HTTP and TLS-ALPN
|
|
|
|
// challenges can be solved. The easiest way to do this is to
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// use NewDefault().TLSConfig() as your TLS config and to wrap
|
|
|
|
// your HTTP handler with NewDefault().HTTPChallengeHandler().
|
|
|
|
// If you don't have an HTTP server, you will need to disable
|
|
|
|
// the HTTP challenge.
|
2018-12-10 13:15:26 +10:00
|
|
|
//
|
|
|
|
// If you already have a TLS config you want to use, you can
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// simply set its GetCertificate field to
|
|
|
|
// NewDefault().GetCertificate.
|
2018-12-10 13:15:26 +10:00
|
|
|
//
|
|
|
|
// Calling this function signifies your acceptance to
|
|
|
|
// the CA's Subscriber Agreement and/or Terms of Service.
|
2021-09-24 06:35:51 +10:00
|
|
|
func ManageSync(ctx context.Context, domainNames []string) error {
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
DefaultACME.Agreed = true
|
2021-09-24 06:35:51 +10:00
|
|
|
return NewDefault().ManageSync(ctx, domainNames)
|
2019-10-16 16:19:57 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// ManageAsync is the same as ManageSync, except that
|
|
|
|
// certificates are managed asynchronously. This means
|
|
|
|
// that the function will return before certificates
|
|
|
|
// are ready, and errors that occur during certificate
|
|
|
|
// obtain or renew operations are only logged. It is
|
|
|
|
// vital that you monitor the logs if using this method,
|
|
|
|
// which is only recommended for automated/non-interactive
|
|
|
|
// environments.
|
2019-10-17 03:11:48 +10:00
|
|
|
func ManageAsync(ctx context.Context, domainNames []string) error {
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
DefaultACME.Agreed = true
|
2019-10-17 03:11:48 +10:00
|
|
|
return NewDefault().ManageAsync(ctx, domainNames)
|
2018-12-10 13:15:26 +10:00
|
|
|
}
|
|
|
|
|
2019-06-21 10:46:52 +10:00
|
|
|
// OnDemandConfig configures on-demand TLS (certificate
|
|
|
|
// operations as-needed, like during TLS handshakes,
|
|
|
|
// rather than immediately).
|
|
|
|
//
|
|
|
|
// When this package's high-level convenience functions
|
|
|
|
// are used (HTTPS, Manage, etc., where the Default
|
|
|
|
// config is used as a template), this struct regulates
|
|
|
|
// certificate operations using an implicit whitelist
|
|
|
|
// containing the names passed into those functions if
|
|
|
|
// no DecisionFunc is set. This ensures some degree of
|
|
|
|
// control by default to avoid certificate operations for
|
|
|
|
// aribtrary domain names. To override this whitelist,
|
|
|
|
// manually specify a DecisionFunc. To impose rate limits,
|
|
|
|
// specify your own DecisionFunc.
|
2018-12-10 13:15:26 +10:00
|
|
|
type OnDemandConfig struct {
|
2019-06-21 10:46:52 +10:00
|
|
|
// If set, this function will be called to determine
|
|
|
|
// whether a certificate can be obtained or renewed
|
|
|
|
// for the given name. If an error is returned, the
|
|
|
|
// request will be denied.
|
2023-10-30 23:47:31 +10:00
|
|
|
DecisionFunc func(ctx context.Context, name string) error
|
2018-12-10 13:15:26 +10:00
|
|
|
|
2023-05-12 04:36:44 +10:00
|
|
|
// Sources for getting new, unmanaged certificates.
|
|
|
|
// They will be invoked only during TLS handshakes
|
|
|
|
// before on-demand certificate management occurs,
|
|
|
|
// for certificates that are not already loaded into
|
|
|
|
// the in-memory cache.
|
|
|
|
//
|
|
|
|
// TODO: EXPERIMENTAL: subject to change and/or removal.
|
|
|
|
Managers []Manager
|
|
|
|
|
2023-05-07 04:30:48 +10:00
|
|
|
// List of allowed hostnames (SNI values) for
|
2019-06-21 10:46:52 +10:00
|
|
|
// deferred (on-demand) obtaining of certificates.
|
|
|
|
// Used only by higher-level functions in this
|
|
|
|
// package to persist the list of hostnames that
|
|
|
|
// the config is supposed to manage. This is done
|
|
|
|
// because it seems reasonable that if you say
|
|
|
|
// "Manage [domain names...]", then only those
|
|
|
|
// domain names should be able to have certs;
|
|
|
|
// we don't NEED this feature, but it makes sense
|
|
|
|
// for higher-level convenience functions to be
|
|
|
|
// able to retain their convenience (alternative
|
|
|
|
// is: the user manually creates a DecisionFunc
|
2023-05-07 04:30:48 +10:00
|
|
|
// that allows the same names it already passed
|
|
|
|
// into Manage) and without letting clients have
|
|
|
|
// their run of any domain names they want.
|
2023-07-01 10:44:53 +10:00
|
|
|
// Only enforced if len > 0. (This is a map to
|
|
|
|
// avoid O(n^2) performance; when it was a slice,
|
|
|
|
// we saw a 30s CPU profile for a config managing
|
|
|
|
// 110K names where 29s was spent checking for
|
|
|
|
// duplicates. Order is not important here.)
|
|
|
|
hostAllowlist map[string]struct{}
|
2018-12-10 13:15:26 +10:00
|
|
|
}
|
|
|
|
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
// PreChecker is an interface that can be optionally implemented by
|
|
|
|
// Issuers. Pre-checks are performed before each call (or batch of
|
|
|
|
// identical calls) to Issue(), giving the issuer the option to ensure
|
2020-03-08 11:56:16 +10:00
|
|
|
// it has all the necessary information/state.
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
type PreChecker interface {
|
2020-07-28 08:50:41 +10:00
|
|
|
PreCheck(ctx context.Context, names []string, interactive bool) error
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Issuer is a type that can issue certificates.
|
|
|
|
type Issuer interface {
|
|
|
|
// Issue obtains a certificate for the given CSR. It
|
|
|
|
// must honor context cancellation if it is long-running.
|
|
|
|
// It can also use the context to find out if the current
|
|
|
|
// call is part of a retry, via AttemptsCtxKey.
|
|
|
|
Issue(ctx context.Context, request *x509.CertificateRequest) (*IssuedCertificate, error)
|
|
|
|
|
|
|
|
// IssuerKey must return a string that uniquely identifies
|
|
|
|
// this particular configuration of the Issuer such that
|
|
|
|
// any certificates obtained by this Issuer will be treated
|
|
|
|
// as identical if they have the same SANs.
|
|
|
|
//
|
|
|
|
// Certificates obtained from Issuers with the same IssuerKey
|
|
|
|
// will overwrite others with the same SANs. For example, an
|
|
|
|
// Issuer might be able to obtain certificates from different
|
|
|
|
// CAs, say A and B. It is likely that the CAs have different
|
|
|
|
// use cases and purposes (e.g. testing and production), so
|
|
|
|
// their respective certificates should not overwrite eaach
|
|
|
|
// other.
|
|
|
|
IssuerKey() string
|
|
|
|
}
|
|
|
|
|
2020-07-28 08:50:41 +10:00
|
|
|
// Revoker can revoke certificates. Reason codes are defined
|
|
|
|
// by RFC 5280 §5.3.1: https://tools.ietf.org/html/rfc5280#section-5.3.1
|
|
|
|
// and are available as constants in our ACME library.
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
type Revoker interface {
|
2020-07-28 08:50:41 +10:00
|
|
|
Revoke(ctx context.Context, cert CertificateResource, reason int) error
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
}
|
|
|
|
|
2022-03-25 03:34:31 +10:00
|
|
|
// Manager is a type that manages certificates (keeps them renewed) such
|
|
|
|
// that we can get certificates during TLS handshakes to immediately serve
|
2022-02-18 07:37:50 +10:00
|
|
|
// to clients.
|
|
|
|
//
|
|
|
|
// TODO: This is an EXPERIMENTAL API. It is subject to change/removal.
|
2022-03-25 03:34:31 +10:00
|
|
|
type Manager interface {
|
2022-02-18 07:37:50 +10:00
|
|
|
// GetCertificate returns the certificate to use to complete the handshake.
|
|
|
|
// Since this is called during every TLS handshake, it must be very fast and not block.
|
2024-04-13 02:09:24 +10:00
|
|
|
// Returning any non-nil value indicates that this Manager manages a certificate
|
|
|
|
// for the described handshake. Returning (nil, nil) is valid and is simply treated as
|
|
|
|
// a no-op Return (nil, nil) when the Manager has no certificate for this handshake.
|
|
|
|
// Return an error or a certificate only if the Manager is supposed to get a certificate
|
|
|
|
// for this handshake. Returning (nil, nil) other Managers or Issuers to try to get
|
|
|
|
// a certificate for the handshake.
|
2022-02-18 07:37:50 +10:00
|
|
|
GetCertificate(context.Context, *tls.ClientHelloInfo) (*tls.Certificate, error)
|
|
|
|
}
|
|
|
|
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
// KeyGenerator can generate a private key.
|
|
|
|
type KeyGenerator interface {
|
|
|
|
// GenerateKey generates a private key. The returned
|
|
|
|
// PrivateKey must be able to expose its associated
|
|
|
|
// public key.
|
|
|
|
GenerateKey() (crypto.PrivateKey, error)
|
|
|
|
}
|
|
|
|
|
2023-06-14 14:05:29 +10:00
|
|
|
// IssuerPolicy is a type that enumerates how to
|
|
|
|
// choose which issuer to use. EXPERIMENTAL and
|
|
|
|
// subject to change.
|
|
|
|
type IssuerPolicy string
|
|
|
|
|
|
|
|
// Supported issuer policies. These are subject to change.
|
|
|
|
const (
|
|
|
|
// UseFirstIssuer uses the first issuer that
|
|
|
|
// successfully returns a certificate.
|
|
|
|
UseFirstIssuer = "first"
|
|
|
|
|
|
|
|
// UseFirstRandomIssuer shuffles the list of
|
|
|
|
// configured issuers, then uses the first one
|
|
|
|
// that successfully returns a certificate.
|
|
|
|
UseFirstRandomIssuer = "first_random"
|
|
|
|
)
|
|
|
|
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
// IssuedCertificate represents a certificate that was just issued.
|
|
|
|
type IssuedCertificate struct {
|
|
|
|
// The PEM-encoding of DER-encoded ASN.1 data.
|
|
|
|
Certificate []byte
|
|
|
|
|
|
|
|
// Any extra information to serialize alongside the
|
2024-05-08 01:46:03 +10:00
|
|
|
// certificate in storage. It MUST be serializable
|
|
|
|
// as JSON in order to be preserved.
|
2022-08-09 02:45:24 +10:00
|
|
|
Metadata any
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// CertificateResource associates a certificate with its private
|
|
|
|
// key and other useful information, for use in maintaining the
|
|
|
|
// certificate.
|
|
|
|
type CertificateResource struct {
|
|
|
|
// The list of names on the certificate;
|
|
|
|
// for convenience only.
|
|
|
|
SANs []string `json:"sans,omitempty"`
|
|
|
|
|
|
|
|
// The PEM-encoding of DER-encoded ASN.1 data
|
|
|
|
// for the cert or chain.
|
|
|
|
CertificatePEM []byte `json:"-"`
|
|
|
|
|
|
|
|
// The PEM-encoding of the certificate's private key.
|
|
|
|
PrivateKeyPEM []byte `json:"-"`
|
|
|
|
|
|
|
|
// Any extra information associated with the certificate,
|
|
|
|
// usually provided by the issuer implementation.
|
2024-05-08 01:46:03 +10:00
|
|
|
IssuerData json.RawMessage `json:"issuer_data,omitempty"`
|
2021-06-13 05:47:47 +10:00
|
|
|
|
|
|
|
// The unique string identifying the issuer of the
|
|
|
|
// certificate; internally useful for storage access.
|
2023-05-06 12:26:50 +10:00
|
|
|
issuerKey string
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// NamesKey returns the list of SANs as a single string,
|
|
|
|
// truncated to some ridiculously long size limit. It
|
|
|
|
// can act as a key for the set of names on the resource.
|
|
|
|
func (cr *CertificateResource) NamesKey() string {
|
|
|
|
sort.Strings(cr.SANs)
|
|
|
|
result := strings.Join(cr.SANs, ",")
|
|
|
|
if len(result) > 1024 {
|
2020-04-07 23:26:31 +10:00
|
|
|
const trunc = "_trunc"
|
|
|
|
result = result[:1024-len(trunc)] + trunc
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// Default contains the package defaults for the
|
|
|
|
// various Config fields. This is used as a template
|
2020-11-17 03:53:41 +10:00
|
|
|
// when creating your own Configs with New() or
|
|
|
|
// NewDefault(), and it is also used as the Config
|
|
|
|
// by all the high-level functions in this package
|
|
|
|
// that abstract away most configuration (HTTPS(),
|
|
|
|
// TLS(), Listen(), etc).
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
//
|
|
|
|
// The fields of this value will be used for Config
|
|
|
|
// fields which are unset. Feel free to modify these
|
|
|
|
// defaults, but do not use this Config by itself: it
|
|
|
|
// is only a template. Valid configurations can be
|
|
|
|
// obtained by calling New() (if you have your own
|
|
|
|
// certificate cache) or NewDefault() (if you only
|
|
|
|
// need a single config and want to use the default
|
2020-11-17 03:53:41 +10:00
|
|
|
// cache).
|
|
|
|
//
|
|
|
|
// Even if the Issuers or Storage fields are not set,
|
|
|
|
// defaults will be applied in the call to New().
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
var Default = Config{
|
2020-02-25 11:42:27 +10:00
|
|
|
RenewalWindowRatio: DefaultRenewalWindowRatio,
|
|
|
|
Storage: defaultFileStorage,
|
|
|
|
KeySource: DefaultKeyGenerator,
|
2022-09-27 02:19:28 +10:00
|
|
|
Logger: defaultLogger,
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
}
|
2018-12-10 13:15:26 +10:00
|
|
|
|
2022-09-27 02:19:28 +10:00
|
|
|
// defaultLogger is guaranteed to be a non-nil fallback logger.
|
|
|
|
var defaultLogger = zap.New(zapcore.NewCore(
|
|
|
|
zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig()),
|
|
|
|
os.Stderr,
|
|
|
|
zap.InfoLevel,
|
|
|
|
))
|
|
|
|
|
2018-12-10 13:15:26 +10:00
|
|
|
const (
|
|
|
|
// HTTPChallengePort is the officially-designated port for
|
|
|
|
// the HTTP challenge according to the ACME spec.
|
|
|
|
HTTPChallengePort = 80
|
|
|
|
|
|
|
|
// TLSALPNChallengePort is the officially-designated port for
|
|
|
|
// the TLS-ALPN challenge according to the ACME spec.
|
|
|
|
TLSALPNChallengePort = 443
|
|
|
|
)
|
|
|
|
|
|
|
|
// Port variables must remain their defaults unless you
|
|
|
|
// forward packets from the defaults to whatever these
|
|
|
|
// are set to; otherwise ACME challenges will fail.
|
|
|
|
var (
|
2018-12-12 08:48:47 +10:00
|
|
|
// HTTPPort is the port on which to serve HTTP
|
2020-11-17 03:53:41 +10:00
|
|
|
// and, as such, the HTTP challenge (unless
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// Default.AltHTTPPort is set).
|
2018-12-10 13:15:26 +10:00
|
|
|
HTTPPort = 80
|
|
|
|
|
2018-12-12 08:48:47 +10:00
|
|
|
// HTTPSPort is the port on which to serve HTTPS
|
2020-11-17 03:53:41 +10:00
|
|
|
// and, as such, the TLS-ALPN challenge
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// (unless Default.AltTLSALPNPort is set).
|
2018-12-10 13:15:26 +10:00
|
|
|
HTTPSPort = 443
|
|
|
|
)
|
|
|
|
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
// Variables for conveniently serving HTTPS.
|
2018-12-10 13:15:26 +10:00
|
|
|
var (
|
|
|
|
httpLn, httpsLn net.Listener
|
|
|
|
lnMu sync.Mutex
|
|
|
|
httpWg sync.WaitGroup
|
|
|
|
)
|
2020-05-13 01:28:56 +10:00
|
|
|
|
|
|
|
// Maximum size for the stack trace when recovering from panics.
|
2020-09-18 04:16:14 +10:00
|
|
|
const stackTraceBufferSize = 1024 * 128
|