feat: add tls.acme mode — nginx inside container manages Let's Encrypt
per mara's suggestion: instead of bind-mounting operator certs, let
nginx handle ACME directly inside the gateway container.
- tls.acme.enable: lets nginx obtain + renew via HTTP-01 challenge
- tls.acme.email: ACME account contact (required when enable=true)
- security.acme in container config when acme.enable
- hasTls includes acme.enable → https, httpsPort listen, firewall
- mutual exclusion assertions: acme vs selfSignedTls vs certDir
- docs/gateway.md: four-mode TLS table + ACME section
typical setup:
selfSignedTls = false; openFirewall = true;
tls.acme = { enable = true; email = "admin@example.com"; };
This commit is contained in:
parent
6c4b47a7ec
commit
fb93cbf5c2
2 changed files with 135 additions and 22 deletions
|
|
@ -160,13 +160,37 @@ frontend-side derivation.
|
|||
|
||||
## TLS modes
|
||||
|
||||
Three modes:
|
||||
Four modes:
|
||||
|
||||
| mode | config | cert source | `.well-known` scheme |
|
||||
|---|---|---|---|
|
||||
| self-signed (default) | `selfSignedTls = true` | auto-generated RSA-4096, 10-year | `https` |
|
||||
| ACME (Let's Encrypt) | `selfSignedTls = false` + `tls.acme.enable = true` | nginx inside container via HTTP-01 | `https` |
|
||||
| operator cert | `selfSignedTls = false` + `tls.certDir` set | bind-mounted from host | `https` |
|
||||
| http-only | `selfSignedTls = false`, `tls.certDir = null` | none | `http` |
|
||||
| http-only | `selfSignedTls = false`, no `tls.certDir`, no `tls.acme` | none | `http` |
|
||||
|
||||
### ACME / Let's Encrypt (`tls.acme`)
|
||||
|
||||
Simplest production path for operators with a public domain:
|
||||
|
||||
```nix
|
||||
services.hyperhive.gateway = {
|
||||
selfSignedTls = false;
|
||||
openFirewall = true;
|
||||
tls.acme = {
|
||||
enable = true;
|
||||
email = "admin@example.com";
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
nginx inside the gateway container obtains and auto-renews certs via the ACME HTTP-01 challenge on `port` (default 80). The gateway container shares the host network namespace (`privateNetwork = false`) so outbound ACME requests work without any extra routing. Certs are stored inside the container's persistent state dir (`/var/lib/acme/` inside `hive-gateway`; survives restarts because `ephemeral = false`).
|
||||
|
||||
**Requirements**: `services.hyperhive.domain` must be publicly DNS-resolvable to this host, and `openFirewall = true` so Let's Encrypt can reach `/.well-known/acme-challenge/`. Each active vhost (main domain, `forge.<domain>`, `matrix.<domain>`) gets its own cert via separate ACME challenges.
|
||||
|
||||
Mutual exclusion: `selfSignedTls = true` or `tls.certDir` set together with `tls.acme.enable = true` fails an assertion.
|
||||
|
||||
**Swarm peers**: CA-signed certs are trusted by default — remote hives need no `certFingerprint` in `swarm.peers`.
|
||||
|
||||
### Self-signed TLS (`selfSignedTls`)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue