From a3b281a96546e99d7fe0ad33f6c6ea455d3e8437 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Mon, 10 Feb 2025 13:51:03 +0100 Subject: [PATCH] nixos/caddy: validate config on build by default --- .../services/web-servers/caddy/default.nix | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/nixos/modules/services/web-servers/caddy/default.nix b/nixos/modules/services/web-servers/caddy/default.nix index d87a04e0f5f159..c6ae50df88ce12 100644 --- a/nixos/modules/services/web-servers/caddy/default.nix +++ b/nixos/modules/services/web-servers/caddy/default.nix @@ -70,6 +70,28 @@ let configPath = "/etc/${etcConfigFile}"; mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix lib; + + validateCaddyConfig = + adapter: configFile: + builtins.fromJSON ( + builtins.readFile ( + pkgs.runCommand "caddy-validate" + { + nativeBuildInputs = [ cfg.package ]; + } + '' + if caddy validate --adapter ${toString adapter} --config ${configFile}; then + echo "true" > $out + else + echo "false" > $out + fi + '' + ) + ); + + configValidationResult = validateCaddyConfig ( + if cfg.adapter != null then cfg.adapter else "caddyfile" + ) cfg.configFile; in { imports = [ @@ -378,6 +400,16 @@ in [here](https://caddyserver.com/docs/caddyfile/concepts#environment-variables) ''; }; + + enforceConfigValidation = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enforce Caddy configuration validation during build. + If true, invalid configuration will cause the build to fail. + If false, invalid configuration will only show a warning. + ''; + }; }; # implementation @@ -390,6 +422,10 @@ in message = "To specify an adapter other than 'caddyfile' please provide your own configuration via `services.caddy.configFile`"; } ] + ++ optional cfg.enforceConfigValidation { + assertion = configValidationResult; + message = "Caddy configuration validation failed. Check your configuration."; + } ++ map ( name: mkCertOwnershipAssertion { @@ -399,6 +435,10 @@ in } ) vhostCertNames; + warnings = lib.optional ( + !cfg.enforceConfigValidation && !configValidationResult + ) "Caddy configuration validation failed. The service might not start correctly."; + services.caddy.globalConfig = '' ${optionalString (cfg.email != null) "email ${cfg.email}"} ${optionalString (cfg.acmeCA != null) "acme_ca ${cfg.acmeCA}"}