SSL Generator Block

Table of Contents

Self-Signed Certificates
Let’s Encrypt
Usage
Debug
Tests
Options Reference

This NixOS module is a block that implements the SSL certificate generator contract.

It is implemented by:

Self-Signed Certificates

Defined in /modules/blocks/ssl.nix.

To use self-signed certificates, we must first generate at least one Certificate Authority (CA):

shb.certs.cas.selfsigned.myca = {
  name = "My CA";
};

Every CA defined this way will be concatenated into the file /etc/ssl/certs/ca-certificates.cert which means those CAs and all certificates generated by those CAs will be automatically trusted.

We can then generate one or more certificates signed by that CA:

shb.certs.certs.selfsigned = {
  "example.com" = {
    ca = config.shb.certs.cas.selfsigned.myca;

    domain = "example.com";
    group = "nginx";
    reloadServices = [ "nginx.service" ];
  };
  "www.example.com" = {
    ca = config.shb.certs.cas.selfsigned.myca;

    domain = "www.example.com";
    group = "nginx";
  };
};

The group has been chosen to be nginx to be consistent with the examples further down in this document.

Let’s Encrypt

Defined in /modules/blocks/ssl.nix.

We can ask Let’s Encrypt to generate a certificate with:

shb.certs.certs.letsencrypt."example.com" = {
  domain = "example.com";
  group = "nginx";
  dnsProvider = "linode";
  adminEmail = "admin@example.com";
  credentialsFile = /path/to/secret/file;
  additionalEnvironment = {
    LINODE_HTTP_TIMEOUT = "10";
    LINODE_POLLING_INTERVAL = "10";
    LINODE_PROPAGATION_TIMEOUT = "240";
  };
};

The credential file’s content would be a key-value pair:

LINODE_TOKEN=XYZ...

For other providers, see the official instruction.

Usage

To use either a self-signed certificates or a Let’s Encrypt generated one, we can reference the path where the certificate and the private key are located:

config.shb.certs.certs.<implementation>.<name>.paths.cert
config.shb.certs.certs.<implementation>.<name>.paths.key
config.shb.certs.certs.<implementation>.<name>.systemdService

For example:

config.shb.certs.certs.selfsigned."example.com".paths.cert
config.shb.certs.certs.selfsigned."example.com".paths.key
config.shb.certs.certs.selfsigned."example.com".systemdService

The full CA bundle is generated by the following Systemd service, running after each individual generator finished:

config.shb.certs.systemdService

See also the SSL certificate generator usage for a more detailed usage example.

Debug

Each CA and Cert is generated by a systemd service whose name can be seen in the systemdService option. You can then see the latest errors messages using journalctl.

Tests

The self-signed implementation is tested in /tests/vm/ssl.nix.

Options Reference

shb.certs.cas.selfsigned

Generate a self-signed Certificate Authority.

Type: attribute set of (submodule)

Default: { }

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.cas.selfsigned.<name>.name

Certificate Authority Name. You can put what you want here, it will be displayed by the browser.

Type: string

Default: "Self Host Blocks Certificate"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.cas.selfsigned.<name>.paths

Paths where CA certs will be located.

This option implements the SSL Generator contract.

Type: anything

Default:

{
  cert = "/var/lib/certs/cas/‹name›.cert";
  key = "/var/lib/certs/cas/‹name›.key";
}

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.cas.selfsigned.<name>.paths.cert

Path to the cert file.

Type: path

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.cas.selfsigned.<name>.paths.key

Path to the key file.

Type: path

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.cas.selfsigned.<name>.systemdService

Systemd oneshot service used to generate the certs.

This option implements the SSL Generator contract.

Type: string

Default: "shb-certs-ca-‹name›.service"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt

Generate certificates signed by Let’s Encrypt.

Type: attribute set of (submodule)

Default: { }

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.additionalEnvironment

Additional environment variables used to configure the DNS provider.

For secrets, use shb.ssl.credentialsFile instead.

See the chosen provider’s documentation for available options.

Type: attribute set of string

Default: { }

Example:

{
  DNSPROVIDER_TIMEOUT = "10";
  DNSPROVIDER_PROPAGATION_TIMEOUT = "240";
}

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.adminEmail

Admin email in case certificate retrieval goes wrong.

Type: string

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.afterAndWants

Systemd service(s) that must start successfully before attempting to reach acme.

