mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-13 22:51:08 -05:00
letsencrypt: Don't maintain assets of sites we don't maintain
This commit is contained in:
parent
e3be524447
commit
64cded8246
1 changed files with 41 additions and 20 deletions
|
@ -20,8 +20,9 @@ import (
|
||||||
|
|
||||||
// Activate sets up TLS for each server config in configs
|
// Activate sets up TLS for each server config in configs
|
||||||
// as needed. It only skips the config if the cert and key
|
// as needed. It only skips the config if the cert and key
|
||||||
// are already provided or if plaintext http is explicitly
|
// are already provided, if plaintext http is explicitly
|
||||||
// specified as the port.
|
// specified as the port, TLS is explicitly disabled, or
|
||||||
|
// the host looks like a loopback or wildcard address.
|
||||||
//
|
//
|
||||||
// This function may prompt the user to provide an email
|
// This function may prompt the user to provide an email
|
||||||
// address if none is available through other means. It
|
// address if none is available through other means. It
|
||||||
|
@ -33,10 +34,14 @@ import (
|
||||||
//
|
//
|
||||||
// Also note that calling this function activates asset
|
// Also note that calling this function activates asset
|
||||||
// management automatically, which <TODO>.
|
// management automatically, which <TODO>.
|
||||||
|
//
|
||||||
|
// Activate returns the updated list of configs, since
|
||||||
|
// some may have been appended, for example, to redirect
|
||||||
|
// plaintext HTTP requests to their HTTPS counterpart.
|
||||||
func Activate(configs []server.Config) ([]server.Config, error) {
|
func Activate(configs []server.Config) ([]server.Config, error) {
|
||||||
// TODO: Is multiple activation (before a deactivation) an error?
|
// TODO: Is multiple activation (before a deactivation) an error?
|
||||||
|
|
||||||
// First identify and configure any eligible hosts for which
|
// Identify and configure any eligible hosts for which
|
||||||
// we already have certs and keys in storage from last time.
|
// we already have certs and keys in storage from last time.
|
||||||
configLen := len(configs) // avoid infinite loop since this loop appends plaintext to the slice
|
configLen := len(configs) // avoid infinite loop since this loop appends plaintext to the slice
|
||||||
for i := 0; i < configLen; i++ {
|
for i := 0; i < configLen; i++ {
|
||||||
|
@ -45,19 +50,22 @@ func Activate(configs []server.Config) ([]server.Config, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// First renew any existing certificates that need it
|
// Filter the configs by what we can maintain automatically
|
||||||
renewCertificates(configs)
|
filteredConfigs := filterConfigs(configs)
|
||||||
|
|
||||||
|
// Renew any existing certificates that need renewal
|
||||||
|
renewCertificates(filteredConfigs)
|
||||||
|
|
||||||
// Group configs by LE email address; this will help us
|
// Group configs by LE email address; this will help us
|
||||||
// reduce round-trips when getting the certs.
|
// reduce round-trips when getting the certs.
|
||||||
initMap, err := groupConfigsByEmail(configs)
|
groupedConfigs, err := groupConfigsByEmail(filteredConfigs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return configs, err
|
return configs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop through each email address and obtain certs; we can obtain more
|
// Loop through each email address and obtain certs; this way, we can obtain more
|
||||||
// than one certificate per email address, and still save them individually.
|
// than one certificate per email address, and still save them individually.
|
||||||
for leEmail, serverConfigs := range initMap {
|
for leEmail, serverConfigs := range groupedConfigs {
|
||||||
// make client to service this email address with CA server
|
// make client to service this email address with CA server
|
||||||
client, err := newClient(leEmail)
|
client, err := newClient(leEmail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -82,8 +90,9 @@ func Activate(configs []server.Config) ([]server.Config, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Deactivate() // in case previous caller wasn't clean about it
|
||||||
stopChan = make(chan struct{})
|
stopChan = make(chan struct{})
|
||||||
go maintainAssets(configs, stopChan)
|
go maintainAssets(filteredConfigs, stopChan)
|
||||||
|
|
||||||
return configs, nil
|
return configs, nil
|
||||||
}
|
}
|
||||||
|
@ -102,14 +111,13 @@ func Deactivate() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// groupConfigsByEmail groups configs by the Let's Encrypt email address
|
// filterConfigs filters and returns configs that are eligible for automatic
|
||||||
// associated to them or to the default Let's Encrypt email address. If the
|
// TLS by skipping configs that do not qualify for automatic maintenance
|
||||||
// default email is not available, the user will be prompted to provide one.
|
// of assets. Configurations with a manual TLS configuration or that already
|
||||||
//
|
// have an HTTPS counterpart host defined will be skipped.
|
||||||
// This function also filters out configs that don't need extra TLS help.
|
func filterConfigs(configs []server.Config) []server.Config {
|
||||||
// Configurations with a manual TLS configuration or one that is already
|
var filtered []server.Config
|
||||||
// found in storage will not be added to any group.
|
|
||||||
func groupConfigsByEmail(configs []server.Config) (map[string][]*server.Config, error) {
|
|
||||||
// configQualifies returns true if cfg qualifes for automatic LE activation
|
// configQualifies returns true if cfg qualifes for automatic LE activation
|
||||||
configQualifies := func(cfg server.Config) bool {
|
configQualifies := func(cfg server.Config) bool {
|
||||||
return cfg.TLS.Certificate == "" && // user could provide their own cert and key
|
return cfg.TLS.Certificate == "" && // user could provide their own cert and key
|
||||||
|
@ -131,11 +139,22 @@ func groupConfigsByEmail(configs []server.Config) (map[string][]*server.Config,
|
||||||
!hostHasOtherScheme(cfg.Host, "https", configs)
|
!hostHasOtherScheme(cfg.Host, "https", configs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, cfg := range configs {
|
||||||
|
if configQualifies(cfg) {
|
||||||
|
filtered = append(filtered, cfg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered
|
||||||
|
}
|
||||||
|
|
||||||
|
// groupConfigsByEmail groups configs by user email address. The returned map is
|
||||||
|
// a map of email address to the configs that are serviced under that account.
|
||||||
|
// If an email address is not available, the user will be prompted to provide one.
|
||||||
|
// This function assumes that all configs passed in qualify for automatic management.
|
||||||
|
func groupConfigsByEmail(configs []server.Config) (map[string][]*server.Config, error) {
|
||||||
initMap := make(map[string][]*server.Config)
|
initMap := make(map[string][]*server.Config)
|
||||||
for i := 0; i < len(configs); i++ {
|
for i := 0; i < len(configs); i++ {
|
||||||
if !configQualifies(configs[i]) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
leEmail := getEmail(configs[i])
|
leEmail := getEmail(configs[i])
|
||||||
if leEmail == "" {
|
if leEmail == "" {
|
||||||
return nil, errors.New("must have email address to serve HTTPS without existing certificate and key")
|
return nil, errors.New("must have email address to serve HTTPS without existing certificate and key")
|
||||||
|
@ -260,6 +279,8 @@ func saveCertsAndKeys(certificates []acme.CertificateResource) error {
|
||||||
|
|
||||||
// autoConfigure enables TLS on cfg and appends, if necessary, a new config
|
// autoConfigure enables TLS on cfg and appends, if necessary, a new config
|
||||||
// to allConfigs that redirects plaintext HTTP to its new HTTPS counterpart.
|
// to allConfigs that redirects plaintext HTTP to its new HTTPS counterpart.
|
||||||
|
// It expects the certificate and key to already be in storage. It returns
|
||||||
|
// the new list of allConfigs.
|
||||||
func autoConfigure(cfg *server.Config, allConfigs []server.Config) []server.Config {
|
func autoConfigure(cfg *server.Config, allConfigs []server.Config) []server.Config {
|
||||||
bundleBytes, err := ioutil.ReadFile(storage.SiteCertFile(cfg.Host))
|
bundleBytes, err := ioutil.ReadFile(storage.SiteCertFile(cfg.Host))
|
||||||
// TODO: Handle these errors better
|
// TODO: Handle these errors better
|
||||||
|
|
Loading…
Reference in a new issue