summary refs log tree commit diff
path: root/nixos/modules/services/web-servers
diff options
context:
space:
mode:
authorRobin Gloster <mail@glob.in>2016-01-24 15:50:54 +0000
committerRobin Gloster <mail@glob.in>2016-07-28 11:58:37 +0000
commitf298be9ef44657fdd267f7c296b40d4c97c9c1fc (patch)
treeb28d0656f10d21b4bff49f58d16f1ad2e031810c /nixos/modules/services/web-servers
parent356c2fe00dcadfb61f01d3962bb61f0210dfb957 (diff)
downloadnixlib-f298be9ef44657fdd267f7c296b40d4c97c9c1fc.tar
nixlib-f298be9ef44657fdd267f7c296b40d4c97c9c1fc.tar.gz
nixlib-f298be9ef44657fdd267f7c296b40d4c97c9c1fc.tar.bz2
nixlib-f298be9ef44657fdd267f7c296b40d4c97c9c1fc.tar.lz
nixlib-f298be9ef44657fdd267f7c296b40d4c97c9c1fc.tar.xz
nixlib-f298be9ef44657fdd267f7c296b40d4c97c9c1fc.tar.zst
nixlib-f298be9ef44657fdd267f7c296b40d4c97c9c1fc.zip
nginx module: declarative config
Diffstat (limited to 'nixos/modules/services/web-servers')
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix113
-rw-r--r--nixos/modules/services/web-servers/nginx/location-options.nix32
-rw-r--r--nixos/modules/services/web-servers/nginx/vhost-options.nix96
3 files changed, 237 insertions, 4 deletions
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index 27a33f33ff93..ab5657a9aa92 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -7,18 +7,107 @@ let
   nginx = cfg.package;
   configFile = pkgs.writeText "nginx.conf" ''
     user ${cfg.user} ${cfg.group};
+    error_log stderr;
     daemon off;
 
     ${cfg.config}
 
-    ${optionalString (cfg.httpConfig != "") ''
     http {
       include ${cfg.package}/conf/mime.types;
+      include ${cfg.package}/conf/fastcgi.conf;
+
+      # optimisation
+      sendfile on;
+      tcp_nopush on;
+      tcp_nodelay on;
+      keepalive_timeout 65;
+      types_hash_max_size 2048;
+
+      # use secure TLS defaults
+      ssl_protocols TLSv1.2;
+      ssl_session_cache shared:SSL:42m;
+      ssl_session_timeout 23m;
+
+      ssl_ciphers EDH+aRSA+AES256:+AESGCM:ECDHE+aRSA+AES256;
+      ssl_ecdh_curve secp521r1;
+      ssl_prefer_server_ciphers on;
+
+      ssl_stapling on;
+      ssl_stapling_verify on;
+
+      gzip on;
+      gzip_disable "msie6";
+      gzip_proxied any;
+      gzip_comp_level 9;
+      gzip_buffers 16 8k;
+      gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
+
+      # sane proxy settings/headers
+      proxy_set_header        Host $host;
+      proxy_set_header        X-Real-IP $remote_addr;
+      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
+      proxy_set_header        X-Forwarded-Proto $scheme;
+      proxy_set_header        Accept-Encoding "";
+
+      proxy_redirect          off;
+      client_max_body_size    10m;
+      client_body_buffer_size 128k;
+      proxy_connect_timeout   90;
+      proxy_send_timeout      90;
+      proxy_read_timeout      90;
+      proxy_buffers           32 4k;
+      proxy_buffer_size       8k;
+      proxy_http_version      1.0;
+
+      server_tokens ${if cfg.serverTokens then "on" else "off"};
+      ${vhosts}
       ${cfg.httpConfig}
     }
-    ''}
     ${cfg.appendConfig}
   '';
+
+  vhosts = concatStringsSep "\n" (mapAttrsToList (serverName: vhost:
+      let
+        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 spdy";
+      in ''
+        ${if vhost.forceSSL then ''
+          server {
+            listen 80;
+            listen [::]:80;
+
+            server_name ${serverName} ${concatStringsSep " " vhost.serverAliases};
+            return 301 https://$host${optionalString (port != 443) ":${port}"}$request_uri;
+          }
+        '' else ""}
+
+        server {
+          listen ${listenString};
+          listen [::]:${listenString};
+
+          server_name ${serverName} ${concatStringsSep " " vhost.serverAliases};
+          ${optionalString (vhost.root != null) "root ${vhost.root};"}
+          ${optionalString (vhost.globalRedirect != null) ''
+            return 301 https://${vhost.globalRedirect}$request_uri;
+          ''}
+          ${optionalString ssl ''
+            ssl_certificate ${vhost.sslCertificate};
+            ssl_certificate_key ${vhost.sslCertificateKey};
+          ''}
+
+          ${genLocations vhost.locations}
+
+          ${vhost.extraConfig}
+        }
+      ''
+  ) cfg.virtualHosts);
+  genLocations = locations: concatStringsSep "\n" (mapAttrsToList (location: config: ''
+    location ${location} {
+      ${optionalString (config.proxyPass != null) "proxy_pass ${config.proxyPass};"}
+      ${optionalString (config.root != null) "root ${config.root};"}
+    }
+  '') locations);
 in
 
 {
@@ -86,8 +175,24 @@ in
         description = "Group account under which nginx runs.";
       };
 