Type: list of string

Default: [ ]

Example:

[ "dnsmasq.service" ]

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.credentialsFile

Credentials file location for the chosen DNS provider.

The content of this file must expose environment variables as written in the documentation of each DNS provider.

For example, if the documentation says the credential must be located in the environment variable DNSPROVIDER_TOKEN, then the file content must be:

DNSPROVIDER_TOKEN=xyz

You can put non-secret environment variables here too or use shb.ssl.additionalcfg instead.

Type: null or path

Default: null

Example: "/run/secrets/ssl"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.debug

Enable debug logging

Type: boolean

Default: false

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.dnsProvider

DNS provider to use.

See https://go-acme.github.io/lego/dns/ for the list of supported providers.

If null is given, use instead the reverse proxy to validate the domain.

Type: null or string

Default: null

Example: "linode"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.dnsResolver

IP of a DNS server used to resolve hostnames.

Type: string

Default: "8.8.8.8"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.domain

Domain to generate a certificate for. This can be a wildcard domain like *.example.com.

Type: string

Example: "example.com"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.extraDomains

Other domains to generate a certificate for.

Type: list of string

Default: [ ]

Example:

[
  "sub1.example.com"
  "sub2.example.com"
]

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.group

Unix group owning this certificate.

Type: null or string

Default: "acme"

Example: "nginx"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.makeAvailableToUser

Make all certificates available to given user.

Type: null or string

Default: null

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.paths

Paths where certs will be located.

This option implements the SSL Generator contract.

Type: anything

Default:

{
  cert = "/var/lib/acme/‹name›/cert.pem";
  key = "/var/lib/acme/‹name›/key.pem";
}

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.paths.cert

Path to the cert file.

Type: path

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.paths.key

Path to the key file.

Type: path

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.reloadServices

The list of systemd services to call systemctl try-reload-or-restart on.

Type: list of string

Default: [ ]

Example:

[
  "nginx.service"
]

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.stagingServer

User Let’s Encrypt’s staging server.

Type: boolean

Default: false

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.letsencrypt.<name>.systemdService

Systemd oneshot service used to generate the certs.

This option implements the SSL Generator contract.

Type: string

Default: "shb-certs-cert-letsencrypt-‹name›.service"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned

Generate self-signed certificates signed by a Certificate Authority.

Type: attribute set of (submodule)

Default: { }

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.ca

CA used to generate this certificate. Only used for self-signed.

This contract input takes the contract output of the shb.certs.cas SSL block.

Type: null or (anything)

Default: null

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.ca.paths

Paths where the files for the CA will be located.

This option is the contract output of the shb.certs.cas SSL block.

Type: anything

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.ca.paths.cert

Path to the cert file.

Type: path

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.ca.paths.key

Path to the key file.

Type: path

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.ca.systemdService

Systemd oneshot service used to generate the CA. Ends with the .service suffix.

Use this if downstream services must wait for the certificates to be generated before starting.

Type: string

Example: "ca-generator.service"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.domain

Domain to generate a certificate for. This can be a wildcard domain like *.example.com.

Type: string

Example: "example.com"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.extraDomains

Other domains to generate a certificate for.

Type: list of string

Default: [ ]

Example:

[
  "sub1.example.com"
  "sub2.example.com"
]

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.group

Unix group owning this certificate.

Type: string

Default: "root"

Example: "nginx"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.paths

Paths where certs will be located.

This option implements the SSL Generator contract.

Type: anything

Default:

{
  cert = "/var/lib/certs/selfsigned/‹name›.cert";
  key = "/var/lib/certs/selfsigned/‹name›.key";
}

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.paths.cert

Path to the cert file.

Type: path

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.paths.key

Path to the key file.

Type: path

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.reloadServices

The list of systemd services to call systemctl try-reload-or-restart on.

Type: list of string

Default: [ ]

Example:

[
  "nginx.service"
]

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.certs.selfsigned.<name>.systemdService

Systemd oneshot service used to generate the certs.

This option implements the SSL Generator contract.

Type: string

Default: "shb-certs-cert-selfsigned-‹name›.service"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>
shb.certs.systemdService

Systemd oneshot service used to generate the Certificate Authority bundle.

Type: string

Default: "shb-ca-bundle.service"

Declared by:

<selfhostblocks/modules/blocks/ssl.nix>