From 82905131ccf52b074e1463326a9e8254379b401f Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Sat, 15 Feb 2025 10:26:35 -0500 Subject: [PATCH] *: basics of a DNS cert expiration alart Signed-off-by: Vincent Batts --- go.mod | 8 +++++++ main.go | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 go.mod create mode 100644 main.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..faecf5e --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module git.batts.cloud/vbatts/too-soon + +go 1.22.5 + +require ( + github.com/sirupsen/logrus v1.9.3 // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..76edb4f --- /dev/null +++ b/main.go @@ -0,0 +1,70 @@ +package main + +import ( + "crypto/x509" + "encoding/pem" + "flag" + "os" + "time" + + log "github.com/sirupsen/logrus" +) + +func main() { + fDays := flag.Int("d", 20, "number of days to alert on") + fDebug := flag.Bool("D", false, "debug mode") + + flag.Parse() + + if *fDebug { + log.SetLevel(log.DebugLevel) + } + + for _, file := range flag.Args() { + var certs []*x509.Certificate + + buf, err := os.ReadFile(file) + if err != nil { + log.Errorf("%q could not be read: %s", file, err) + continue + } + + more := true + for more { + block, rest := pem.Decode(buf) + log.Debugf("%q : %s", file, block.Type) + + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + log.Errorf("%q cert could not be parsed: %s", file, err) + continue + } + certs = append(certs, cert) + + if len(rest) == 0 { + more = false + } + // reset the buffer if there is more + buf = rest + } + + for _, cert := range certs { + if len(cert.DNSNames) == 0 { + continue + } + + hours := time.Duration(*fDays * -24) + alertTime := cert.NotAfter.Add(hours * time.Hour) + today := time.Now() + if today.After(alertTime) { + log.Warnf("%q : TIME TO RENEW CERTIFICATE (expires in less than %d days)", file, *fDays) + log.Infof("%q : %v", file, cert.NotAfter) + log.Infof("%q : %v", file, cert.DNSNames) + } else { + log.Debugf("%q : %v", file, cert.NotAfter) + log.Debugf("%q : %v", file, cert.DNSNames) + } + } + } + +}