caddytls: Require 'ask' endpoint for on-demand TLS

This commit is contained in:
Matthew Holt 2023-03-14 10:02:44 -06:00
parent 6cc3cbbc69
commit b97c76fb47
No known key found for this signature in database
GPG Key ID: 2A349DD577D586A5
1 changed files with 18 additions and 14 deletions

View File

@ -168,22 +168,26 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error {
// on-demand TLS // on-demand TLS
var ond *certmagic.OnDemandConfig var ond *certmagic.OnDemandConfig
if ap.OnDemand { if ap.OnDemand {
// ask endpoint is now required after a number of negligence cases causing abuse
if tlsApp.Automation == nil || tlsApp.Automation.OnDemand == nil || tlsApp.Automation.OnDemand.Ask == "" {
return fmt.Errorf("on-demand TLS cannot be enabled without an 'ask' endpoint to prevent abuse; please refer to documentation for details")
}
ond = &certmagic.OnDemandConfig{ ond = &certmagic.OnDemandConfig{
DecisionFunc: func(name string) error { DecisionFunc: func(name string) error {
// if an "ask" endpoint was defined, consult it first if err := onDemandAskRequest(tlsApp.logger, tlsApp.Automation.OnDemand.Ask, name); err != nil {
if tlsApp.Automation != nil && // distinguish true errors from denials, because it's important to elevate actual errors
tlsApp.Automation.OnDemand != nil && if errors.Is(err, errAskDenied) {
tlsApp.Automation.OnDemand.Ask != "" { tlsApp.logger.Debug("certificate issuance denied",
if err := onDemandAskRequest(tlsApp.logger, tlsApp.Automation.OnDemand.Ask, name); err != nil { zap.String("ask_endpoint", tlsApp.Automation.OnDemand.Ask),
// distinguish true errors from denials, because it's important to log actual errors zap.String("domain", name),
if !errors.Is(err, errAskDenied) { zap.Error(err))
tlsApp.logger.Error("request to 'ask' endpoint failed", } else {
zap.Error(err), tlsApp.logger.Error("request to 'ask' endpoint failed",
zap.String("endpoint", tlsApp.Automation.OnDemand.Ask), zap.String("ask_endpoint", tlsApp.Automation.OnDemand.Ask),
zap.String("domain", name)) zap.String("domain", name),
} zap.Error(err))
return err
} }
return err
} }
// check the rate limiter last because // check the rate limiter last because
// doing so makes a reservation // doing so makes a reservation
@ -404,7 +408,7 @@ type OnDemandConfig struct {
// issuance of certificates from handshakes. // issuance of certificates from handshakes.
RateLimit *RateLimit `json:"rate_limit,omitempty"` RateLimit *RateLimit `json:"rate_limit,omitempty"`
// If Caddy needs to obtain or renew a certificate // REQUIRED. If Caddy needs to obtain/renew a certificate
// during a TLS handshake, it will perform a quick // during a TLS handshake, it will perform a quick
// HTTP request to this URL to check if it should be // HTTP request to this URL to check if it should be
// allowed to try to get a certificate for the name // allowed to try to get a certificate for the name