about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services/web-servers/nginx/default.nix')
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/nginx/default.nix145
1 files changed, 81 insertions, 64 deletions
diff --git a/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix b/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
index 93b1a3fdfadd..08fab09e1e55 100644
--- a/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
@@ -164,7 +164,7 @@ let
       ${commonHttpConfig}
 
       ${optionalString (cfg.resolver.addresses != []) ''
-        resolver ${toString cfg.resolver.addresses} ${optionalString (cfg.resolver.valid != "") "valid=${cfg.resolver.valid}"} ${optionalString (!cfg.resolver.ipv6) "ipv6=off"};
+        resolver ${toString cfg.resolver.addresses} ${optionalString (cfg.resolver.valid != "") "valid=${cfg.resolver.valid}"} ${optionalString (!cfg.resolver.ipv4) "ipv4=off"} ${optionalString (!cfg.resolver.ipv6) "ipv6=off"};
       ''}
       ${upstreamConfig}
 
@@ -352,7 +352,8 @@ let
 
         # The acme-challenge location doesn't need to be added if we are not using any automated
         # certificate provisioning and can also be omitted when we use a certificate obtained via a DNS-01 challenge
-        acmeLocation = optionalString (vhost.enableACME || (vhost.useACMEHost != null && config.security.acme.certs.${vhost.useACMEHost}.dnsProvider == null))
+        acmeName = if vhost.useACMEHost != null then vhost.useACMEHost else vhostName;
+        acmeLocation = optionalString ((vhost.enableACME || vhost.useACMEHost != null) && config.security.acme.certs.${acmeName}.dnsProvider == null)
           # Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx)
           # We use ^~ here, so that we don't check any regexes (which could
           # otherwise easily override this intended match accidentally).
