mermet: postgresql: install pg_top
[sourcephile-nix.git] / nixos / profiles / services / nginx.nix
index 264c4adf2dab91b449fcf9d78f585711d1eb4abb..5f267b3b35a67d5cace8cba4a59b2bf17cc19233 100644 (file)
-{ inputs, pkgs, lib, config, host, ... }:
+{ lib, config, host, hostName, inputs, ... }:
 let
   inherit (lib) types;
   inherit (config) networking;
   inherit (config.services) nginx;
 in
 {
-options = {
-  services.nginx = {
-    configs = lib.mkOption {
-      type = types.attrsOf types.lines;
-      default = {};
-      description = ''
-        Make some configs available to all virtual hosts.
-        Useful to workaround the reset of add_header:
-        https://blog.g3rt.nl/nginx-add_header-pitfall.html
-      '';
-      #apply = lib.mapAttrs (name: pkgs.writeText "${name}.conf");
+  options = {
+    services.nginx = {
+      configs = lib.mkOption {
+        type = types.attrsOf types.lines;
+        default = { };
+        description = ''
+          Make some configs available to all virtual hosts.
+          Useful to workaround the reset of add_header:
+          https://blog.g3rt.nl/nginx-add_header-pitfall.html
+        '';
+        #apply = lib.mapAttrs (name: pkgs.writeText "${name}.conf");
+      };
     };
   };
-};
-config = {
-systemd.tmpfiles.rules = [
-  "d '/dev/shm/nginx' '750' '${nginx.user}' '${nginx.group}' - -"
-];
-systemd.services.nginx = {
-  requires = [ "systemd-tmpfiles-setup-dev.service" ];
-  serviceConfig = {
-    # FIXME: remove all the mkForce in LogsDirectory
-    # whenever upstream uses a list instead of a string.
-    LogsDirectory = lib.mkForce ["nginx"];
-    StateDirectory = ["nginx"];
-    StateDirectoryMode = "2770";
-    #BindPaths = ["/dev/shm/nginx:/var/cache/nginx"];
-  };
-};
-services.nginx = {
-  eventsConfig = ''
-    multi_accept on;
-    use epoll;
-    worker_connections 1024;
-  '';
-  clientMaxBodySize = "20m";
-  recommendedGzipSettings = true;
-  recommendedOptimisation = false;
-  recommendedProxySettings = true;
-  recommendedTlsSettings = true;
-  resolver = {
-    ipv6 = lib.mkDefault (networking.defaultGateway6 != null);
-  };
-  serverTokens = false;
-  # Only allow PFS-enabled ciphers with AES256
-  #sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
-  #sslCiphers = "HIGH:!ADH:!MD5:!CAMELLIA:!SEED:!3DES:!DES:!RC4:!eNULL";
-  #sslCiphers = "EECDH+aRSA+AESGCM:EDH+aRSA:EECDH+aRSA:+AES256:+AES128:+SHA1:!CAMELLIA:!SEED:!3DES:!DES:!RC4:!eNULL";
-  sslDhparam = inputs.secrets + "/openssl/dh.pem";
-  sslProtocols = "TLSv1.3 TLSv1.2";
-  configs = rec {
-    http_add_headers = ''
-      # Enable CSP
-      #add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
+  config = {
+    systemd.tmpfiles.rules = [
+      "d '/dev/shm/nginx' '750' '${nginx.user}' '${nginx.group}' - -"
+    ];
+    systemd.services.nginx = {
+      requires = [ "systemd-tmpfiles-setup-dev.service" ];
+      serviceConfig = {
+        # FIXME: remove all the mkForce in LogsDirectory
+        # whenever upstream uses a list instead of a string.
+        LogsDirectory = lib.mkForce [ "nginx" ];
+        StateDirectory = [ "nginx" ];
+        StateDirectoryMode = "2771";
+        #BindPaths = ["/dev/shm/nginx:/var/cache/nginx"];
+      };
+    };
+    services.logrotate = {
+      enable = true;
+      settings.nginx = {
+        files = [
+          "/var/log/nginx/*.log"
+          "/var/log/nginx/*/*.log"
+          "/var/log/nginx/*/*/*.log"
+          "/var/log/nginx/*/*/*/*.log"
+          "/var/log/nginx/*/*/*/*/*.log"
+          "/var/log/nginx/*.json"
+          "/var/log/nginx/*/*.json"
+          "/var/log/nginx/*/*/*.json"
+          "/var/log/nginx/*/*/*/*.json"
+          "/var/log/nginx/*/*/*/*/*.json"
+        ];
+        frequency = "weekly";
+        rotate = 26;
+        compress = true;
+        delaycompress = true;
+        postrotate = ''
+          [ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`
+        '';
+      };
+    };
+    services.nginx = {
+      eventsConfig = ''
+        multi_accept on;
+        use epoll;
+        worker_connections 1024;
+      '';
+      clientMaxBodySize = "20m";
+      recommendedGzipSettings = true;
+      recommendedOptimisation = false;
+      recommendedProxySettings = true;
+      recommendedTlsSettings = true;
+      resolver = {
+        ipv6 = lib.mkDefault (networking.defaultGateway6 != null);
+      };
+      serverTokens = false;
+      # Only allow PFS-enabled ciphers with AES256
+      #sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
+      #sslCiphers = "HIGH:!ADH:!MD5:!CAMELLIA:!SEED:!3DES:!DES:!RC4:!eNULL";
+      #sslCiphers = "EECDH+aRSA+AESGCM:EDH+aRSA:EECDH+aRSA:+AES256:+AES128:+SHA1:!CAMELLIA:!SEED:!3DES:!DES:!RC4:!eNULL";
+      sslDhparam = inputs.self + "/hosts/${hostName}/nginx/dh4096.pem";
+      sslProtocols = "TLSv1.3 TLSv1.2";
+      configs = rec {
+        http_add_headers = ''
+          # Enable CSP
+          #add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
 
-      # Enable XSS protection of the browser.
-      # May be unnecessary when CSP is configured properly (see above)
-      add_header X-XSS-Protection "1; mode=block";
+          # Enable XSS protection of the browser.
+          # May be unnecessary when CSP is configured properly (see above)
+          add_header X-XSS-Protection "1; mode=block";
 
-      # Minimize information leaked to other domains
-      add_header 'Referrer-Policy' 'origin-when-cross-origin';
+          # Minimize information leaked to other domains
+          add_header 'Referrer-Policy' 'origin-when-cross-origin';
 
-      # Restrict embedding as a frame
-      #add_header X-Frame-Options SAMEORIGIN;
+          # Restrict embedding as a frame
+          #add_header X-Frame-Options SAMEORIGIN;
 
-      # Prevent injection of code in other mime types (XSS Attacks)
-      add_header X-Content-Type-Options nosniff;
-    '';
-    https_add_headers = ''
-      ${http_add_headers}
-      # Add HSTS header with preloading to HTTPS requests.
-      # Adding this header to HTTP requests is discouraged,
-      # as doing so makes the connection vulnerable to SSL stripping attacks
-      # DOC: https://blog.qualys.com/securitylabs/2016/03/28/the-importance-of-a-proper-http-strict-transport-security-implementation-on-your-web-server
-      add_header Strict-Transport-Security $hsts_header;
-    '';
-  };
-  commonHttpConfig = ''
-    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
-                    '$status $body_bytes_sent "$http_referer" '
-                    '"$http_user_agent" "$http_x_forwarded_for"';
-    log_format json escape=json '{'
-      '"time_local":"$time_local",'
-      '"host":"$host",'
-      '"request":"$request",'
-      '"status":"$status",'
-      '"http_referrer":"$http_referer",'
-      '"remote_addr":"$remote_addr",'
-      '"remote_user":"$remote_user",'
-      '"msec":"$msec",'
-      '"body_bytes_sent":"$body_bytes_sent",'
-      '"bytes_sent":"$bytes_sent",'
-      '"http_user_agent":"$http_user_agent",'
-      '"request_length":"$request_length",'
-      '"request_method":"$request_method",'
-      '"request_time":"$request_time",'
-      '"request_uri":"$request_uri",'
-      '"server_protocol":"$server_protocol",'
-      '"ssl_protocol":"$ssl_protocol",'
-      '"upstream_addr":"$upstream_addr",'
-      '"upstream_connect_time":"$upstream_connect_time",'
-      '"upstream_response_time":"$upstream_response_time"'
-    '}';
-    charset UTF-8;
-    types {
-      text/html html5;
-      text/plain dump;
-    }
-    '' +
-    lib.concatStringsSep "\n" (lib.attrValues {
-      default = ''
-        #default_type application/octet-stream;
-        root /var/lib/nginx;
-      '';
-      security = ''
-        #error_page 403 = 404;
+          # Prevent injection of code in other mime types (XSS Attacks)
+          add_header X-Content-Type-Options nosniff;
+        '';
+        https_add_headers = ''
+          ${http_add_headers}
+          # Add HSTS header with preloading to HTTPS requests.
+          # Adding this header to HTTP requests is discouraged,
+          # as doing so makes the connection vulnerable to SSL stripping attacks
+          # DOC: https://blog.qualys.com/securitylabs/2016/03/28/the-importance-of-a-proper-http-strict-transport-security-implementation-on-your-web-server
+          add_header Strict-Transport-Security $hsts_header;
+        '';
+      };
+      commonHttpConfig = ''
+        log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+                        '$status $body_bytes_sent "$http_referer" '
+                        '"$http_user_agent" "$http_x_forwarded_for"';
+        log_format json escape=json '{'
+          '"time_local":"$time_local",'
+          '"host":"$host",'
+          '"request":"$request",'
+          '"status":"$status",'
+          '"http_referrer":"$http_referer",'
+          '"remote_addr":"$remote_addr",'
+          '"remote_user":"$remote_user",'
+          '"msec":"$msec",'
+          '"body_bytes_sent":"$body_bytes_sent",'
+          '"bytes_sent":"$bytes_sent",'
+          '"http_user_agent":"$http_user_agent",'
+          '"request_length":"$request_length",'
+          '"request_method":"$request_method",'
+          '"request_time":"$request_time",'
+          '"request_uri":"$request_uri",'
+          '"server_protocol":"$server_protocol",'
+          '"ssl_protocol":"$ssl_protocol",'
+          '"upstream_addr":"$upstream_addr",'
+          '"upstream_connect_time":"$upstream_connect_time",'
+          '"upstream_response_time":"$upstream_response_time"'
+        '}';
+        charset UTF-8;
+        types {
+          text/html html5;
+          text/plain dump;
+        }
+      '' +
+      lib.concatStringsSep "\n" (lib.attrValues {
+        default = ''
+          #default_type application/octet-stream;
+          root /var/lib/nginx;
+        '';
+        security = ''
+          #error_page 403 = 404;
 
-        ${nginx.configs.http_add_headers}
+          ${nginx.configs.http_add_headers}
 
-        # This might create errors
-        #proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
-      '';
-      log = ''
-        access_log /var/log/nginx/access.json json buffer=32k;
-        error_log  /var/log/nginx/error.log warn;
-        open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;
-      '';
-      proxy = ''
-        proxy_cache_use_stale updating;
-        proxy_temp_path /var/cache/nginx/proxy_temp 1 2;
-      '';
-      fastcgi = ''
-        # DOC: http://wiki.nginx.org/HttpFastcgiModule
-        fastcgi_buffer_size 128k;
-        fastcgi_buffers 256 4k;
-        fastcgi_busy_buffers_size 256k;
-        fastcgi_cache_key "$request_method $scheme://$http_host$request_uri";
-        fastcgi_connect_timeout 60;
-        fastcgi_ignore_client_abort off;
-        fastcgi_intercept_errors on;
-        fastcgi_max_temp_file_size 2M;
-        #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-        fastcgi_param SCRIPT_FILENAME $request_filename;
-        fastcgi_temp_path /var/cache/nginx/fastcgi_temp 1 2;
-      '';
-      connection = ''
-        sendfile on;
-        # If the client stops reading data,
-        # free up the stale client connection after this much time.
-        send_timeout 60;
-        # Causes nginx to attempt to send its HTTP response head
-        # in one packet, instead of using partial frames.
-        # This is useful for prepending headers before calling sendfile,
-        # or for throughput optimization.
-        tcp_nopush on;
-        # Don't buffer data-sends (disable Nagle algorithm).
-        # Good for sending frequent small bursts of data in real time.
-        tcp_nodelay on;
-        keepalive_timeout 20;
-        reset_timedout_connection on;
-        types_hash_max_size 4096;
-        server_names_hash_bucket_size 128;
-      '';
-      map = ''
-        map $time_iso8601 $date {
-          default 'date-not-found';
-          '~^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})' $year-$month-$day;
-        }
+          # This might create errors
+          #proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
+        '';
+        log = ''
+          access_log /var/log/nginx/access.json json;
+          error_log  /var/log/nginx/error.log warn;
+          open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;
+        '';
+        proxy = ''
+          proxy_cache_use_stale updating;
+          proxy_temp_path /var/cache/nginx/proxy_temp 1 2;
+        '';
+        fastcgi = ''
+          # DOC: http://wiki.nginx.org/HttpFastcgiModule
+          fastcgi_buffer_size 128k;
+          fastcgi_buffers 256 4k;
+          fastcgi_busy_buffers_size 256k;
+          fastcgi_cache_key "$request_method $scheme://$http_host$request_uri";
+          fastcgi_connect_timeout 60;
+          fastcgi_ignore_client_abort off;
+          fastcgi_intercept_errors on;
+          fastcgi_max_temp_file_size 2M;
+          #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+          fastcgi_param SCRIPT_FILENAME $request_filename;
+          fastcgi_temp_path /var/cache/nginx/fastcgi_temp 1 2;
+        '';
+        connection = ''
+          sendfile on;
+          # If the client stops reading data,
+          # free up the stale client connection after this much time.
+          send_timeout 60;
+          # Causes nginx to attempt to send its HTTP response head
+          # in one packet, instead of using partial frames.
+          # This is useful for prepending headers before calling sendfile,
+          # or for throughput optimization.
+          tcp_nopush on;
+          # Don't buffer data-sends (disable Nagle algorithm).
+          # Good for sending frequent small bursts of data in real time.
+          tcp_nodelay on;
+          keepalive_timeout 20;
+          reset_timedout_connection on;
+          server_names_hash_bucket_size 128;
+        '';
+        map = ''
+          map $time_iso8601 $date {
+            default 'date-not-found';
+            '~^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})' $year-$month-$day;
+          }
 
-        map $scheme $hsts_header {
-          https  "max-age=31536000; includeSubdomains; preload";
-        }
+          map $scheme $hsts_header {
+            https  "max-age=31536000; includeSubdomains; preload";
+          }
 
-        # User agents that are to be blocked.
-        #map $http_user_agent $bad_bot {
-        #  default 0;
-        #  libwww-perl 1;
-        #  ~(?i)(httrack|htmlparser|libwww) 1;
-        #}
-        # Referrers that are to be blocked.
-        #map $http_referer $bad_referer {
-        #  default 0;
-        #  ~(?i)(babes|casino|click|diamond|forsale|girl|jewelry|love|nudit|organic|poker|porn|poweroversoftware|replica|sex|teen|webcam|zippo) 1;
-        #}
-        #geo $not_local {
-        #  default 1;
-        #  127.0.0.1 0;
-        #}
-      '';
-      cache = ''
-        client_body_buffer_size 4K;
-          # getconf PAGESIZE
-          # 4096
-        client_body_temp_path /var/cache/nginx/client_body_temp 1 2;
-        client_body_timeout 60;
-        client_header_buffer_size 1k;
-        client_header_timeout 60;
-        large_client_header_buffers 4 8k;
+          # User agents that are to be blocked.
+          #map $http_user_agent $bad_bot {
+          #  default 0;
+          #  libwww-perl 1;
+          #  ~(?i)(httrack|htmlparser|libwww) 1;
+          #}
+          # Referrers that are to be blocked.
+          #map $http_referer $bad_referer {
+          #  default 0;
+          #  ~(?i)(babes|casino|click|diamond|forsale|girl|jewelry|love|nudit|organic|poker|porn|poweroversoftware|replica|sex|teen|webcam|zippo) 1;
+          #}
+          #geo $not_local {
+          #  default 1;
+          #  127.0.0.1 0;
+          #}
+        '';
+        cache = ''
+          client_body_buffer_size 4K;
+            # getconf PAGESIZE
+            # 4096
+          client_body_temp_path /var/cache/nginx/client_body_temp 1 2;
+          client_body_timeout 60;
+          client_header_buffer_size 1k;
+          client_header_timeout 60;
+          large_client_header_buffers 4 8k;
 
-        open_file_cache max=200000 inactive=20s;
-        open_file_cache_errors on;
-        open_file_cache_min_uses 2;
-        open_file_cache_valid 30s;
+          open_file_cache max=200000 inactive=20s;
+          open_file_cache_errors on;
+          open_file_cache_min_uses 2;
+          open_file_cache_valid 30s;
+        '';
+      });
+      appendConfig = ''
+        worker_processes ${toString host.CPUs};
       '';
-    });
-  appendConfig = ''
-    worker_processes ${toString host.CPUs};
-  '';
-};
-};
+    };
+  };
 }