lol

Merge pull request #33900 from jtojnar/nginx-acme

nixos/nginx: allow using existing ACME certificate

authored by

Jan Tojnar and committed by
GitHub
0f21306c 47d0a11a

+30 -5
+15 -4
nixos/modules/services/web-servers/nginx/default.nix
··· 15 15 } // (optionalAttrs vhostConfig.enableACME { 16 16 sslCertificate = "/var/lib/acme/${serverName}/fullchain.pem"; 17 17 sslCertificateKey = "/var/lib/acme/${serverName}/key.pem"; 18 + }) // (optionalAttrs (vhostConfig.useACMEHost != null) { 19 + sslCertificate = "/var/lib/acme/${vhostConfig.useACMEHost}/fullchain.pem"; 20 + sslCertificateKey = "/var/lib/acme/${vhostConfig.useACMEHost}/key.pem"; 18 21 }) 19 22 ) cfg.virtualHosts; 20 23 enableIPv6 = config.networking.enableIPv6; ··· 174 177 175 178 redirectListen = filter (x: !x.ssl) defaultListen; 176 179 177 - acmeLocation = '' 180 + acmeLocation = optionalString (vhost.enableACME || vhost.useACMEHost != null) '' 178 181 location /.well-known/acme-challenge { 179 182 ${optionalString (vhost.acmeFallbackHost != null) "try_files $uri @acme-fallback;"} 180 183 root ${vhost.acmeRoot}; ··· 194 197 ${concatMapStringsSep "\n" listenString redirectListen} 195 198 196 199 server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases}; 197 - ${optionalString vhost.enableACME acmeLocation} 200 + ${acmeLocation} 198 201 location / { 199 202 return 301 https://$host$request_uri; 200 203 } ··· 204 207 server { 205 208 ${concatMapStringsSep "\n" listenString hostListen} 206 209 server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases}; 207 - ${optionalString vhost.enableACME acmeLocation} 210 + ${acmeLocation} 208 211 ${optionalString (vhost.root != null) "root ${vhost.root};"} 209 212 ${optionalString (vhost.globalRedirect != null) '' 210 213 return 301 http${optionalString hasSSL "s"}://${vhost.globalRedirect}$request_uri; ··· 555 558 are mutually exclusive. 556 559 ''; 557 560 } 561 + 562 + { 563 + assertion = all (conf: !(conf.enableACME && conf.useACMEHost != null)) (attrValues virtualHosts); 564 + message = '' 565 + Options services.nginx.service.virtualHosts.<name>.enableACME and 566 + services.nginx.virtualHosts.<name>.useACMEHost are mutually exclusive. 567 + ''; 568 + } 558 569 ]; 559 570 560 571 systemd.services.nginx = { ··· 580 591 security.acme.certs = filterAttrs (n: v: v != {}) ( 581 592 let 582 593 vhostsConfigs = mapAttrsToList (vhostName: vhostConfig: vhostConfig) virtualHosts; 583 - acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME) vhostsConfigs; 594 + acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME && vhostConfig.useACMEHost == null) vhostsConfigs; 584 595 acmePairs = map (vhostConfig: { name = vhostConfig.serverName; value = { 585 596 user = cfg.user; 586 597 group = lib.mkDefault cfg.group;
+15 -1
nixos/modules/services/web-servers/nginx/vhost-options.nix
··· 48 48 enableACME = mkOption { 49 49 type = types.bool; 50 50 default = false; 51 - description = "Whether to ask Let's Encrypt to sign a certificate for this vhost."; 51 + description = '' 52 + Whether to ask Let's Encrypt to sign a certificate for this vhost. 53 + Alternately, you can use an existing certificate through <option>useACMEHost</option>. 54 + ''; 55 + }; 56 + 57 + useACMEHost = mkOption { 58 + type = types.nullOr types.str; 59 + default = null; 60 + description = '' 61 + A host of an existing Let's Encrypt certificate to use. 62 + This is useful if you have many subdomains and want to avoid hitting the 63 + <link xlink:href="https://letsencrypt.org/docs/rate-limits/">rate limit</link>. 64 + Alternately, you can generate a certificate through <option>enableACME</option>. 65 + ''; 52 66 }; 53 67 54 68 acmeRoot = mkOption {