@@ -477,12 +478,12 @@ in
 {
   options = {
     services.nginx = {
-      enable = mkEnableOption (lib.mdDoc "Nginx Web Server");
+      enable = mkEnableOption "Nginx Web Server";
 
       statusPage = mkOption {
         default = false;
         type = types.bool;
-        description = lib.mdDoc ''
+        description = ''
           Enable status page reachable from localhost on http://127.0.0.1/nginx_status.
         '';
       };
@@ -490,7 +491,7 @@ in
       recommendedTlsSettings = mkOption {
         default = false;
         type = types.bool;
-        description = lib.mdDoc ''
+        description = ''
           Enable recommended TLS settings.
         '';
       };
@@ -498,7 +499,7 @@ in
       recommendedOptimisation = mkOption {
         default = false;
         type = types.bool;
-        description = lib.mdDoc ''
+        description = ''
           Enable recommended optimisation settings.
         '';
       };
@@ -506,7 +507,7 @@ in
       recommendedBrotliSettings = mkOption {
         default = false;
         type = types.bool;
-        description = lib.mdDoc ''
+        description = ''
           Enable recommended brotli settings.
           Learn more about compression in Brotli format [here](https://github.com/google/ngx_brotli/).
 
@@ -517,7 +518,7 @@ in
       recommendedGzipSettings = mkOption {
         default = false;
         type = types.bool;
-        description = lib.mdDoc ''
+        description = ''
           Enable recommended gzip settings.
           Learn more about compression in Gzip format [here](https://docs.nginx.com/nginx/admin-guide/web-server/compression/).
         '';
@@ -526,7 +527,7 @@ in
       recommendedZstdSettings = mkOption {
         default = false;
         type = types.bool;
-        description = lib.mdDoc ''
+        description = ''
           Enable recommended zstd settings.
           Learn more about compression in Zstd format [here](https://github.com/tokers/zstd-nginx-module).
 
@@ -537,7 +538,7 @@ in
       recommendedProxySettings = mkOption {
         default = false;
         type = types.bool;
-        description = lib.mdDoc ''
+        description = ''
           Whether to enable recommended proxy settings if a vhost does not specify the option manually.
         '';
       };
@@ -546,7 +547,7 @@ in
         type = types.str;
         default = "60s";
         example = "20s";
-        description = lib.mdDoc ''
+        description = ''
           Change the proxy related timeouts in recommendedProxySettings.
         '';
       };
@@ -556,26 +557,26 @@ in
           options = {
             addr = mkOption {
               type = str;
-              description = lib.mdDoc "IP address.";
+              description = "IP address.";
             };
             port = mkOption {
               type = nullOr port;
-              description = lib.mdDoc "Port number.";
+              description = "Port number.";
               default = null;
             };
             ssl  = mkOption {
               type = nullOr bool;
               default = null;
-              description = lib.mdDoc "Enable SSL.";
+              description = "Enable SSL.";
             };
             proxyProtocol = mkOption {
               type = bool;
-              description = lib.mdDoc "Enable PROXY protocol.";
+              description = "Enable PROXY protocol.";
               default = false;
             };
             extraParameters = mkOption {
               type = listOf str;
-              description = lib.mdDoc "Extra parameters of this listen directive.";
+              description = "Extra parameters of this listen directive.";
               default = [ ];
               example = [ "backlog=1024" "deferred" ];
             };
@@ -589,7 +590,7 @@ in
             { addr = "[::0]"; }
           ]
         '';
-        description = lib.mdDoc ''
+        description = ''
           If vhosts do not specify listen, use these addresses by default.
           This option takes precedence over {option}`defaultListenAddresses` and
           other listen-related defaults options.
@@ -601,7 +602,7 @@ in
         default = [ "0.0.0.0" ] ++ optional enableIPv6 "[::0]";
         defaultText = literalExpression ''[ "0.0.0.0" ] ++ lib.optional config.networking.enableIPv6 "[::0]"'';
         example = literalExpression ''[ "10.0.0.12" "[2002:a00:1::]" ]'';
-        description = lib.mdDoc ''
+        description = ''
           If vhosts do not specify listenAddresses, use these addresses by default.
           This is akin to writing `defaultListen = [ { addr = "0.0.0.0" } ]`.
         '';
@@ -611,7 +612,7 @@ in
         type = types.port;
         default = 80;
         example = 8080;
-        description = lib.mdDoc ''
+        description = ''
           If vhosts do not specify listen.port, use these ports for HTTP by default.
         '';
       };
@@ -620,7 +621,7 @@ in
         type = types.port;
         default = 443;
         example = 8443;
-        description = lib.mdDoc ''
+        description = ''
           If vhosts do not specify listen.port, use these ports for SSL by default.
         '';
       };
@@ -630,7 +631,7 @@ in
         default = "${pkgs.mailcap}/etc/nginx/mime.types";
         defaultText = literalExpression "$''{pkgs.mailcap}/etc/nginx/mime.types";
         example = literalExpression "$''{pkgs.nginx}/conf/mime.types";
-        description = lib.mdDoc ''
+        description = ''
           Default MIME types for NGINX, as MIME types definitions from NGINX are very incomplete,
           we use by default the ones bundled in the mailcap package, used by most of the other
           Linux distributions.
@@ -644,7 +645,7 @@ in
         apply = p: p.override {
           modules = lib.unique (p.modules ++ cfg.additionalModules);
         };
-        description = lib.mdDoc ''
+        description = ''
           Nginx package to use. This defaults to the stable version. Note
           that the nginx team recommends to use the mainline version which
           available in nixpkgs as `nginxMainline`.
@@ -657,7 +658,7 @@ in
         default = [];
         type = types.listOf (types.attrsOf types.anything);
         example = literalExpression "[ pkgs.nginxModules.echo ]";
-        description = lib.mdDoc ''
+        description = ''
           Additional [third-party nginx modules](https://www.nginx.com/resources/wiki/modules/)
           to install. Packaged modules are available in `pkgs.nginxModules`.
         '';
@@ -666,7 +667,7 @@ in
       logError = mkOption {
         default = "stderr";
         type = types.str;
-        description = lib.mdDoc ''
+        description = ''
           Configures logging.
           The first parameter defines a file that will store the log. The
           special value stderr selects the standard error file. Logging to
@@ -683,7 +684,7 @@ in
       preStart =  mkOption {
         type = types.lines;
         default = "";
-        description = lib.mdDoc ''
+        description = ''
           Shell commands executed before the service's nginx is started.
         '';
       };
@@ -691,7 +692,7 @@ in
       config = mkOption {
         type = types.str;
         default = "";
-        description = lib.mdDoc ''
+        description = ''
           Verbatim {file}`nginx.conf` configuration.
           This is mutually exclusive to any other config option for
           {file}`nginx.conf` except for
@@ -707,7 +708,7 @@ in
       appendConfig = mkOption {
         type = types.lines;
         default = "";
-        description = lib.mdDoc ''
+        description = ''
           Configuration lines appended to the generated Nginx
           configuration file. Commonly used by different modules
           providing http snippets. {option}`appendConfig`
@@ -727,7 +728,7 @@ in
                               '"$request" $status $body_bytes_sent '
                               '"$http_referer" "$http_user_agent"';
         '';
-        description = lib.mdDoc ''
+        description = ''
           With nginx you must provide common http context definitions before
           they are used, e.g. log_format, resolver, etc. inside of server
           or location contexts. Use this attribute to set these definitions
@@ -738,7 +739,7 @@ in
       httpConfig = mkOption {
         type = types.lines;
         default = "";
-        description = lib.mdDoc ''
+        description = ''
           Configuration lines to be set inside the http block.
           This is mutually exclusive with the structured configuration
           via virtualHosts and the recommendedXyzSettings configuration
@@ -756,7 +757,7 @@ in
             proxy_pass 192.168.0.1:53535;
           }
         '';
-        description = lib.mdDoc ''
+        description = ''
           Configuration lines to be set inside the stream block.
         '';
       };
@@ -764,7 +765,7 @@ in
       eventsConfig = mkOption {
         type = types.lines;
         default = "";
-        description = lib.mdDoc ''
+        description = ''
           Configuration lines to be set inside the events block.
         '';
       };
@@ -772,7 +773,7 @@ in
       appendHttpConfig = mkOption {
         type = types.lines;
         default = "";
-        description = lib.mdDoc ''
+        description = ''
           Configuration lines to be appended to the generated http block.
           This is mutually exclusive with using config and httpConfig for
           specifying the whole http block verbatim.
@@ -782,7 +783,7 @@ in
       enableReload = mkOption {
         default = false;
         type = types.bool;
-        description = lib.mdDoc ''
+        description = ''
           Reload nginx when configuration file changes (instead of restart).
           The configuration file is exposed at {file}`/etc/nginx/nginx.conf`.
           See also `systemd.services.*.restartIfChanged`.
@@ -792,7 +793,7 @@ in
       enableQuicBPF = mkOption {
         default = false;
         type = types.bool;
-        description = lib.mdDoc ''
+        description = ''
           Enables routing of QUIC packets using eBPF. When enabled, this allows
           to support QUIC connection migration. The directive is only supported
           on Linux 5.7+.
@@ -805,52 +806,52 @@ in
       user = mkOption {
         type = types.str;
         default = "nginx";
-        description = lib.mdDoc "User account under which nginx runs.";
+        description = "User account under which nginx runs.";
       };
 
       group = mkOption {
         type = types.str;
         default = "nginx";
-        description = lib.mdDoc "Group account under which nginx runs.";
+        description = "Group account under which nginx runs.";
       };
 
       serverTokens = mkOption {
         type = types.bool;
         default = false;
-        description = lib.mdDoc "Show nginx version in headers and error pages.";
+        description = "Show nginx version in headers and error pages.";
       };
 
       clientMaxBodySize = mkOption {
         type = types.str;
         default = "10m";
-        description = lib.mdDoc "Set nginx global client_max_body_size.";
+        description = "Set nginx global client_max_body_size.";
       };
 
       sslCiphers = mkOption {
         type = types.nullOr types.str;
         # Keep in sync with https://ssl-config.mozilla.org/#server=nginx&config=intermediate
-        default = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
-        description = lib.mdDoc "Ciphers to choose from when negotiating TLS handshakes.";
+        default = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305";
+        description = "Ciphers to choose from when negotiating TLS handshakes.";
       };
 
       sslProtocols = mkOption {
         type = types.str;
         default = "TLSv1.2 TLSv1.3";
         example = "TLSv1 TLSv1.1 TLSv1.2 TLSv1.3";
-        description = lib.mdDoc "Allowed TLS protocol versions.";
+        description = "Allowed TLS protocol versions.";
       };
 
       sslDhparam = mkOption {
         type = types.nullOr types.path;
         default = null;
         example = "/path/to/dhparams.pem";
-        description = lib.mdDoc "Path to DH parameters file.";
+        description = "Path to DH parameters file.";
       };
 
       proxyResolveWhileRunning = mkOption {
         type = types.bool;
         default = false;
-        description = lib.mdDoc ''
+        description = ''
           Resolves domains of proxyPass targets at runtime
           and not only at start, you have to set
           services.nginx.resolver, too.
@@ -860,7 +861,7 @@ in
       mapHashBucketSize = mkOption {
         type = types.nullOr (types.enum [ 32 64 128 ]);
         default = null;
-        description = lib.mdDoc ''
+        description = ''
             Sets the bucket size for the map variables hash tables. Default
             value depends on the processor’s cache line size.
           '';
@@ -869,7 +870,7 @@ in
       mapHashMaxSize = mkOption {
         type = types.nullOr types.ints.positive;
         default = null;
-        description = lib.mdDoc ''
+        description = ''
             Sets the maximum size of the map variables hash tables.
           '';
       };
@@ -877,7 +878,7 @@ in
       serverNamesHashBucketSize = mkOption {
         type = types.nullOr types.ints.positive;
         default = null;
-        description = lib.mdDoc ''
+        description = ''
             Sets the bucket size for the server names hash tables. Default
             value depends on the processor’s cache line size.
           '';
@@ -886,7 +887,7 @@ in
       serverNamesHashMaxSize = mkOption {
         type = types.nullOr types.ints.positive;
         default = null;
-        description = lib.mdDoc ''
+        description = ''
             Sets the maximum size of the server names hash tables.
           '';
       };
@@ -894,27 +895,27 @@ in
       proxyCachePath = mkOption {
         type = types.attrsOf (types.submodule ({ ... }: {
           options = {
-            enable = mkEnableOption (lib.mdDoc "this proxy cache path entry");
+            enable = mkEnableOption "this proxy cache path entry";
 
             keysZoneName = mkOption {
               type = types.str;
               default = "cache";
               example = "my_cache";
-              description = lib.mdDoc "Set name to shared memory zone.";
+              description = "Set name to shared memory zone.";
             };
 
             keysZoneSize = mkOption {
               type = types.str;
               default = "10m";
               example = "32m";
-              description = lib.mdDoc "Set size to shared memory zone.";
+              description = "Set size to shared memory zone.";
             };
 
             levels = mkOption {
               type = types.str;
               default = "1:2";
               example = "1:2:2";
-              description = lib.mdDoc ''
+              description = ''
                 The levels parameter defines structure of subdirectories in cache: from
                 1 to 3, each level accepts values 1 or 2. Сan be used any combination of
                 1 and 2 in these formats: x, x:x and x:x:x.
@@ -925,7 +926,7 @@ in
               type = types.bool;
               default = false;
               example = true;
-              description = lib.mdDoc ''
+              description = ''
                 Nginx first writes files that are destined for the cache to a temporary
                 storage area, and the use_temp_path=off directive instructs Nginx to
                 write them to the same directories where they will be cached. Recommended
@@ -938,7 +939,7 @@ in
               type = types.str;
               default = "10m";
               example = "1d";
-              description = lib.mdDoc ''
+              description = ''
                 Cached data that has not been accessed for the time specified by
                 the inactive parameter is removed from the cache, regardless of
                 its freshness.
@@ -949,12 +950,12 @@ in
               type = types.str;
               default = "1g";
               example = "2048m";
-              description = lib.mdDoc "Set maximum cache size";
+              description = "Set maximum cache size";
             };
           };
         }));
         default = {};
-        description = lib.mdDoc ''
+        description = ''
           Configure a proxy cache path entry.
           See <https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_path> for documentation.
         '';
@@ -967,21 +968,30 @@ in
               type = types.listOf types.str;
               default = [];
               example = literalExpression ''[ "[::1]" "127.0.0.1:5353" ]'';
-              description = lib.mdDoc "List of resolvers to use";
+              description = "List of resolvers to use";
             };
             valid = mkOption {
               type = types.str;
               default = "";
               example = "30s";
-              description = lib.mdDoc ''
+              description = ''
                 By default, nginx caches answers using the TTL value of a response.
                 An optional valid parameter allows overriding it
               '';
             };
+            ipv4 = mkOption {
+              type = types.bool;
+              default = true;
+              description = ''
+                By default, nginx will look up both IPv4 and IPv6 addresses while resolving.
+                If looking up of IPv4 addresses is not desired, the ipv4=off parameter can be
+                specified.
+              '';
+            };
             ipv6 = mkOption {
               type = types.bool;
               default = true;
-              description = lib.mdDoc ''
+              description = ''
                 By default, nginx will look up both IPv4 and IPv6 addresses while resolving.
                 If looking up of IPv6 addresses is not desired, the ipv6=off parameter can be
                 specified.
@@ -989,7 +999,7 @@ in
             };
           };
         };
-        description = lib.mdDoc ''
+        description = ''
           Configures name servers used to resolve names of upstream servers into addresses
         '';
         default = {};
@@ -1005,14 +1015,14 @@ in
                   backup = mkOption {
                     type = types.bool;
                     default = false;
-                    description = lib.mdDoc ''
+                    description = ''
                       Marks the server as a backup server. It will be passed
                       requests when the primary servers are unavailable.
                     '';
                   };
                 };
               });
-              description = lib.mdDoc ''
+              description = ''
                 Defines the address and other parameters of the upstream servers.
                 See [the documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#server)
                 for the available parameters.
@@ -1023,13 +1033,13 @@ in
             extraConfig = mkOption {
               type = types.lines;
               default = "";
-              description = lib.mdDoc ''
+              description = ''
                 These lines go to the end of the upstream verbatim.
               '';
             };
           };
         });
-        description = lib.mdDoc ''
+        description = ''
           Defines a group of servers to use as proxy target.
         '';
         default = {};
@@ -1070,7 +1080,7 @@ in
             };
           };
         '';
-        description = lib.mdDoc "Declarative vhost config";
+        description = "Declarative vhost config";
       };
     };
   };
@@ -1179,6 +1189,13 @@ in
           to answer to ACME requests.
         '';
       }
+
+      {
+        assertion = cfg.resolver.ipv4 || cfg.resolver.ipv6;
+        message = ''
+          At least one of services.nginx.resolver.ipv4 and services.nginx.resolver.ipv6 must be true.
+        '';
+      }
     ] ++ map (name: mkCertOwnershipAssertion {
       inherit (cfg) group user;
       cert = config.security.acme.certs.${name};