HTTP/2 multiplexing vs per-connection rate limits
Every request succeeded and the log stayed 33,000 entries behind. Switching transport gave me three connections instead of one, and changed nothing.
Reads newly issued SSL/TLS certificates from Chrome- and Apple-trusted Certificate Transparency logs and streams them over WebSocket or Server-Sent Events. Both RFC 6962 and static-ct-api logs are supported, in a single binary.
docker run -d -p 8080:8080 ghcr.io/reloading01/certstream-server-rust:latest
Certificate updates can be consumed over WebSocket or Server-Sent Events. Both transports carry the same certificate stream.
The server watches both classic get-entries logs and newer static-ct-api logs based on checkpoints and tiles. Both types run in the same process.
The same certificate is often submitted to several CT logs. Certificates are deduplicated by SHA-256 before broadcast, so clients receive one update per certificate within the configured deduplication window.
Watcher positions can be written to disk and restored after a restart, so each log does not start from scratch after a restart or upgrade.
Optional limits can be applied to the total connection count and per IP address.
Bearer-token authentication can be enabled for client connections. Tokens are compared in constant time, and multiple tokens and a custom header name are supported.
The configuration file can be watched for changes, so supported settings can be updated without restarting the process.
Each CT log is tracked independently. Repeated failures move a watcher through healthy, degraded, and unhealthy, with retries and exponential backoff behind a per-log circuit breaker.
Prometheus metrics are exposed at /metrics. An optional REST API serves server statistics, CT log status, and certificate lookup.
The certificate message format follows the one used by Calidog's certstream-server and certstream-server-go, so a client only needs a different WebSocket address.
import certstream certstream.listen_for_events(callback, url='wss://your-host:8080/')
# same certificate_update messages, # same all_domains, same leaf_cert wscat -c wss://your-host:8080/
Message types, field names and the leaf_cert shape are unchanged, so a parser written
against either predecessor keeps working. This implementation additionally reads static-ct-api
logs and deduplicates certificates seen across several logs. If only domain names are needed, the
/domains-only stream sends roughly 100 to 500 bytes per message instead of the 2 to
5 KB of the default stream.
A two-hour run against all 45 Chrome- and Apple-trusted logs, with the default configuration and one subscriber on the domains-only stream. Metrics were sampled every 30 seconds.
At the measured median that is about 36 million certificate updates a day. Each certificate is
serialized once and shared with every subscriber through an
Arc<PreSerializedMessage>, and serialization is skipped when no client is
connected. The memory behaviour is described in
358 MB resident, 52 MB in use.
Every request succeeded and the log stayed 33,000 entries behind. Switching transport gave me three connections instead of one, and changed nothing.
Three logs, zero errors, and 279,000 entries behind. The faster path was already there, behind an endpoint that returns 404.
A service that looked like it was leaking. It wasn't, and the fix was five settings the allocator had been running without.
certstream-server-rust is developed in my spare time and released under the MIT license. If you find it useful, starring the repository, reporting issues, or sharing it with someone who needs it is appreciated.
GitHub Sponsors is also available for anyone who wants to support development.