From 7df420c27ebe7daaa4fd099c457ce9a9075b840e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= Date: Thu, 16 May 2019 23:23:05 +0200 Subject: Add certificate creation and handling to websites --- modules/websites/default.nix | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'modules/websites') diff --git a/modules/websites/default.nix b/modules/websites/default.nix index 6a18c8a..b76aeea 100644 --- a/modules/websites/default.nix +++ b/modules/websites/default.nix @@ -3,6 +3,9 @@ let cfg = config.services.websites; in { + options.services.websitesCerts = mkOption { + description = "Default websites configuration for certificates as accepted by acme"; + }; options.services.websites = with types; mkOption { default = {}; description = "Each type of website to enable will target a distinct httpd server"; @@ -72,6 +75,16 @@ in type = attrsOf (submodule { options = { certName = mkOption { type = string; }; + addToCerts = mkOption { + type = bool; + default = false; + description = "Use these to certificates. Is ignored (considered true) if certMainHost is not null"; + }; + certMainHost = mkOption { + type = nullOr string; + description = "Use that host as 'main host' for acme certs"; + default = null; + }; hosts = mkOption { type = listOf string; }; root = mkOption { type = nullOr path; }; extraConfig = mkOption { type = listOf lines; default = []; }; @@ -145,4 +158,42 @@ in ++ [ (redirectVhost icfg.ips) ]; }) ) cfg; + + config.security.acme.certs = let + typesToManage = attrsets.filterAttrs (k: v: v.enable) cfg; + flatVhosts = lists.flatten (attrsets.mapAttrsToList (k: v: + attrValues v.vhostConfs + ) typesToManage); + groupedCerts = attrsets.filterAttrs + (_: group: builtins.any (v: v.addToCerts || !isNull v.certMainHost) group) + (lists.groupBy (v: v.certName) flatVhosts); + groupToDomain = group: + let + nonNull = builtins.filter (v: !isNull v.certMainHost) group; + domains = lists.unique (map (v: v.certMainHost) nonNull); + in + if builtins.length domains == 0 + then null + else assert (builtins.length domains == 1); (elemAt domains 0); + extraDomains = group: + let + mainDomain = groupToDomain group; + in + lists.remove mainDomain ( + lists.unique ( + lists.flatten (map (c: optionals (c.addToCerts || !isNull c.certMainHost) c.hosts) group) + ) + ); + in attrsets.mapAttrs (k: g: + if (!isNull (groupToDomain g)) + then config.services.websitesCerts // { + domain = groupToDomain g; + extraDomains = builtins.listToAttrs ( + map (d: attrsets.nameValuePair d null) (extraDomains g)); + } + else { + extraDomains = builtins.listToAttrs ( + map (d: attrsets.nameValuePair d null) (extraDomains g)); + } + ) groupedCerts; } -- cgit v1.2.3