Add issuer label to ocsp_filter_responses metric (#7546)
Add a new "issuer" label to the ocsp-responder's ocsp_filter_responses metric. This allows the count of responses served by ocsp-responder to be broken down by which intermediate issued the certificate (and OCSP response) in question. This approach has the benefit of being minimal. The filterSource is the only place within ocsp-responder that actually has knowledge of which intermediate issued the certificate/ocsp response. The HTTP-handling code above filterSource and the other redis and live-signing sources below filterSource have no knowledge of the set of issuing intermediates. They operate solely on the serial, because we guarantee that our serials are unique across all issuers. So adding the metric label here means that we don't have to make any other ocsp-responder code aware of the issuers. However, this approach has the cost of being somewhat surprising. Every source has a `counter` metric with a "result" label; adding this "issuer" label makes the filterSource's metric unique. Fixes https://github.com/letsencrypt/boulder/issues/7538
This commit is contained in:
parent
a69ba99760
commit
0f0c3e1432
|
@ -13,22 +13,26 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/jmhodges/clock"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/crypto/ocsp"
|
||||
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
"github.com/letsencrypt/boulder/issuance"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/crypto/ocsp"
|
||||
)
|
||||
|
||||
// responderID contains the SHA1 hashes of an issuer certificate's name and key,
|
||||
// exactly as the issuerNameHash and issuerKeyHash fields of an OCSP request
|
||||
// should be computed by OCSP clients that are compliant with RFC 5019, the
|
||||
// Lightweight OCSP Profile for High-Volume Environments. It also contains the
|
||||
// Subject Common Name of the issuer certificate, for our own observability.
|
||||
type responderID struct {
|
||||
nameHash []byte
|
||||
keyHash []byte
|
||||
nameHash []byte
|
||||
keyHash []byte
|
||||
commonName string
|
||||
}
|
||||
|
||||
// computeLightweightResponderID computes the SHA1 hashes of the certificate's
|
||||
// name and key, exactly as the issuerNameHash and issuerKeyHash fields should
|
||||
// be computed by OCSP clients that are compliant with RFC 5019, Lightweight
|
||||
// OCSP Profile for High-Volume Environments.
|
||||
// computeLightweightResponderID builds a responderID from an issuer certificate.
|
||||
func computeLightweightResponderID(ic *issuance.Certificate) (responderID, error) {
|
||||
// nameHash is the SHA1 hash over the DER encoding of the issuer certificate's
|
||||
// Subject Distinguished Name.
|
||||
|
@ -49,7 +53,7 @@ func computeLightweightResponderID(ic *issuance.Certificate) (responderID, error
|
|||
}
|
||||
keyHash := sha1.Sum(spki.PublicKey.RightAlign())
|
||||
|
||||
return responderID{nameHash[:], keyHash[:]}, nil
|
||||
return responderID{nameHash[:], keyHash[:], ic.Subject.CommonName}, nil
|
||||
}
|
||||
|
||||
type filterSource struct {
|
||||
|
@ -82,7 +86,7 @@ func NewFilterSource(issuerCerts []*issuance.Certificate, serialPrefixes []strin
|
|||
counter := prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "ocsp_filter_responses",
|
||||
Help: "Count of OCSP requests/responses by action taken by the filter",
|
||||
}, []string{"result"})
|
||||
}, []string{"result", "issuer"})
|
||||
stats.MustRegister(counter)
|
||||
|
||||
return &filterSource{
|
||||
|
@ -103,24 +107,26 @@ func (src *filterSource) Response(ctx context.Context, req *ocsp.Request) (*Resp
|
|||
iss, err := src.checkRequest(req)
|
||||
if err != nil {
|
||||
src.log.Debugf("Not responding to filtered OCSP request: %s", err.Error())
|
||||
src.counter.WithLabelValues("request_filtered").Inc()
|
||||
src.counter.WithLabelValues("request_filtered", "none").Inc()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
counter := src.counter.MustCurryWith(prometheus.Labels{"issuer": src.issuers[iss].commonName})
|
||||
|
||||
resp, err := src.wrapped.Response(ctx, req)
|
||||
if err != nil {
|
||||
src.counter.WithLabelValues("wrapped_error").Inc()
|
||||
counter.WithLabelValues("wrapped_error").Inc()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = src.checkResponse(iss, resp)
|
||||
if err != nil {
|
||||
src.log.Warningf("OCSP Response not sent for CA=%s, Serial=%s, err: %s", hex.EncodeToString(req.IssuerKeyHash), core.SerialToString(req.SerialNumber), err)
|
||||
src.counter.WithLabelValues("response_filtered").Inc()
|
||||
counter.WithLabelValues("response_filtered").Inc()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
src.counter.WithLabelValues("success").Inc()
|
||||
counter.WithLabelValues("success").Inc()
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue