mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-29 19:18:57 -04:00
The Tailscale daemon only refreshed TLS certs as a side effect of inbound TLS handshakes or "tailscale cert" CLI calls. A node that doesn't see inbound traffic during the renewal window silently rolls past expiry. Add a once-per-hour background loop on LocalBackend that enumerates Serve and Funnel HTTPS hostnames (filtered against the netmap's CertDomains so we don't poke ACME for other nodes' service hostnames) and calls the existing GetCertPEM path. The renewal decision (ARI window, then 2/3 expiry fallback) is unchanged; the loop just guarantees it runs. For visibility during initial issuance or restart with a long-expired cached cert, add a "tls-cert-pending" health Warnable that's set while ACME is in flight and no usable cached cert exists. Async renewal of a still-valid cert intentionally doesn't fire it. Expose the structured health.State (with WarnableCode keys) via a new /localapi/v0/health endpoint, registered from a new feature/health package and conditionally pulled in via feature/condregister so it can be linked out with ts_omit_health. tailscale cert polls that endpoint while CertPairWithValidity blocks and prints the pending warning to stderr, matching by WarnableCode rather than by rendered text. Fixes #19911 Fixes #19912 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: I144e46c40e957b2e879587decace32a523a6eade