Skip to content

Fix angie ssl-listen pick, expose cert SAN domains#14

Merged
sergeyfast merged 2 commits into
masterfrom
fix/angie-ssl-listen-and-cert-san
May 14, 2026
Merged

Fix angie ssl-listen pick, expose cert SAN domains#14
sergeyfast merged 2 commits into
masterfrom
fix/angie-ssl-listen-and-cert-san

Conversation

@sergeyfast
Copy link
Copy Markdown
Contributor

@sergeyfast sergeyfast commented May 14, 2026

Summary

Two related fixes against angie discovery & SSL reporting, surfaced by production logs showing angie: API returned error status status=400 and a UI listing only 2 domains for a host with many access logs.

  • angie auto-discovery picks a usable listen port. When a server block has both listen 80; and listen 443 ssl;, findDirective used to overwrite the port with the last listen seen — ending up with http://127.0.0.1:443/status/, which makes angie return HTTP 400 («plain HTTP to HTTPS port»). Both the api collector and the ACME collector (which reuses the same URL) failed. Now non-ssl listen always wins; an ssl-only listen is still recorded (better than port 0) but logs a warning at startup so operators see the misconfig before scrape errors land.
  • SSL collector exposes every domain a cert serves. Multi-host certs from angie ACME pack several subdomains into one .pem via SAN. The collector previously emitted only Subject.CommonName, so the UI showed the primary CN but missed every other SAN entry. New info-style metric topsrv_ssl_certificate_san_info{path,domain} enumerates every DNS name in CN ∪ SANs (dedup, CN first). topsrv_ssl_certificate_expiry_seconds stays one series per cert file — NotAfter isn't duplicated across N rows. Convention follows blackbox_exporter's probe_ssl_last_chain_info. Operators join by path to get «days until expiry per served domain».

Docs: README.md, docs/metrics.md, and docs/promql-recipes.md updated with the new metric and a join example.

Test plan

  • make fmt lint — 0 issues
  • GOEXPERIMENT=jsonv2 go test ./... — full suite green
  • New unit tests:
    • TestDiscoverAngieEdgeCases/multiple_listen_—_non-ssl_wins_over_ssl
    • TestDiscoverAngieEdgeCases/ssl_listen_declared_first_—_non-ssl_still_wins
    • TestDiscoverAngieEdgeCases/ssl_flag_among_other_listen_params_(http2)
    • TestSSLCollectorSANInfo — 3-domain SAN (example.com placeholders), CN-in-DNSNames dedup
    • TestSSLCollectorNoCNorSAN — patological cert, san_info suppressed, expiry still visible
  • Deploy to an affected host: verify angie: auto-detected API url=http://127.0.0.1:80/status/ (not 443), no more HTTP 400 from collectors, and SSL Certificates UI lists all SAN domains for every multi-host ACME cert

- Auto-discovery for angie api/stub_status now prefers non-ssl
  listen when a server block has both ssl and non-ssl. Picking an
  ssl-only listen (e.g. `listen 443 ssl`) sent plain http to an
  HTTPS port and got HTTP 400 — same URL also broke the ACME
  collector. When only ssl listen exists, log a warning at
  startup so the misconfig is visible before scrape errors land
- Expose SAN domains as topsrv_ssl_certificate_san_info{path,
  domain}: one info series per DNS name in CN ∪ SANs (dedup, CN
  first). Multi-host certs (typical for angie ACME, which packs
  subdomains into one .pem) are no longer reduced to the CN in
  dashboards. expiry metric stays one series per cert — its value
  (NotAfter) isn't duplicated across N domain rows. Convention
  follows blackbox_exporter's probe_ssl_last_chain_info
- Tests: ssl-flag among other listen params (`listen 443 ssl
  http2`), ssl-first listen order, SAN dedup with CN-in-DNSNames,
  pathological no-CN-no-SAN cert (san_info suppressed, expiry
  still visible)
Replace real customer hostnames with example.com placeholders in
TestSSLCollectorSANInfo — same assertion, no behavior change.
@sergeyfast sergeyfast merged commit 01bc23d into master May 14, 2026
2 checks passed
@sergeyfast sergeyfast deleted the fix/angie-ssl-listen-and-cert-san branch May 14, 2026 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant