diff options
Diffstat (limited to 'fleet/modules/acme.nix')
-rw-r--r-- | fleet/modules/acme.nix | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/fleet/modules/acme.nix b/fleet/modules/acme.nix new file mode 100644 index 0000000..f06ac4e --- /dev/null +++ b/fleet/modules/acme.nix @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: V <v@unfathomable.blue> +# SPDX-License-Identifier: OSL-3.0 + +{ config, lib, pkgs, ... }: + +with lib; + +let + webroot = "/var/lib/acme/challenges"; +in { + options = { + # We want to set webroot on every single certificate, but trying + # to do this by using genAttrs on the certificate attribute names + # produces infinite recursion. To get around this, we're instead + # setting webroot from within the certificate submodule itself. + # + # The fact that this is even possible is because submodules are + # just like normal modules, insofar that they can have both an + # 'options' and a 'config' attribute, both of which are scoped + # to the submodule itself. Additionally, normal merging logic + # is applied to module options, meaning we can just define the + # certificates option again and that'll be handled correctly. + # + # TODO(V): Add a global security.acme.webroot option to the upstream module + security.acme.certs = mkOption { + type = types.attrsOf (types.submodule { + inherit webroot; + }); + }; + }; + + config = { + security.acme = { + acceptTerms = true; + email = "acme@unfathomable.blue"; + }; + + services.caddy.config = '' + ${concatStringsSep ", " (unique (mapAttrsToList (_: cert: "http://${cert.domain}") config.security.acme.certs))} { + import all + + route { + # TODO(V): make use of the 'file' matcher, so this is guaranteed to never 404? + file_server /.well-known/acme-challenge/* { + root ${webroot} + } + + # Manually handling http:// disables Caddy's automatic HTTPS + # redirects for the domain, so let's do that ourselves + redir https://{host}{uri} 308 + } + } + ''; + }; +} |