@ -12,6 +12,7 @@ import (
"io"
"io"
"net"
"net"
"net/http"
"net/http"
"net/netip"
"time"
"time"
"github.com/pkg/errors"
"github.com/pkg/errors"
@ -23,25 +24,33 @@ const expiresSoon = 7 * 24 * time.Hour // 7 days from now
// TLS returns a Probe that healthchecks a TLS endpoint.
// TLS returns a Probe that healthchecks a TLS endpoint.
//
//
// The ProbeFunc connects to a host name (host:port string), does a TLS
// The ProbeFunc connects to a host Port (host:port string), does a TLS
// handshake, verifies that the hostname matches the presented certificate,
// handshake, verifies that the hostname matches the presented certificate,
// checks certificate validity time and OCSP revocation status.
// checks certificate validity time and OCSP revocation status.
func TLS ( host name string ) ProbeFunc {
func TLS ( host Port string ) ProbeFunc {
return func ( ctx context . Context ) error {
return func ( ctx context . Context ) error {
return probeTLS ( ctx , hostname )
certDomain , _ , err := net . SplitHostPort ( hostPort )
if err != nil {
return err
}
return probeTLS ( ctx , certDomain , hostPort )
}
}
}
}
func probeTLS ( ctx context . Context , hostname string ) error {
// TLSWithIP is like TLS, but dials the provided dialAddr instead
host , _ , err := net . SplitHostPort ( hostname )
// of using DNS resolution. The certDomain is the expected name in
if err != nil {
// the cert (and the SNI name to send).
return err
func TLSWithIP ( certDomain string , dialAddr netip . AddrPort ) ProbeFunc {
return func ( ctx context . Context ) error {
return probeTLS ( ctx , certDomain , dialAddr . String ( ) )
}
}
}
dialer := & tls . Dialer { Config : & tls . Config { ServerName : host } }
func probeTLS ( ctx context . Context , certDomain string , dialHostPort string ) error {
conn , err := dialer . DialContext ( ctx , "tcp" , hostname )
dialer := & tls . Dialer { Config : & tls . Config { ServerName : certDomain } }
conn , err := dialer . DialContext ( ctx , "tcp" , dialHostPort )
if err != nil {
if err != nil {
return fmt . Errorf ( "connecting to %q: %w" , hostname , err )
return fmt . Errorf ( "connecting to %q: %w" , dialHostPort , err )
}
}
defer conn . Close ( )
defer conn . Close ( )