mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-29 09:02:46 +00:00
nixos/nginx: allow using existing ACME certificate
When a domain has a lot of subdomains, it is quite easy to hit the rate limit: https://letsencrypt.org/docs/rate-limits/ Instead you can define the certificate manually in `security.acme.certs` and list the subdomains in the `extraDomains` option.
This commit is contained in:
parent
ee4e6ebbfa
commit
41d252d7a4
|
@ -15,6 +15,9 @@ let
|
||||||
} // (optionalAttrs vhostConfig.enableACME {
|
} // (optionalAttrs vhostConfig.enableACME {
|
||||||
sslCertificate = "/var/lib/acme/${serverName}/fullchain.pem";
|
sslCertificate = "/var/lib/acme/${serverName}/fullchain.pem";
|
||||||
sslCertificateKey = "/var/lib/acme/${serverName}/key.pem";
|
sslCertificateKey = "/var/lib/acme/${serverName}/key.pem";
|
||||||
|
}) // (optionalAttrs (vhostConfig.useACMEHost != null) {
|
||||||
|
sslCertificate = "/var/lib/acme/${vhostConfig.useACMEHost}/fullchain.pem";
|
||||||
|
sslCertificateKey = "/var/lib/acme/${vhostConfig.useACMEHost}/key.pem";
|
||||||
})
|
})
|
||||||
) cfg.virtualHosts;
|
) cfg.virtualHosts;
|
||||||
enableIPv6 = config.networking.enableIPv6;
|
enableIPv6 = config.networking.enableIPv6;
|
||||||
|
@ -174,7 +177,7 @@ let
|
||||||
|
|
||||||
redirectListen = filter (x: !x.ssl) defaultListen;
|
redirectListen = filter (x: !x.ssl) defaultListen;
|
||||||
|
|
||||||
acmeLocation = ''
|
acmeLocation = optionalString (vhost.enableACME || vhost.useACMEHost != null) ''
|
||||||
location /.well-known/acme-challenge {
|
location /.well-known/acme-challenge {
|
||||||
${optionalString (vhost.acmeFallbackHost != null) "try_files $uri @acme-fallback;"}
|
${optionalString (vhost.acmeFallbackHost != null) "try_files $uri @acme-fallback;"}
|
||||||
root ${vhost.acmeRoot};
|
root ${vhost.acmeRoot};
|
||||||
|
@ -194,7 +197,7 @@ let
|
||||||
${concatMapStringsSep "\n" listenString redirectListen}
|
${concatMapStringsSep "\n" listenString redirectListen}
|
||||||
|
|
||||||
server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases};
|
server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases};
|
||||||
${optionalString vhost.enableACME acmeLocation}
|
${acmeLocation}
|
||||||
location / {
|
location / {
|
||||||
return 301 https://$host$request_uri;
|
return 301 https://$host$request_uri;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +207,7 @@ let
|
||||||
server {
|
server {
|
||||||
${concatMapStringsSep "\n" listenString hostListen}
|
${concatMapStringsSep "\n" listenString hostListen}
|
||||||
server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases};
|
server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases};
|
||||||
${optionalString vhost.enableACME acmeLocation}
|
${acmeLocation}
|
||||||
${optionalString (vhost.root != null) "root ${vhost.root};"}
|
${optionalString (vhost.root != null) "root ${vhost.root};"}
|
||||||
${optionalString (vhost.globalRedirect != null) ''
|
${optionalString (vhost.globalRedirect != null) ''
|
||||||
return 301 http${optionalString hasSSL "s"}://${vhost.globalRedirect}$request_uri;
|
return 301 http${optionalString hasSSL "s"}://${vhost.globalRedirect}$request_uri;
|
||||||
|
@ -555,6 +558,14 @@ in
|
||||||
are mutually exclusive.
|
are mutually exclusive.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
assertion = all (conf: !(conf.enableACME && conf.useACMEHost != null)) (attrValues virtualHosts);
|
||||||
|
message = ''
|
||||||
|
Options services.nginx.service.virtualHosts.<name>.enableACME and
|
||||||
|
services.nginx.virtualHosts.<name>.useACMEHost are mutually exclusive.
|
||||||
|
'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.services.nginx = {
|
systemd.services.nginx = {
|
||||||
|
@ -580,7 +591,7 @@ in
|
||||||
security.acme.certs = filterAttrs (n: v: v != {}) (
|
security.acme.certs = filterAttrs (n: v: v != {}) (
|
||||||
let
|
let
|
||||||
vhostsConfigs = mapAttrsToList (vhostName: vhostConfig: vhostConfig) virtualHosts;
|
vhostsConfigs = mapAttrsToList (vhostName: vhostConfig: vhostConfig) virtualHosts;
|
||||||
acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME) vhostsConfigs;
|
acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME && vhostConfig.useACMEHost == null) vhostsConfigs;
|
||||||
acmePairs = map (vhostConfig: { name = vhostConfig.serverName; value = {
|
acmePairs = map (vhostConfig: { name = vhostConfig.serverName; value = {
|
||||||
user = cfg.user;
|
user = cfg.user;
|
||||||
group = lib.mkDefault cfg.group;
|
group = lib.mkDefault cfg.group;
|
||||||
|
|
|
@ -48,7 +48,21 @@ with lib;
|
||||||
enableACME = mkOption {
|
enableACME = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "Whether to ask Let's Encrypt to sign a certificate for this vhost.";
|
description = ''
|
||||||
|
Whether to ask Let's Encrypt to sign a certificate for this vhost.
|
||||||
|
Alternately, you can use an existing certificate through <option>useACMEHost</option>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
useACMEHost = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
A host of an existing Let's Encrypt certificate to use.
|
||||||
|
This is useful if you have many subdomains and want to avoid hitting the
|
||||||
|
<link xlink:href="https://letsencrypt.org/docs/rate-limits/">rate limit</link>.
|
||||||
|
Alternately, you can generate a certificate through <option>enableACME</option>.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
acmeRoot = mkOption {
|
acmeRoot = mkOption {
|
||||||
|
|
Loading…
Reference in a new issue