Skip to content

Commit

Permalink
Added metric to return TLS Key Size and Information
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Jolly <[email protected]>
  • Loading branch information
djcode committed May 31, 2024
1 parent 6efcf0c commit f71756a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 3 deletions.
11 changes: 11 additions & 0 deletions prober/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ func ProbeGRPC(ctx context.Context, target string, module config.Module, registr
},
[]string{"fingerprint_sha256", "subject", "issuer", "subjectalternative"},
)

probeSSLLastKeyBits = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "probe_ssl_last_chain_key_bits",
Help: "Contains SSL leaf key information and size in bits",
},
[]string{"type", "fingerprint_sha256"},
)
)

for _, lv := range []string{"resolve"} {
Expand All @@ -124,6 +132,7 @@ func ProbeGRPC(ctx context.Context, target string, module config.Module, registr
registry.MustRegister(probeSSLEarliestCertExpiryGauge)
registry.MustRegister(probeTLSVersion)
registry.MustRegister(probeSSLLastInformation)
registry.MustRegister(probeSSLLastKeyBits)

if !strings.HasPrefix(target, "http://") && !strings.HasPrefix(target, "https://") {
target = "http://" + target
Expand Down Expand Up @@ -207,6 +216,8 @@ func ProbeGRPC(ctx context.Context, target string, module config.Module, registr
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)).Set(1)
keyType, keySize := getTLSKeyTypeAndSize(&tlsInfo.State)
probeSSLLastKeyBits.WithLabelValues(keyType, getTLSKeyFingerprint(&tlsInfo.State)).Set(float64(keySize))
} else {
isSSLGauge.Set(float64(0))
}
Expand Down
12 changes: 11 additions & 1 deletion prober/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,14 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr
[]string{"fingerprint_sha256", "subject", "issuer", "subjectalternative"},
)

probeSSLLastKeyBits = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "probe_ssl_last_chain_key_bits",
Help: "Contains SSL leaf key information and size in bits",
},
[]string{"type", "fingerprint_sha256"},
)

probeTLSVersion = prometheus.NewGaugeVec(
probeTLSInfoGaugeOpts,
[]string{"version"},
Expand Down Expand Up @@ -643,12 +651,14 @@ 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(probeSSLEarliestCertExpiryGauge, probeTLSVersion, probeTLSCipher, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation, probeSSLLastKeyBits)
probeSSLEarliestCertExpiryGauge.Set(float64(getEarliestCertExpiry(resp.TLS).Unix()))
probeTLSVersion.WithLabelValues(getTLSVersion(resp.TLS)).Set(1)
probeTLSCipher.WithLabelValues(getTLSCipher(resp.TLS)).Set(1)
probeSSLLastChainExpiryTimestampSeconds.Set(float64(getLastChainExpiry(resp.TLS).Unix()))
probeSSLLastInformation.WithLabelValues(getFingerprint(resp.TLS), getSubject(resp.TLS), getIssuer(resp.TLS), getDNSNames(resp.TLS)).Set(1)
keyType, keySize := getTLSKeyTypeAndSize(resp.TLS)
probeSSLLastKeyBits.WithLabelValues(keyType, getTLSKeyFingerprint(resp.TLS)).Set(float64(keySize))
if httpConfig.FailIfSSL {
level.Error(logger).Log("msg", "Final request was over SSL")
success = false
Expand Down
17 changes: 15 additions & 2 deletions prober/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ func ProbeTCP(ctx context.Context, target string, module config.Module, registry
},
[]string{"fingerprint_sha256", "subject", "issuer", "subjectalternative"},
)

probeSSLLastKeyBits := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "probe_ssl_last_chain_key_bits",
Help: "Contains SSL leaf certificate information",
},
[]string{"type", "fingerprint_sha256"},
)

probeTLSVersion := prometheus.NewGaugeVec(
probeTLSInfoGaugeOpts,
[]string{"version"},
Expand Down Expand Up @@ -126,11 +135,13 @@ 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(probeSSLEarliestCertExpiry, probeTLSVersion, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation, probeSSLLastKeyBits)
probeSSLEarliestCertExpiry.Set(float64(getEarliestCertExpiry(&state).Unix()))
probeTLSVersion.WithLabelValues(getTLSVersion(&state)).Set(1)
probeSSLLastChainExpiryTimestampSeconds.Set(float64(getLastChainExpiry(&state).Unix()))
probeSSLLastInformation.WithLabelValues(getFingerprint(&state), getSubject(&state), getIssuer(&state), getDNSNames(&state)).Set(1)
keyType, keySize := getTLSKeyTypeAndSize(&state)
probeSSLLastKeyBits.WithLabelValues(keyType, getTLSKeyFingerprint(&state)).Set(float64(keySize))
}
scanner := bufio.NewScanner(conn)
for i, qr := range module.TCP.QueryResponse {
Expand Down Expand Up @@ -192,11 +203,13 @@ func ProbeTCP(ctx context.Context, target string, module config.Module, registry

// Get certificate expiry.
state := tlsConn.ConnectionState()
registry.MustRegister(probeSSLEarliestCertExpiry, probeTLSVersion, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation)
registry.MustRegister(probeSSLEarliestCertExpiry, probeTLSVersion, probeSSLLastChainExpiryTimestampSeconds, probeSSLLastInformation, probeSSLLastKeyBits)
probeSSLEarliestCertExpiry.Set(float64(getEarliestCertExpiry(&state).Unix()))
probeTLSVersion.WithLabelValues(getTLSVersion(&state)).Set(1)
probeSSLLastChainExpiryTimestampSeconds.Set(float64(getLastChainExpiry(&state).Unix()))
probeSSLLastInformation.WithLabelValues(getFingerprint(&state), getSubject(&state), getIssuer(&state), getDNSNames(&state)).Set(1)
keyType, keySize := getTLSKeyTypeAndSize(&state)
probeSSLLastKeyBits.WithLabelValues(keyType, getTLSKeyFingerprint(&state)).Set(float64(keySize))
}
}
return true
Expand Down
19 changes: 19 additions & 0 deletions prober/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package prober
import (
"crypto/sha256"
"crypto/tls"
"crypto/rsa"
"crypto/ecdsa"
"encoding/hex"
"strings"
"time"
Expand Down Expand Up @@ -87,3 +89,20 @@ func getTLSVersion(state *tls.ConnectionState) string {
func getTLSCipher(state *tls.ConnectionState) string {
return tls.CipherSuiteName(state.CipherSuite)
}

func getTLSKeyTypeAndSize(state *tls.ConnectionState) (string, int) {
cert := state.PeerCertificates[0]
if key, ok := cert.PublicKey.(*ecdsa.PublicKey); ok {
return "ec", key.Curve.Params().BitSize
}
if key, ok := cert.PublicKey.(*rsa.PublicKey); ok {
return "rsa", key.N.BitLen()
}
return "", 0
}

func getTLSKeyFingerprint(state *tls.ConnectionState) string {
cert := state.PeerCertificates[0]
fingerprint := sha256.Sum256(cert.RawSubjectPublicKeyInfo)
return hex.EncodeToString(fingerprint[:])
}

0 comments on commit f71756a

Please sign in to comment.