diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index ae14aa28ae3..f83413b4534 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -123,45 +123,49 @@ let vhosts = concatStringsSep "\n" (mapAttrsToList (vhostName: vhost: let - serverName = vhost.serverName; ssl = vhost.enableSSL || vhost.forceSSL; - port = if vhost.port != null then vhost.port else (if ssl then 443 else 80); - listenString = toString port + optionalString ssl " ssl http2" - + optionalString vhost.default " default_server"; - acmeLocation = optionalString vhost.enableACME ('' + defaultPort = if ssl then 443 else 80; + + listenString = { addr, port, ... }: + "listen ${addr}:${toString (if port != null then port else defaultPort)} " + + optionalString ssl "ssl http2 " + + optionalString vhost.default "default_server" + + ";"; + + redirectListenString = { addr, ... }: + "listen ${addr}:80 ${optionalString vhost.default "default_server"};"; + + acmeLocation = '' location /.well-known/acme-challenge { ${optionalString (vhost.acmeFallbackHost != null) "try_files $uri @acme-fallback;"} root ${vhost.acmeRoot}; auth_basic off; } - '' + (optionalString (vhost.acmeFallbackHost != null) '' - location @acme-fallback { - auth_basic off; - proxy_pass http://${vhost.acmeFallbackHost}; - } - '')); + ${optionalString (vhost.acmeFallbackHost != null) '' + location @acme-fallback { + auth_basic off; + proxy_pass http://${vhost.acmeFallbackHost}; + } + ''} + ''; + in '' ${optionalString vhost.forceSSL '' server { - listen 80 ${optionalString vhost.default "default_server"}; - ${optionalString enableIPv6 - ''listen [::]:80 ${optionalString vhost.default "default_server"};'' - } + ${concatMapStringsSep "\n" redirectListenString vhost.listen} - server_name ${serverName} ${concatStringsSep " " vhost.serverAliases}; - ${acmeLocation} + server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases}; + ${optionalString vhost.enableACME acmeLocation} location / { - return 301 https://$host${optionalString (port != 443) ":${toString port}"}$request_uri; + return 301 https://$host$request_uri; } } ''} server { - listen ${listenString}; - ${optionalString enableIPv6 "listen [::]:${listenString};"} - - server_name ${serverName} ${concatStringsSep " " vhost.serverAliases}; - ${acmeLocation} + ${concatMapStringsSep "\n" listenString vhost.listen} + server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases}; + ${optionalString vhost.enableACME acmeLocation} ${optionalString (vhost.root != null) "root ${vhost.root};"} ${optionalString (vhost.globalRedirect != null) '' return 301 http${optionalString ssl "s"}://${vhost.globalRedirect}$request_uri; @@ -380,7 +384,7 @@ in virtualHosts = mkOption { type = types.attrsOf (types.submodule (import ./vhost-options.nix { - inherit lib; + inherit config lib; })); default = { localhost = {}; diff --git a/nixos/modules/services/web-servers/nginx/vhost-options.nix b/nixos/modules/services/web-servers/nginx/vhost-options.nix index c0ea645b3df..60260512bc2 100644 --- a/nixos/modules/services/web-servers/nginx/vhost-options.nix +++ b/nixos/modules/services/web-servers/nginx/vhost-options.nix @@ -3,7 +3,7 @@ # has additional options that affect the web server as a whole, like # the user/group to run under.) -{ lib }: +{ config, lib }: with lib; { @@ -26,12 +26,26 @@ with lib; ''; }; - port = mkOption { - type = types.nullOr types.int; - default = null; + listen = mkOption { + type = with types; listOf (submodule { + options = { + addr = mkOption { type = str; description = "IP address."; }; + port = mkOption { type = nullOr int; description = "Port number."; }; + }; + }); + default = + [ { addr = "0.0.0.0"; port = null; } ] + ++ optional config.networking.enableIPv6 + { addr = "[::]"; port = null; }; + example = [ + { addr = "195.154.1.1"; port = 443; } + { addr = "192.168.1.2"; port = 443; } + ]; description = '' - Port for the server. Defaults to 80 for http - and 443 for https (i.e. when enableSSL is set). + Listen addresses and ports for this virtual host. + IPv6 addresses must be enclosed in square brackets. + Setting the port to null defaults + to 80 for http and 443 for https (i.e. when enableSSL is set). ''; };