Switch ACME to DNS-01 challenge with auto-configured certificates

Changed certificate generation from HTTP-01 to DNS-01 challenge to support
services behind Tailscale/CGNAT IPs. HTTP-01 challenges fail because Let's
Encrypt cannot reach private Tailscale IPs (100.x.x.x) that Cloudflare DNS
points to.

Changes:
- Pre-configure certificates in security.acme.certs using DNS-01 via Cloudflare
- Auto-generate certificate configs from shared/services.nix
  - Alexandria: filters services with host == "alexandria"
  - Trantor: filters services with host == "trantor"
- Updated mkNginxVHosts to use useACMEHost instead of enableACME
- Each domain gets its own certificate configured with DNS-01 challenge

This ensures all services get valid Let's Encrypt certificates even when
accessible only through Tailscale or private networks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
William 2025-11-08 22:53:18 -03:00
parent 952a55f03d
commit 58fec03579
3 changed files with 30 additions and 8 deletions

View file

@ -7,7 +7,15 @@
let
utils = import ../../utils.nix { inherit inputs lib; };
inherit (utils) mkNginxVHosts;
inherit (utils) mkNginxVHosts services;
# Get all unique domains from shared services that have LAN IPs (served by this host)
localDomains = lib.unique (map (s: s.domain) (lib.filter (s: s.host == "alexandria") services));
# Generate ACME cert configs for all local domains
acmeCerts = lib.genAttrs localDomains (domain: {
group = "nginx";
});
in
{
@ -19,6 +27,7 @@ in
dnsProvider = "cloudflare";
credentialsFile = config.age.secrets.cloudflare.path;
};
certs = acmeCerts;
};
services.nginx = {