160 lines
5.1 KiB
Markdown
160 lines
5.1 KiB
Markdown
# SSL Generator Block {#block-ssl}
|
|
|
|
This NixOS module is a block that implements the [SSL certificate generator](contracts-ssl.html) contract.
|
|
|
|
It is implemented by:
|
|
- [`shb.certs.cas.selfsigned`][10] and [`shb.certs.certs.selfsigned`][11]: Generates self-signed certificates,
|
|
including self-signed CA thanks to the [certtool][1] package.
|
|
- [`shb.certs.certs.letsencrypt`][12]: Requests certificates from [Let's Encrypt][2].
|
|
|
|
[1]: https://search.nixos.org/packages?channel=23.11&show=gnutls&from=0&size=50&sort=relevance&type=packages&query=certtool
|
|
[2]: https://letsencrypt.org/
|
|
|
|
[10]: blocks-ssl.html#blocks-ssl-options-shb.certs.cas.selfsigned
|
|
[11]: blocks-ssl.html#blocks-ssl-options-shb.certs.certs.selfsigned
|
|
[12]: blocks-ssl.html#blocks-ssl-options-shb.certs.certs.letsencrypt
|
|
|
|
## Self-Signed Certificates {#block-ssl-impl-self-signed}
|
|
|
|
Defined in [`/modules/blocks/ssl.nix`](@REPO@/modules/blocks/ssl.nix).
|
|
|
|
To use self-signed certificates, we must first generate at least one Certificate Authority (CA):
|
|
|
|
```nix
|
|
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:
|
|
|
|
```nix
|
|
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 {#block-ssl-impl-lets-encrypt}
|
|
|
|
Defined in [`/modules/blocks/ssl.nix`](@REPO@/modules/blocks/ssl.nix).
|
|
|
|
We can ask Let's Encrypt to generate a certificate with:
|
|
|
|
```nix
|
|
shb.certs.certs.letsencrypt."example.com" = {
|
|
domain = "example.com";
|
|
group = "nginx";
|
|
reloadServices = [ "nginx.service" ];
|
|
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:
|
|
|
|
```yaml
|
|
LINODE_TOKEN=XYZ...
|
|
```
|
|
|
|
If you use one subdomain per service,
|
|
asking for certificates for a subdomain is done with:
|
|
|
|
```nix
|
|
shb.certs.certs.letsencrypt."example.com".extraDomains = [ "nextcloud.${domain}" ];
|
|
```
|
|
|
|
For other providers, see the [official instruction](https://go-acme.github.io/lego/dns/).
|
|
|
|
## Usage {#block-ssl-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:
|
|
|
|
```nix
|
|
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:
|
|
|
|
```nix
|
|
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:
|
|
|
|
```nix
|
|
config.shb.certs.systemdService
|
|
```
|
|
|
|
See also the [SSL certificate generator usage](contracts-ssl.html#ssl-contract-usage) for a more detailed usage
|
|
example.
|
|
|
|
## Monitoring {#blocks-ssl-monitoring}
|
|
|
|
A dashboard for SSL certificates is provided.
|
|
See [SSL Certificates Dashboard and Alert](blocks-monitoring.html#blocks-monitoring-ssl) section in the monitoring chapter.
|
|
|
|
## Debug {#block-ssl-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`.
|
|
|
|
### Let's Encrypt debug {#blocks-ssl-debug-lets-encrypt}
|
|
|
|
Since the SHB SSL block uses the [`security.acme`][] module under the hood,
|
|
knowing how that one works can become required if something goes wrong.
|
|
|
|
For each domain and subdomain, noted as `fqdn` hereunder,
|
|
the following systemd timers and services are created:
|
|
|
|
- `acme-renew-${fqdn}.timer` triggers the `acme-order-renew-${fqdn}.service` service every day.
|
|
- `acme-${fqdn}.service` (re)generate the initial self-signed certificate,
|
|
only if the following job never succeeded at least once yet.
|
|
- `acme-order-renew-${fqdn}.service` asks for a new certificate
|
|
only if the certificate will expire in the next 30 days.
|
|
Has logic to only renew if the list of domains has not changed.
|
|
|
|
Also, a global service named `acme-setup.service` is created
|
|
|
|
[`security.acme`]: https://nixos.org/manual/nixos/stable/#module-security-acme
|
|
|
|
## Tests {#block-ssl-tests}
|
|
|
|
The self-signed implementation is tested in [`/tests/vm/ssl.nix`](@REPO@/tests/vm/ssl.nix).
|
|
|
|
## Options Reference {#block-ssl-options}
|
|
|
|
```{=include=} options
|
|
id-prefix: blocks-ssl-options-
|
|
list-id: selfhostblocks-options
|
|
source: @OPTIONS_JSON@
|
|
```
|