Help us shape the future of Go! Take the 2026 Go Developer Survey

cert-monitor

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: MIT

README

cert-monitor

Go Reference

Watches the TLS certificates of your hosts and tells you, once per stage, before something breaks. It's a single Go binary with a status page and Telegram and email alerts.

It checks:

  • Expiry: alerts at 30, 14, 7 and 1 days left (configurable), and again when a certificate has expired. Each alert is sent once per threshold per certificate. Renewing (a new fingerprint) starts over.
  • Chain of trust: an unknown issuer, a self-signed certificate, a missing intermediate, or an expired intermediate.
  • Hostname: the certificate must cover the name you connect with (SNI).
  • Weak crypto: SHA-1/MD5 signatures on the leaf or intermediates, RSA keys under 2048 bits, ECDSA under 256, and servers that negotiate TLS 1.0/1.1.

Hosts can use custom ports and an SNI that differs from the address you connect to (api.example.com@10.0.0.5:8443), which is useful for checking one backend behind a load balancer.

Who it's for

Small teams and self-hosters with a handful to a few hundred endpoints, such as web servers, mail servers on 993/465, or internal APIs. It's for people who want a heads-up on Telegram or by email rather than a full observability stack.

Install

Install the binary with Go:

go install github.com/AbdeldjalilChougui/cert-monitor/cmd/cert-monitor@latest

Quick start

go build -o cert-monitor ./cmd/cert-monitor

# One-off check (exit code 0 ok, 1 warning, 2 critical):
./cert-monitor -check example.com mail.example.com:993 api.example.com@10.0.0.5:8443

# Run continuously:
cp config.example.json config.json   # edit targets and notifiers
TELEGRAM_BOT_TOKEN=… TELEGRAM_CHAT_ID=… SMTP_PASSWORD=… ./cert-monitor -config config.json
open http://localhost:8090/

${VAR} references in the config are expanded from the environment, so secrets stay out of the file. Example output:

TARGET                        STATUS    DAYS   EXPIRES     DETAILS
github.com                    ok        43     2026-11-29
expired.badssl.com            critical  -4206  2015-04-12  certificate expired on 2015-04-12; chain: …
wrong.host.badssl.com         critical  72     2026-12-28  hostname: certificate is not valid for wrong.host.badssl.com (it covers *.badssl.com, badssl.com)
sha1-intermediate.badssl.com  critical  -2331  2020-05-30  …; weak signature: intermediate COMODO SSL CA is signed with SHA1-RSA
Config
key default
targets — host, host:port or sni@host:port
interval 6h time between check rounds
timeout 10s per-host dial and handshake timeout
thresholds [30,14,7,1] days-left alert stages
state_file (memory) where alert dedupe state is kept between restarts
listen :8090 status page: /, /api/status, POST /api/check, /healthz
telegram — bot_token, chat_id
smtp — addr, username, password, from, to (STARTTLS when offered)

How it works

  • Checking. It dials with InsecureSkipVerify and then verifies by hand with x509.Verify, VerifyHostname and its own algorithm checks. A broken certificate is reported in detail ("missing intermediate", "covers a.test, b.test") instead of failing with one handshake error. Eight hosts are checked in parallel.
  • Dedupe. The state per target is the leaf fingerprint, the most urgent threshold already alerted, the set of non-expiry problems, and a streak of connection errors. An expiry alert fires when days-left reaches a stage that hasn't been alerted for that certificate. Problems alert when their set changes, and a "resolved" message follows when it empties. Connection errors must happen twice in a row. State only advances when at least one notifier delivered, so a Telegram outage means a retry, not a lost alert. State is saved atomically (temp file + rename).
  • Status page. A server-rendered table sorted by urgency, plus JSON.

Tests

go test -race ./...

The tests generate their own PKI at runtime (a root, intermediates and leaves) and serve it with httptest TLS servers. They cover a healthy certificate, warning and critical expiry, an expired certificate, hostname mismatch, SNI picking the right certificate among several, self-signed and missing-intermediate chains, a 1024-bit RSA key, a SHA-1-signed leaf, a server capped at TLS 1.1, and connection failure. The alert tests cover the full threshold sequence including renewal, problem sets and resolution, the two-strikes rule for errors, state persistence, the Telegram Bot API (fake server) and SMTP (a minimal in-process SMTP server). The monitor tests cover one alert per stage across runs, retry after a failed delivery, and the status page and JSON.

Status and limitations

  • No OCSP or CRL revocation checks, no Certificate Transparency lookups, and no CAA checks.
  • STARTTLS protocols (SMTP on 25/587, IMAP on 143, and so on) aren't supported. Only implicit TLS ports (443, 465, 993, 8443…) are.
  • Alerts go to every configured notifier. There's no per-target routing or quiet hours.
  • The status page has no authentication. Bind it to localhost or put it behind a proxy if your host list is sensitive.
  • Weak-algorithm checks cover signatures, key sizes and protocol version, not individual cipher suites.

License

MIT. See LICENSE.

Directories

Path Synopsis
cmd
cert-monitor command
Command cert-monitor watches TLS certificates and alerts before they expire or break.
Command cert-monitor watches TLS certificates and alerts before they expire or break.
internal
alert
Package alert decides when a check result deserves a notification and sends it through Telegram or SMTP.
Package alert decides when a check result deserves a notification and sends it through Telegram or SMTP.
check
Package check connects to a TLS endpoint and inspects what it serves: expiry, chain of trust, hostname match, and weak algorithms or keys.
Package check connects to a TLS endpoint and inspects what it serves: expiry, chain of trust, hostname match, and weak algorithms or keys.
config
Package config loads the JSON config.
Package config loads the JSON config.
monitor
Package monitor runs checks on a schedule, keeps the latest results for the status page, and sends deduplicated alerts.
Package monitor runs checks on a schedule, keeps the latest results for the status page, and sends deduplicated alerts.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL