diff --git a/hosts/vps1/default.nix b/hosts/vps1/default.nix index f6bda0b..d17173e 100644 --- a/hosts/vps1/default.nix +++ b/hosts/vps1/default.nix @@ -11,6 +11,7 @@ ./headscale.nix ./kanidm.nix ./matrix.nix + ./nginx.nix ./outline.nix ./photoprism.nix ../server.nix @@ -64,7 +65,6 @@ ]; repoPath = "ssh://p91y8oh7@p91y8oh7.repo.borgbase.com/./repo"; }; - nginx.enable = true; postgresql.enable = true; }; }; diff --git a/hosts/vps1/nginx.nix b/hosts/vps1/nginx.nix new file mode 100644 index 0000000..1609a83 --- /dev/null +++ b/hosts/vps1/nginx.nix @@ -0,0 +1,179 @@ +{ + pkgs, + ... +}: + +let + nginxErrorPages = '' + location @error_pages { + rewrite ^.*$ /''${status}.html break; + + root "/var/www/html/errors"; + } + ''; + nginxEdgeHeaders = '' + more_set_headers 'Server: Vimium'; + more_set_headers 'Access-Control-Allow-Origin: *'; + add_header Expect-CT max-age=30 always; + add_header Referrer-Policy strict-origin-when-cross-origin always; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; + add_header Vimium-Responding-Instance $hostname; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options nosniff always; + ''; + nginxStrictHeaders = '' + add_header X-Frame-Options SAMEORIGIN always; + add_header Permissions-Policy "fullscreen=(self), sync-xhr=(self)" always; + ''; + mkRedirect = from: to: { + "${from}" = { + forceSSL = true; + enableACME = true; + serverAliases = [ "www.${from}" ]; + locations."/".return = "301 https://${to}$request_uri"; + extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders; + }; + }; +in +{ + networking.firewall.allowedTCPPorts = [ + 80 # HTTP + 443 # HTTPS + ]; + + services.nginx = { + enable = true; + package = pkgs.openresty; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedTlsSettings = true; + clientMaxBodySize = "2G"; + sslProtocols = "TLSv1.2 TLSv1.3"; + sslCiphers = "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"; + appendHttpConfig = '' + error_page 400 @error_pages; + error_page 401 @error_pages; + error_page 403 @error_pages; + error_page 404 @error_pages; + error_page 405 @error_pages; + error_page 429 @error_pages; + error_page 500 @error_pages; + error_page 501 @error_pages; + error_page 502 @error_pages; + error_page 503 @error_pages; + error_page 504 @error_pages; + + client_body_buffer_size 16k; + client_header_buffer_size 8k; + ''; + appendConfig = '' + worker_processes auto; + worker_cpu_affinity auto; + worker_rlimit_nofile 50000; + ''; + eventsConfig = '' + worker_connections 20000; + multi_accept off; + ''; + proxyCachePath = { + "skycam" = { + enable = true; + keysZoneName = "skycam_cache"; + maxSize = "100m"; + }; + }; + virtualHosts = + { + ## Static sites + "jellyfin.vimium.com" = { + forceSSL = true; + enableACME = true; + extraConfig = nginxErrorPages + nginxEdgeHeaders; + locations."/" = { + proxyPass = "http://localhost:8000"; + extraConfig = '' + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + + proxy_set_header Range $http_range; + proxy_set_header If-Range $http_if_range; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + ''; + }; + }; + "jdholt.com" = { + forceSSL = true; + enableACME = true; + serverAliases = [ "www.jdholt.com" ]; + extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders; + locations."/skycam/snapshot.jpg" = { + extraConfig = '' + set $backend "skycam.mesh.vimium.net:8080"; + + resolver 100.100.100.100; + + proxy_pass http://$backend/snapshot; + proxy_cache skycam_cache; + proxy_cache_valid any 10s; + proxy_ignore_headers Cache-Control Expires Set-Cookie; + ''; + }; + locations."/".return = "301 https://vimium.com$request_uri"; + }; + "pki.vimium.com" = { + addSSL = true; + forceSSL = false; + enableACME = true; + extraConfig = '' + ${nginxErrorPages} + more_set_headers 'Server: Vimium'; + ''; + locations."/" = { + root = "/var/www/pki.vimium.com"; + }; + }; + "suhailhussain.com" = { + forceSSL = true; + enableACME = true; + serverAliases = [ "www.suhailhussain.com" ]; + extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders; + locations."/" = { + root = "/var/www/suhailhussain.com"; + }; + }; + "vimium.com" = { + default = true; + forceSSL = true; + enableACME = true; + serverAliases = [ "www.vimium.com" ]; + extraConfig = + nginxErrorPages + + nginxEdgeHeaders + + nginxStrictHeaders + + '' + add_header Content-Security-Policy "default-src 'self' https://vimium.com https://www.vimium.com; style-src 'unsafe-inline'; object-src 'none'; upgrade-insecure-requests" always; + ''; + locations."/" = { + root = "/var/www/vimium.com"; + }; + }; + } + ## Redirects + // (mkRedirect "h0lt.com" "jdholt.com") + // (mkRedirect "jordanholt.xyz" "jdholt.com") + // (mkRedirect "omnimagic.com" "vimium.com") + // (mkRedirect "omnimagic.net" "vimium.com") + // (mkRedirect "thelostlegend.com" "suhailhussain.com") + // (mkRedirect "vimium.co" "vimium.com") + // (mkRedirect "vimium.co.uk" "vimium.com") + // (mkRedirect "vimium.info" "vimium.com") + // (mkRedirect "vimium.net" "vimium.com") + // (mkRedirect "vimium.org" "vimium.com") + // (mkRedirect "vimium.xyz" "vimium.com"); + }; +} diff --git a/modules/nixos/services/nginx.nix b/modules/nixos/services/nginx.nix deleted file mode 100644 index 4f635f0..0000000 --- a/modules/nixos/services/nginx.nix +++ /dev/null @@ -1,193 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: - -with lib; - -let - cfg = config.modules.services.nginx; - nginxErrorPages = '' - location @error_pages { - rewrite ^.*$ /''${status}.html break; - - root "/var/www/html/errors"; - } - ''; - nginxEdgeHeaders = '' - more_set_headers 'Server: Vimium'; - more_set_headers 'Access-Control-Allow-Origin: *'; - add_header Expect-CT max-age=30 always; - add_header Referrer-Policy strict-origin-when-cross-origin always; - add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; - add_header Vimium-Responding-Instance $hostname; - add_header X-XSS-Protection "1; mode=block" always; - add_header X-Content-Type-Options nosniff always; - ''; - nginxStrictHeaders = '' - add_header X-Frame-Options SAMEORIGIN always; - add_header Permissions-Policy "fullscreen=(self), sync-xhr=(self)" always; - ''; - mkRedirect = from: to: { - "${from}" = { - forceSSL = true; - enableACME = true; - serverAliases = [ "www.${from}" ]; - locations."/".return = "301 https://${to}$request_uri"; - extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders; - }; - }; -in -{ - options.modules.services.nginx = { - enable = mkOption { - default = false; - example = true; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = [ - 80 # HTTP - 443 # HTTPS - ]; - - services.nginx = { - enable = true; - package = pkgs.openresty; - recommendedGzipSettings = true; - recommendedOptimisation = true; - recommendedTlsSettings = true; - clientMaxBodySize = "2G"; - sslProtocols = "TLSv1.2 TLSv1.3"; - sslCiphers = "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"; - appendHttpConfig = '' - error_page 400 @error_pages; - error_page 401 @error_pages; - error_page 403 @error_pages; - error_page 404 @error_pages; - error_page 405 @error_pages; - error_page 429 @error_pages; - error_page 500 @error_pages; - error_page 501 @error_pages; - error_page 502 @error_pages; - error_page 503 @error_pages; - error_page 504 @error_pages; - - client_body_buffer_size 16k; - client_header_buffer_size 8k; - ''; - appendConfig = '' - worker_processes auto; - worker_cpu_affinity auto; - worker_rlimit_nofile 50000; - ''; - eventsConfig = '' - worker_connections 20000; - multi_accept off; - ''; - proxyCachePath = { - "skycam" = { - enable = true; - keysZoneName = "skycam_cache"; - maxSize = "100m"; - }; - }; - virtualHosts = - { - ## Static sites - "jellyfin.vimium.com" = { - forceSSL = true; - enableACME = true; - extraConfig = nginxErrorPages + nginxEdgeHeaders; - locations."/" = { - proxyPass = "http://localhost:8000"; - extraConfig = '' - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header Host $host; - - proxy_set_header Range $http_range; - proxy_set_header If-Range $http_if_range; - - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - ''; - }; - }; - "jdholt.com" = { - forceSSL = true; - enableACME = true; - serverAliases = [ "www.jdholt.com" ]; - extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders; - locations."/skycam/snapshot.jpg" = { - extraConfig = '' - set $backend "skycam.mesh.vimium.net:8080"; - - resolver 100.100.100.100; - - proxy_pass http://$backend/snapshot; - proxy_cache skycam_cache; - proxy_cache_valid any 10s; - proxy_ignore_headers Cache-Control Expires Set-Cookie; - ''; - }; - locations."/".return = "301 https://vimium.com$request_uri"; - }; - "pki.vimium.com" = { - addSSL = true; - forceSSL = false; - enableACME = true; - extraConfig = '' - ${nginxErrorPages} - more_set_headers 'Server: Vimium'; - ''; - locations."/" = { - root = "/var/www/pki.vimium.com"; - }; - }; - "suhailhussain.com" = { - forceSSL = true; - enableACME = true; - serverAliases = [ "www.suhailhussain.com" ]; - extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders; - locations."/" = { - root = "/var/www/suhailhussain.com"; - }; - }; - "vimium.com" = { - default = true; - forceSSL = true; - enableACME = true; - serverAliases = [ "www.vimium.com" ]; - extraConfig = - nginxErrorPages - + nginxEdgeHeaders - + nginxStrictHeaders - + '' - add_header Content-Security-Policy "default-src 'self' https://vimium.com https://www.vimium.com; style-src 'unsafe-inline'; object-src 'none'; upgrade-insecure-requests" always; - ''; - locations."/" = { - root = "/var/www/vimium.com"; - }; - }; - } - ## Redirects - // (mkRedirect "h0lt.com" "jdholt.com") - // (mkRedirect "jordanholt.xyz" "jdholt.com") - // (mkRedirect "omnimagic.com" "vimium.com") - // (mkRedirect "omnimagic.net" "vimium.com") - // (mkRedirect "thelostlegend.com" "suhailhussain.com") - // (mkRedirect "vimium.co" "vimium.com") - // (mkRedirect "vimium.co.uk" "vimium.com") - // (mkRedirect "vimium.info" "vimium.com") - // (mkRedirect "vimium.net" "vimium.com") - // (mkRedirect "vimium.org" "vimium.com") - // (mkRedirect "vimium.xyz" "vimium.com"); - }; - }; -}