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>
59 lines
1.2 KiB
Nix
59 lines
1.2 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
inputs,
|
|
...
|
|
}:
|
|
|
|
let
|
|
utils = import ../../utils.nix { inherit inputs lib; };
|
|
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
|
|
|
|
{
|
|
security.acme = {
|
|
acceptTerms = true;
|
|
defaults = {
|
|
email = "baduhai@proton.me";
|
|
dnsResolver = "1.1.1.1:53";
|
|
dnsProvider = "cloudflare";
|
|
credentialsFile = config.age.secrets.cloudflare.path;
|
|
};
|
|
certs = acmeCerts;
|
|
};
|
|
|
|
services.nginx = {
|
|
enable = true;
|
|
recommendedGzipSettings = true;
|
|
recommendedOptimisation = true;
|
|
recommendedProxySettings = true;
|
|
recommendedTlsSettings = true;
|
|
virtualHosts = {
|
|
"_" = {
|
|
default = true;
|
|
locations."/".return = "444";
|
|
};
|
|
};
|
|
};
|
|
|
|
users.users.nginx.extraGroups = [ "acme" ];
|
|
|
|
networking.firewall.allowedTCPPorts = [
|
|
80
|
|
443
|
|
];
|
|
|
|
age.secrets.cloudflare = {
|
|
file = ../../secrets/cloudflare.age;
|
|
owner = "nginx";
|
|
group = "nginx";
|
|
};
|
|
}
|