summary refs log tree commit diff
path: root/fleet/modules/acme.nix
blob: f06ac4ec67bde92a07c1224b48ec4f67cb7953e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
        }
      }
    '';
  };
}