@marcel91200 / caddy Mirror · read-only / commits / 3aabbc49
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 15:30 UTC

caddytls: Log error if ask request fails

Errors returned from the DecisionFunc (whether to get a cert on-demand) are used as a signal whether to allow a cert or not; *any* error will forbid cert issuance. We bubble up the error all the way to the caller, but that caller is the Go standard library which might gobble it up. Now we explicitly log connection errors so sysadmins can ensure their ask endpoints are working. Thanks to our sponsor AppCove for reporting this!

Matthew Holt committed Aug 23, 2022 at 22:28 UTC 3aabbc49a2eccc66a20d3223e9fb2925cbbdd0d4
2 files changed +37 -24
modules/caddytls/acmeissuer.go
+28 -24
@@ -17,6 +17,7 @@ package caddytls
17 import (
18 "context"
19 "crypto/x509"
20 + "errors"
21 "fmt"
22 "net/url"
23 "os"
@@ -250,28 +251,27 @@ func (iss *ACMEIssuer) GetACMEIssuer() *ACMEIssuer { return iss }
251
252 // UnmarshalCaddyfile deserializes Caddyfile tokens into iss.
253 //
253 -// ... acme [<directory_url>] {
254 -// dir <directory_url>
255 -// test_dir <test_directory_url>
256 -// email <email>
257 -// timeout <duration>
258 -// disable_http_challenge
259 -// disable_tlsalpn_challenge
260 -// alt_http_port <port>
261 -// alt_tlsalpn_port <port>
262 -// eab <key_id> <mac_key>
263 -// trusted_roots <pem_files...>
264 -// dns <provider_name> [<options>]
265 -// propagation_delay <duration>
266 -// propagation_timeout <duration>
267 -// resolvers <dns_servers...>
268 -// dns_challenge_override_domain <domain>
269 -// preferred_chains [smallest] {
270 -// root_common_name <common_names...>
271 -// any_common_name <common_names...>
272 -// }
273 -// }
274 -//
254 +// ... acme [<directory_url>] {
255 +// dir <directory_url>
256 +// test_dir <test_directory_url>
257 +// email <email>
258 +// timeout <duration>
259 +// disable_http_challenge
260 +// disable_tlsalpn_challenge
261 +// alt_http_port <port>
262 +// alt_tlsalpn_port <port>
263 +// eab <key_id> <mac_key>
264 +// trusted_roots <pem_files...>
265 +// dns <provider_name> [<options>]
266 +// propagation_delay <duration>
267 +// propagation_timeout <duration>
268 +// resolvers <dns_servers...>
269 +// dns_challenge_override_domain <domain>
270 +// preferred_chains [smallest] {
271 +// root_common_name <common_names...>
272 +// any_common_name <common_names...>
273 +// }
274 +// }
275 func (iss *ACMEIssuer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
276 for d.Next() {
277 if d.NextArg() {
@@ -494,8 +494,7 @@ func onDemandAskRequest(ask string, name string) error {
494 resp.Body.Close()
495
496 if resp.StatusCode < 200 || resp.StatusCode > 299 {
497 - return fmt.Errorf("certificate for hostname '%s' not allowed; non-2xx status code %d returned from %v",
498 - name, resp.StatusCode, ask)
497 + return fmt.Errorf("%s: %w %s - non-2xx status code %d", name, errAskDenied, ask, resp.StatusCode)
498 }
499
500 return nil
@@ -568,6 +567,11 @@ type ChainPreference struct {
567 AnyCommonName []string `json:"any_common_name,omitempty"`
568 }
569
570 +// errAskDenied is an error that should be wrapped or returned when the
571 +// configured "ask" endpoint does not allow a certificate to be issued,
572 +// to distinguish that from other errors such as connection failure.
573 +var errAskDenied = errors.New("certificate not allowed by ask endpoint")
574 +
575 // Interface guards
576 var (
577 _ certmagic.PreChecker = (*ACMEIssuer)(nil)
modules/caddytls/automation.go
+9
@@ -16,6 +16,7 @@ package caddytls
16
17 import (
18 "encoding/json"
19 + "errors"
20 "fmt"
21 "net/http"
22 "time"
@@ -23,6 +24,7 @@ import (
24 "github.com/caddyserver/caddy/v2"
25 "github.com/caddyserver/certmagic"
26 "github.com/mholt/acmez"
27 + "go.uber.org/zap"
28 )
29
30 // AutomationConfig governs the automated management of TLS certificates.
@@ -174,6 +176,13 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error {
176 tlsApp.Automation.OnDemand.Ask != "" {
177 err := onDemandAskRequest(tlsApp.Automation.OnDemand.Ask, name)
178 if err != nil {
179 + // distinguish true errors from denials, because it's important to log actual errors
180 + if !errors.Is(err, errAskDenied) {
181 + tlsApp.logger.Error("request to 'ask' endpoint failed",
182 + zap.Error(err),
183 + zap.String("endpoint", tlsApp.Automation.OnDemand.Ask),
184 + zap.String("domain", name))
185 + }
186 return err
187 }
188 }