1
0
mirror of https://github.com/ribbybibby/ssl_exporter.git synced 2025-07-15 23:54:18 +02:00

feat: add http_file prober

This commit is contained in:
Rob Best
2024-01-05 16:21:46 +00:00
parent 3a594bc445
commit dc001f0c32
6 changed files with 220 additions and 29 deletions

83
prober/http_file.go Normal file
View File

@ -0,0 +1,83 @@
package prober
import (
"context"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"github.com/ribbybibby/ssl_exporter/v2/config"
)
// ProbeHTTPFile performs a http_file probe
func ProbeHTTPFile(ctx context.Context, logger log.Logger, target string, module config.Module, registry *prometheus.Registry) error {
tlsConfig, err := config.NewTLSConfig(&module.TLSConfig)
if err != nil {
return err
}
targetURL, err := url.Parse(target)
if err != nil {
return err
}
// If server name isn't set, then use the target hostname
if tlsConfig.ServerName == "" {
tlsConfig.ServerName = targetURL.Hostname()
}
proxy := http.ProxyFromEnvironment
if module.HTTPS.ProxyURL.URL != nil {
proxy = http.ProxyURL(module.HTTPS.ProxyURL.URL)
}
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
Proxy: proxy,
DisableKeepAlives: true,
},
}
// Issue a GET request to the target
request, err := http.NewRequest(http.MethodGet, targetURL.String(), nil)
if err != nil {
return err
}
request = request.WithContext(ctx)
resp, err := client.Do(request)
if err != nil {
return err
}
defer func() {
_, err := io.Copy(ioutil.Discard, resp.Body)
if err != nil {
level.Error(logger).Log("msg", err)
}
resp.Body.Close()
}()
data, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
certs, err := decodeCertificates(data)
if err != nil {
return err
}
if len(certs) == 0 {
return fmt.Errorf("no certificates in response body")
}
return collectCertificateMetrics(certs, registry)
}

81
prober/http_file_test.go Normal file
View File

@ -0,0 +1,81 @@
package prober
import (
"context"
"crypto/x509"
"encoding/pem"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/ribbybibby/ssl_exporter/v2/config"
"github.com/ribbybibby/ssl_exporter/v2/test"
)
func TestProbeHTTPFile(t *testing.T) {
certPEM, _ := test.GenerateTestCertificate(time.Now().Add(time.Hour * 1))
block, _ := pem.Decode([]byte(certPEM))
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
t.Fatalf("parsing cert: %s", err)
}
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(certPEM)
}))
server.Start()
defer server.Close()
registry := prometheus.NewRegistry()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := ProbeHTTPFile(ctx, newTestLogger(), server.URL+"/file", config.Module{}, registry); err != nil {
t.Fatalf("error: %s", err)
}
checkCertificateMetrics(cert, registry, t)
}
func TestProbeHTTPFile_HTTPS(t *testing.T) {
server, certPEM, _, caFile, teardown, err := test.SetupHTTPSServer()
if err != nil {
t.Fatalf(err.Error())
}
defer teardown()
block, _ := pem.Decode([]byte(certPEM))
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
t.Fatalf("parsing cert: %s", err)
}
server.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(certPEM)
})
server.StartTLS()
defer server.Close()
module := config.Module{
TLSConfig: config.TLSConfig{
CAFile: caFile,
InsecureSkipVerify: false,
},
}
registry := prometheus.NewRegistry()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := ProbeHTTPFile(ctx, newTestLogger(), server.URL+"/file", module, registry); err != nil {
t.Fatalf("error: %s", err)
}
checkCertificateMetrics(cert, registry, t)
}

View File

@ -13,6 +13,7 @@ var (
Probers = map[string]ProbeFn{
"https": ProbeHTTPS,
"http": ProbeHTTPS,
"http_file": ProbeHTTPFile,
"tcp": ProbeTCP,
"file": ProbeFile,
"kubernetes": ProbeKubernetes,