lol

nixos/acme: ensure web servers using certs can access them

+36 -13
+1 -1
nixos/modules/module-list.nix
··· 226 226 ./programs/zsh/zsh-autosuggestions.nix 227 227 ./programs/zsh/zsh-syntax-highlighting.nix 228 228 ./rename.nix 229 - ./security/acme.nix 229 + ./security/acme 230 230 ./security/apparmor.nix 231 231 ./security/audit.nix 232 232 ./security/auditd.nix
+1 -1
nixos/modules/security/acme.nix nixos/modules/security/acme/default.nix
··· 916 916 917 917 meta = { 918 918 maintainers = lib.teams.acme.members; 919 - doc = ./acme.xml; 919 + doc = ./doc.xml; 920 920 }; 921 921 }
nixos/modules/security/acme.xml nixos/modules/security/acme/doc.xml
+4
nixos/modules/security/acme/mk-cert-ownership-assertion.nix
··· 1 + { cert, group, groups, user }: { 2 + assertion = cert.group == group || builtins.any (u: u == user) groups.${cert.group}.members; 3 + message = "Group for certificate ${cert.domain} must be ${group}, or user ${user} must be a member of group ${cert.group}"; 4 + }
+7 -1
nixos/modules/services/web-servers/apache-httpd/default.nix
··· 370 370 cat ${php.phpIni} > $out 371 371 echo "$options" >> $out 372 372 ''; 373 + 374 + mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix; 373 375 in 374 376 375 377 ··· 657 659 `services.httpd.virtualHosts.<name>.useACMEHost` are mutually exclusive. 658 660 ''; 659 661 } 660 - ]; 662 + ] ++ map (name: mkCertOwnershipAssertion { 663 + inherit (cfg) group user; 664 + cert = config.security.acme.certs.${name}; 665 + groups = config.users.groups; 666 + }) dependentCertNames; 661 667 662 668 warnings = 663 669 mapAttrsToList (name: hostOpts: ''
+10 -3
nixos/modules/services/web-servers/caddy/default.nix
··· 38 38 ''; 39 39 in 40 40 if pkgs.stdenv.buildPlatform == pkgs.stdenv.hostPlatform then Caddyfile-formatted else Caddyfile; 41 + 42 + acmeHosts = unique (catAttrs "useACMEHost" acmeVHosts); 43 + 44 + mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix; 41 45 in 42 46 { 43 47 imports = [ ··· 266 270 { assertion = cfg.adapter != "caddyfile" -> cfg.configFile != configFile; 267 271 message = "Any value other than 'caddyfile' is only valid when providing your own `services.caddy.configFile`"; 268 272 } 269 - ]; 273 + ] ++ map (name: mkCertOwnershipAssertion { 274 + inherit (cfg) group user; 275 + cert = config.security.acme.certs.${name}; 276 + groups = config.users.groups; 277 + }) acmeHosts; 270 278 271 279 services.caddy.extraConfig = concatMapStringsSep "\n" mkVHostConf virtualHosts; 272 280 services.caddy.globalConfig = '' ··· 323 331 324 332 security.acme.certs = 325 333 let 326 - eachACMEHost = unique (catAttrs "useACMEHost" acmeVHosts); 327 - reloads = map (useACMEHost: nameValuePair useACMEHost { reloadServices = [ "caddy.service" ]; }) eachACMEHost; 334 + reloads = map (useACMEHost: nameValuePair useACMEHost { reloadServices = [ "caddy.service" ]; }) acmeHosts; 328 335 in 329 336 listToAttrs reloads; 330 337
+7 -1
nixos/modules/services/web-servers/nginx/default.nix
··· 374 374 ${user}:{PLAIN}${password} 375 375 '') authDef) 376 376 ); 377 + 378 + mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix; 377 379 in 378 380 379 381 { ··· 842 844 services.nginx.virtualHosts.<name>.useACMEHost are mutually exclusive. 843 845 ''; 844 846 } 845 - ]; 847 + ] ++ map (name: mkCertOwnershipAssertion { 848 + inherit (cfg) group user; 849 + cert = config.security.acme.certs.${name}; 850 + groups = config.users.groups; 851 + }) dependentCertNames; 846 852 847 853 systemd.services.nginx = { 848 854 description = "Nginx Web Server";
+6 -6
nixos/tests/acme.nix
··· 54 54 baseConfig = { nodes, config, specialConfig ? {} }: lib.mkMerge [ 55 55 { 56 56 security.acme = { 57 - defaults = (dnsConfig nodes) // { 58 - inherit group; 59 - }; 57 + defaults = (dnsConfig nodes); 60 58 # One manual wildcard cert 61 59 certs."example.test" = { 62 60 domain = "*.example.test"; 63 61 }; 64 62 }; 63 + 64 + users.users."${config.services."${server}".user}".extraGroups = ["acme"]; 65 65 66 66 services."${server}" = { 67 67 enable = true; ··· 252 252 } // (let 253 253 baseCaddyConfig = { nodes, config, ... }: { 254 254 security.acme = { 255 - defaults = (dnsConfig nodes) // { 256 - group = config.services.caddy.group; 257 - }; 255 + defaults = (dnsConfig nodes); 258 256 # One manual wildcard cert 259 257 certs."example.test" = { 260 258 domain = "*.example.test"; 261 259 }; 262 260 }; 261 + 262 + users.users."${config.services.caddy.user}".extraGroups = ["acme"]; 263 263 264 264 services.caddy = { 265 265 enable = true;