Skip to content

Adding the metric for certificate start #1382

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion prober/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ func ProbeGRPC(ctx context.Context, target string, module config.Module, registr
Help: "Response HealthCheck response",
}, []string{"serving_status"})

probeSSLEarliestCertStartGauge = prometheus.NewGauge(sslEarliestCertStartGaugeOpts)

probeSSLEarliestCertExpiryGauge = prometheus.NewGauge(sslEarliestCertExpiryGaugeOpts)

probeTLSVersion = prometheus.NewGaugeVec(
Expand Down Expand Up @@ -200,8 +202,9 @@ func ProbeGRPC(ctx context.Context, target string, module config.Module, registr
if serverPeer != nil {
tlsInfo, tlsOk := serverPeer.AuthInfo.(credentials.TLSInfo)
if tlsOk {
registry.MustRegister(probeSSLEarliestCertExpiryGauge, probeTLSVersion, probeSSLLastInformation)
registry.MustRegister(probeSSLEarliestCertStartGauge, probeSSLEarliestCertExpiryGauge, probeTLSVersion, probeSSLLastInformation)
isSSLGauge.Set(float64(1))
probeSSLEarliestCertStartGauge.Set(float64(getEarliestCertStart(&tlsInfo.State).Unix()))
probeSSLEarliestCertExpiryGauge.Set(float64(getEarliestCertExpiry(&tlsInfo.State).Unix()))
probeTLSVersion.WithLabelValues(getTLSVersion(&tlsInfo.State)).Set(1)
probeSSLLastInformation.WithLabelValues(getFingerprint(&tlsInfo.State), getSubject(&tlsInfo.State), getIssuer(&tlsInfo.State), getDNSNames(&tlsInfo.State), getSerialNumber(&tlsInfo.State)).Set(1)
Expand Down
8 changes: 7 additions & 1 deletion prober/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,12 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr
Help: "Response HTTP status code",
})

probeSSLEarliestCertStartGauge = prometheus.NewGauge(sslEarliestCertStartGaugeOpts)

probeSSLEarliestCertExpiryGauge = prometheus.NewGauge(sslEarliestCertExpiryGaugeOpts)

probeSSLLastChainStartTimestampSeconds = prometheus.NewGauge(sslChainStartInTimeStampGaugeOpts)

probeSSLLastChainExpiryTimestampSeconds = prometheus.NewGauge(sslChainExpiryInTimeStampGaugeOpts)

probeSSLLastInformation = prometheus.NewGaugeVec(
Expand Down Expand Up @@ -714,10 +718,12 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr

if resp.TLS != nil {
isSSLGauge.Set(float64(1))
registry.MustRegister(probeSSLEarliestCertExpiryGauge, probeTLSVersion, probeTLSCipher, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation)
registry.MustRegister(probeSSLEarliestCertStartGauge, probeSSLEarliestCertExpiryGauge, probeTLSVersion, probeTLSCipher, probeSSLLastChainStartTimestampSeconds, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation)
probeSSLEarliestCertStartGauge.Set(float64(getEarliestCertStart(resp.TLS).Unix()))
probeSSLEarliestCertExpiryGauge.Set(float64(getEarliestCertExpiry(resp.TLS).Unix()))
probeTLSVersion.WithLabelValues(getTLSVersion(resp.TLS)).Set(1)
probeTLSCipher.WithLabelValues(getTLSCipher(resp.TLS)).Set(1)
probeSSLLastChainStartTimestampSeconds.Set(float64(getLastChainStart(resp.TLS).Unix()))
probeSSLLastChainExpiryTimestampSeconds.Set(float64(getLastChainExpiry(resp.TLS).Unix()))
probeSSLLastInformation.WithLabelValues(getFingerprint(resp.TLS), getSubject(resp.TLS), getIssuer(resp.TLS), getDNSNames(resp.TLS), getSerialNumber(resp.TLS)).Set(1)
if httpConfig.FailIfSSL {
Expand Down
14 changes: 13 additions & 1 deletion prober/prober.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,30 @@ import (
type ProbeFn func(ctx context.Context, target string, config config.Module, registry *prometheus.Registry, logger *slog.Logger) bool

const (
helpSSLEarliestCertExpiry = "Returns last SSL chain expiry in unixtime"
helpSSLEarliestCertStart = "Returns earliest SSL cert start in unixtime"
helpSSLEarliestCertExpiry = "Returns earliest SSL cert expiry in unixtime"
helpSSLChainStartInTimeStamp = "Returns last SSL chain start in timestamp"
helpSSLChainExpiryInTimeStamp = "Returns last SSL chain expiry in timestamp"
helpProbeTLSInfo = "Returns the TLS version used or NaN when unknown"
helpProbeTLSCipher = "Returns the TLS cipher negotiated during handshake"
)

var (
sslEarliestCertStartGaugeOpts = prometheus.GaugeOpts{
Name: "probe_ssl_earliest_cert_start",
Help: helpSSLEarliestCertStart,
}

sslEarliestCertExpiryGaugeOpts = prometheus.GaugeOpts{
Name: "probe_ssl_earliest_cert_expiry",
Help: helpSSLEarliestCertExpiry,
}

sslChainStartInTimeStampGaugeOpts = prometheus.GaugeOpts{
Name: "probe_ssl_last_chain_start_timestamp_seconds",
Help: helpSSLChainStartInTimeStamp,
}

sslChainExpiryInTimeStampGaugeOpts = prometheus.GaugeOpts{
Name: "probe_ssl_last_chain_expiry_timestamp_seconds",
Help: helpSSLChainExpiryInTimeStamp,
Expand Down
12 changes: 9 additions & 3 deletions prober/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ func probeExpectInfo(registry *prometheus.Registry, qr *config.QueryResponse, by
}

func ProbeTCP(ctx context.Context, target string, module config.Module, registry *prometheus.Registry, logger *slog.Logger) bool {
probeSSLEarliestCertStart := prometheus.NewGauge(sslEarliestCertStartGaugeOpts)
probeSSLEarliestCertExpiry := prometheus.NewGauge(sslEarliestCertExpiryGaugeOpts)
probeSSLLastChainStartTimestampSeconds := prometheus.NewGauge(sslChainStartInTimeStampGaugeOpts)
probeSSLLastChainExpiryTimestampSeconds := prometheus.NewGauge(sslChainExpiryInTimeStampGaugeOpts)
probeSSLLastInformation := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Expand Down Expand Up @@ -143,9 +145,11 @@ func ProbeTCP(ctx context.Context, target string, module config.Module, registry
}
if module.TCP.TLS {
state := conn.(*tls.Conn).ConnectionState()
registry.MustRegister(probeSSLEarliestCertExpiry, probeTLSVersion, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation)
registry.MustRegister(probeSSLEarliestCertStart, probeSSLEarliestCertExpiry, probeTLSVersion, probeSSLLastChainStartTimestampSeconds, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation)
probeSSLEarliestCertStart.Set(float64(getEarliestCertStart(&state).Unix()))
probeSSLEarliestCertExpiry.Set(float64(getEarliestCertExpiry(&state).Unix()))
probeTLSVersion.WithLabelValues(getTLSVersion(&state)).Set(1)
probeSSLLastChainStartTimestampSeconds.Set(float64(getLastChainStart(&state).Unix()))
probeSSLLastChainExpiryTimestampSeconds.Set(float64(getLastChainExpiry(&state).Unix()))
probeSSLLastInformation.WithLabelValues(getFingerprint(&state), getSubject(&state), getIssuer(&state), getDNSNames(&state), getSerialNumber(&state)).Set(1)
}
Expand Down Expand Up @@ -210,11 +214,13 @@ func ProbeTCP(ctx context.Context, target string, module config.Module, registry
conn = net.Conn(tlsConn)
scanner = bufio.NewScanner(conn)

// Get certificate expiry.
// Get certificate start and expiry.
state := tlsConn.ConnectionState()
registry.MustRegister(probeSSLEarliestCertExpiry, probeTLSVersion, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation)
registry.MustRegister(probeSSLEarliestCertStart, probeSSLEarliestCertExpiry, probeTLSVersion, probeSSLLastChainStartTimestampSeconds, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation)
probeSSLEarliestCertStart.Set(float64(getEarliestCertStart(&state).Unix()))
probeSSLEarliestCertExpiry.Set(float64(getEarliestCertExpiry(&state).Unix()))
probeTLSVersion.WithLabelValues(getTLSVersion(&state)).Set(1)
probeSSLLastChainStartTimestampSeconds.Set(float64(getLastChainStart(&state).Unix()))
probeSSLLastChainExpiryTimestampSeconds.Set(float64(getLastChainExpiry(&state).Unix()))
probeSSLLastInformation.WithLabelValues(getFingerprint(&state), getSubject(&state), getIssuer(&state), getDNSNames(&state), getSerialNumber(&state)).Set(1)
}
Expand Down
35 changes: 31 additions & 4 deletions prober/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,24 @@ import (
"time"
)

func getEarliestCertStart(state *tls.ConnectionState) time.Time {
earliestStart := time.Time{}
for _, cert := range state.PeerCertificates {
if (earliestStart.IsZero() || cert.NotBefore.Before(earliestStart)) && !cert.NotBefore.IsZero() {
earliestStart = cert.NotBefore
}
}
return earliestStart
}

func getEarliestCertExpiry(state *tls.ConnectionState) time.Time {
earliest := time.Time{}
earliestExpiry := time.Time{}
for _, cert := range state.PeerCertificates {
if (earliest.IsZero() || cert.NotAfter.Before(earliest)) && !cert.NotAfter.IsZero() {
earliest = cert.NotAfter
if (earliestExpiry.IsZero() || cert.NotAfter.Before(earliestExpiry)) && !cert.NotAfter.IsZero() {
earliestExpiry = cert.NotAfter
}
}
return earliest
return earliestExpiry
}

func getFingerprint(state *tls.ConnectionState) string {
Expand All @@ -53,6 +63,23 @@ func getDNSNames(state *tls.ConnectionState) string {
return strings.Join(cert.DNSNames, ",")
}

func getLastChainStart(state *tls.ConnectionState) time.Time {
lastChainStart := time.Time{}
for _, chain := range state.VerifiedChains {
earliestCertStart := time.Time{}
for _, cert := range chain {
if (earliestCertStart.IsZero() || cert.NotBefore.After(earliestCertStart)) && !cert.NotAfter.IsZero() {
earliestCertStart = cert.NotBefore
}
}
if lastChainStart.IsZero() || lastChainStart.After(earliestCertStart) {
lastChainStart = earliestCertStart
}

}
return lastChainStart
}

func getLastChainExpiry(state *tls.ConnectionState) time.Time {
lastChainExpiry := time.Time{}
for _, chain := range state.VerifiedChains {
Expand Down