View Source SiteEncrypt behaviour (site_encrypt v0.6.0)

Functions for interacting with sites managed by SiteEncrypt.

Summary

Types

Uniquely identifies the site certified via site_encrypt.

Callbacks

Invoked during startup to obtain certification info.

Invoked after the new certificate has been obtained.

Functions

Invoke this macro from certification/0 to return the fully shaped configuration.

Generates a new throwaway certificate for the given site.

Unconditionally obtains the new certificate for the site.

Returns the paths to the certificates and the key for the given site.

Refresh the configuration for a given endpoint.

Sets the new site certificate.

Types

Link to this opaque

certification()

View Source (opaque)
@opaque certification()
@type id() :: any()

Uniquely identifies the site certified via site_encrypt.

The actual value is determined by the adapter used to start the site. For example, if SiteEncrypt.Phoenix is used, the site id is the endpoint module.

@type pems() :: %{privkey: String.t(), cert: String.t(), chain: String.t()}

Callbacks

@callback certification() :: certification()

Invoked during startup to obtain certification info.

See configure/1 for details.

@callback handle_new_cert() :: any()

Invoked after the new certificate has been obtained.

Functions

Link to this macro

configure(opts)

View Source (macro)

Invoke this macro from certification/0 to return the fully shaped configuration.

The minimal implementation of certification/0 looks as follows:

@impl SiteEncrypt
def certification do
  SiteEncrypt.configure(
    client: :native,
    domains: ["mysite.com", "www.mysite.com"],
    emails: ["contact@abc.org", "another_contact@abc.org"],

    # By default the certs will be stored in tmp/site_encrypt_db, which is convenient for
    # local development. Make sure that tmp folder is gitignored.
    #
    # Set OS env var SITE_ENCRYPT_DB on staging/production hosts to some absolute path
    # outside of the deployment folder. Otherwise, the deploy may delete the db_folder,
    # which will effectively remove the generated key and certificate files.
    db_folder:
      System.get_env("SITE_ENCRYPT_DB", Path.join("tmp", "site_encrypt_db")),

    # set OS env var CERT_MODE to "staging" or "production" on staging/production hosts
    directory_url:
      case System.get_env("CERT_MODE", "local") do
        "local" -> {:internal, port: 4002}
        "staging" -> "https://acme-staging-v02.api.letsencrypt.org/directory"
        "production" -> "https://acme-v02.api.letsencrypt.org/directory"
      end
  )
end

Options

  • :client - Required. Can be either :native or :certbot.

    The native client requires no extra OS-level dependencies, and it runs faster, which is
    especially useful in a local development and tests. However, this client is very immature,
    possibly buggy, and incomplete.
    
    The certbot client is a wrapper around the [certbot](https://certbot.eff.org/) tool, which has
    to be installed on the host machine. This client is much more reliable than the native client,
    but it is also significantly slower.
    
    As a compromise between these two choices, you can consider running certbot client in
    production and during CI tests, while using the native client for local development and local
    tests.
  • :domains - Required. The list of domains for which the certificate will be obtained. Must

      contain at least one element.
  • :emails - Required. The list of email addresses which will be passed to the CA when

      creating the new account.
  • :db_folder (String.t/0) - Required. The folder where site_encrypt stores its data, such as certificates

      and account keys.
  • :directory_url - Required. The URL to CA directory resource. It can be either a string (e.g. "https://acme-v02.api.letsencrypt.org/directory") or a tuple in the shape of {:internal, port: local_acme_server_port}. In the latter case, an internal ACME server will be started at the given port. This is useful for local development and testing.

  • :backup (String.t/0) - Path to the backup file. If this option is provided, site_encrypt will backup the entire content of the :db_folder to the given path after every successful certification. When the system is being started, if the backup file exists while the :db_folder is empty, the system will perform a restore. The generated file will be a zipped tarball. If this option is not provided no backup will be generated.

  • :days_to_renew (pos_integer/0) - A positive integer which determines the next renewal attempt. For example, if this value is 30, the certificate will be renewed if it expires in 30 days or less. The default value is 30.

  • :log_level - Logger level for info messages. The default value is :info.

  • :key_size (pos_integer/0) - The size used for generating private keys. The default value is 4096.

  • :mode - When set to :auto, the certificate will be automatically created or renewed when needed.

    When set to :manual, you need to start the certification manually, using functions such as SiteEncrypt.force_certify/1 or SiteEncrypt.dry_certify/2. This can be useful for the first deploy, where you want to manually test the certification. In :test mix environment the mode is always :manual.

    The default value is :auto.

Link to this function

dry_certify(id, opts \\ [])

View Source
@spec dry_certify(id(), [{:directory_url, String.t()}]) :: {:ok, pems()} | :error

Generates a new throwaway certificate for the given site.

This function will perform the full certification at the given CA server. The new certificate won't be used by the site, nor stored on disk. This is mostly useful to test the certification through the staging CA server from the production server, which can be done as follows:

SiteEncrypt.dry_certify(
  MySystemWeb.Endpoint,
  directory_url: "https://acme-staging-v02.api.letsencrypt.org/directory"
)

If for some reasons you want to apply the certificate to the site, you can pass the returned pems to set_certificate/2.

@spec force_certify(id()) :: :ok | :error

Unconditionally obtains the new certificate for the site.

Be very careful when invoking this function in production, because you might trip some rate limit at the CA server (see here for Let's Encrypt limits).

@spec https_keys(id()) :: [
  keyfile: Path.t(),
  certfile: Path.t(),
  cacertfile: Path.t()
]

Returns the paths to the certificates and the key for the given site.

Refresh the configuration for a given endpoint.

Use this if your endpoint is dynamically retrieving the list of domains from the database for example and you want to update the configuration in the registry. In most cases it makes sense to call SiteEncrypt.force_certify/1 after the config has been refreshed.

Link to this function

set_certificate(id, pems)

View Source
@spec set_certificate(id(), pems()) :: :ok

Sets the new site certificate.

This operation doesn't persist the certificate in the client storage. As a result, if the client previously obtained and stored a valid certificate, that certificate will be used after the endpoint is restarted.