Sovite.TLS.CertStore (sovite v0.2.0)

Copy Markdown View Source

Holds server certificates, picks one per connection by SNI (RFC 6066), and reloads them when their files change.

children = [
  {Sovite.TLS.CertStore,
   name: MyApp.Certs,
   certificates: [
     %{cert_file: "/etc/tls/mx.example.com.pem", key_file: "/etc/tls/mx.example.com.key"},
     %{cert_file: "/etc/tls/mail.example.org.pem", key_file: "/etc/tls/mail.example.org.key"}
   ]}
]

ssl_opts = Sovite.TLS.CertStore.server_options(MyApp.Certs)

A client asking for a name gets every certificate valid for it (for example both an RSA and an ECDSA one; :ssl picks what the client supports). Clients without SNI, or asking for an unknown name, get the default: the first certificate, with any others for exactly the same names.

Files are checked every :reload_interval and reloaded when their size, modification time, or inode changes. A file that fails to load keeps its previous certificate, so a half-written renewal does not take TLS down. reload/1 forces a check.

Options

  • :certificates - a list of %{cert_file, key_file} maps, see Sovite.TLS.Certificate.load/2. Add optional: true to skip a pair whose files do not exist yet, such as one an ACME client will write. Required.
  • :tls - options for Sovite.TLS.server_options/1, such as :min_version and :ciphers.
  • :reload_interval - milliseconds, or nil to never check. Defaults to 60 seconds.
  • :name - registered name.

Starting fails if a required certificate cannot be loaded.

Telemetry

  • [:sovite, :tls, :certificate, :loaded] - %{}, %{cert_file, names, not_after}
  • [:sovite, :tls, :certificate, :error] - %{}, %{cert_file, reason} (a Sovite.TLS.Certificate.error())

Summary

Functions

Returns the loaded certificates, default first.

Checks the files now and reloads what changed.

Returns :ssl server options for the current certificates, or nil when none is loaded. Call it per connection, so reloaded certificates apply to new connections.

Starts the store.

Functions

certificates(store)

@spec certificates(GenServer.server()) :: [Sovite.TLS.Certificate.t()]

Returns the loaded certificates, default first.

reload(store)

@spec reload(GenServer.server()) :: :ok

Checks the files now and reloads what changed.

server_options(store)

@spec server_options(GenServer.server()) :: [:ssl.tls_server_option()] | nil

Returns :ssl server options for the current certificates, or nil when none is loaded. Call it per connection, so reloaded certificates apply to new connections.

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

Starts the store.