-    };
+      serverTokens = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Show nginx version in headers and error pages";
+      };
 
+      virtualHosts = mkOption {
+        type = types.attrsOf (types.submodule (import ./vhost-options.nix {
+          inherit lib;
+        }));
+        default = {
+          localhost = {};
+        };
+        example = [];
+        description = ''
+        '';
+      };
+    };
   };
 
   config = mkIf cfg.enable {
@@ -107,7 +212,7 @@ in
       serviceConfig = {
         ExecStart = "${nginx}/bin/nginx -c ${configFile} -p ${cfg.stateDir}";
         ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
-        Restart = "on-failure";
+        Restart = "always";
         RestartSec = "10s";
         StartLimitInterval = "1min";
       };
diff --git a/nixos/modules/services/web-servers/nginx/location-options.nix b/nixos/modules/services/web-servers/nginx/location-options.nix
new file mode 100644
index 000000000000..6537e45a459d
--- /dev/null
+++ b/nixos/modules/services/web-servers/nginx/location-options.nix
@@ -0,0 +1,32 @@
+# This file defines the options that can be used both for the Apache
+# main server configuration, and for the virtual hosts.  (The latter
+# has additional options that affect the web server as a whole, like
+# the user/group to run under.)
+
+{ lib }:
+
+with lib;
+
+{
+  options = {
+    proxyPass = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      example = "http://www.example.org/";
+      description = ''
+        Adds proxy_pass directive and sets default proxy headers Host, X-Real-Ip
+        and X-Forwarded-For.
+      '';
+    };
+
+    root = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      example = /your/root/directory;
+      description = ''
+        Root directory for requests.
+      '';
+    };
+  };
+}
+
diff --git a/nixos/modules/services/web-servers/nginx/vhost-options.nix b/nixos/modules/services/web-servers/nginx/vhost-options.nix
new file mode 100644
index 000000000000..2acb3743677d
--- /dev/null
+++ b/nixos/modules/services/web-servers/nginx/vhost-options.nix
@@ -0,0 +1,96 @@
+# This file defines the options that can be used both for the Apache
+# main server configuration, and for the virtual hosts.  (The latter
+# has additional options that affect the web server as a whole, like
+# the user/group to run under.)
+
+{ lib }:
+
+with lib;
+{
+  options = {
+    serverAliases = mkOption {
+      type = types.listOf types.str;
+      default = [];
+      example = ["www.example.org" "example.org"];
+      description = ''
+        Additional names of virtual hosts served by this virtual host configuration.
+      '';
+    };
+
+    port = mkOption {
+      type = types.nullOr types.int;
+      default = null;
+      description = ''
+        Port for the server. 80 for http
+        and 443 for https (i.e. when enableSSL is set).
+      '';
+    };
+
+    enableSSL = mkOption {
+      type = types.bool;
+      default = false;
+      description = "Whether to enable SSL (https) support.";
+    };
+
+    forceSSL = mkOption {
+      type = types.bool;
+      default = false;
+      description = "Whether to always redirect to https.";
+    };
+
+    sslCertificate = mkOption {
+      type = types.path;
+      example = "/var/host.cert";
+      description = "Path to server SSL certificate.";
+    };
+
+    sslCertificateKey= mkOption {
+      type = types.path;
+      example = "/var/host.key";
+      description = "Path to server SSL certificate key.";
+    };
+
+    root = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      example = "/data/webserver/docs";
+      description = ''
+        The path of the web root directory.
+      '';
+    };
+
+    extraConfig = mkOption {
+      type = types.lines;
+      default = "";
+      description = ''
+        These lines go to the end of the vhost verbatim.
+      '';
+    };
+
+    globalRedirect = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      example = http://newserver.example.org/;
+      description = ''
+        If set, all requests for this host are redirected permanently to
+        the given URL.
+      '';
+    };
+
+    basicAuth = mkOption {
+      type = types.attrsOf types.str;
+      default = {};
+      description = "user = password";
+    };
+
+    locations = mkOption {
+      type = types.attrsOf (types.submodule (import ./location-options.nix {
+        inherit lib;
+      }));
+      default = {};
+      example = {};
+      description = ''
+      '';
+    };
+  };
+}