# configuration.nix { config, pkgs, lib, ... }: let # Define an overlay to build nginxMainline with QUIC support. # This is necessary because the NixOS module doesn't automatically # enable this build-time feature. nginxOverlay = final: prev: { nginxMainline = prev.nginxMainline.overrideAttrs (oldAttrs: { # Ensure QUIC (HTTP/3) support is compiled in. withQuic = true; # kTLS support depends on runtime config + OpenSSL 3.0+ (usually default), # not typically a build flag here. }); # If you preferred the stable branch: # nginx = prev.nginx.overrideAttrs (oldAttrs: { withQuic = true; }); }; in { # Apply the overlay to nixpkgs for this configuration nixpkgs.overlays = lib.mkIf config.services.nginx.enable [ nginxOverlay ]; # Ensure a kernel with kTLS support is used (usually default). # boot.kernelPackages = pkgs.linuxPackages_latest; # Example if needed # --- Nginx Service Configuration --- services.nginx = { enable = true; # Explicitly select the package built by our overlay. # Change to pkgs.nginx if you overlayed that instead. package = pkgs.nginxMainline; # Use recommended base settings provided by the NixOS module recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; # Handles TLS protocols, ciphers, DH params etc. # --- Virtual Host Configuration (Example) --- virtualHosts."your.domain.com" = { # Use structured NixOS options where available forceSSL = true; # Redirect HTTP to HTTPS enableACME = true; # Use Let's Encrypt via security.acme.* # OR specify manual certs: # sslCertificate = "/path/to/your/fullchain.pem"; # sslCertificateKey = "/path/to/your/privkey.pem"; # Define listeners: TCP for HTTP/1.1+HTTP/2, UDP for HTTP/3 # The 'quic' and 'reuseport' keys are passed directly to nginx config # as the NixOS module doesn't have specific options for them. listen = [ # Standard IPv4 HTTPS/HTTP2 listener (TCP) { addr = "0.0.0.0"; port = 443; ssl = true; http2 = true; } # Standard IPv6 HTTPS/HTTP2 listener (TCP) { addr = "[::]"; port = 443; ssl = true; http2 = true; } # QUIC / HTTP/3 Listener (UDP/IPv4) { addr = "0.0.0.0"; port = 443; ssl = true; quic = true; reuseport = true; } # QUIC / HTTP/3 Listener (UDP/IPv6) { addr = "[::]"; port = 443; ssl = true; quic = true; reuseport = true; } ]; # Add directives not covered by specific NixOS options extraConfig = '' # === HTTP/3 Alt-Svc Header === # Advertise QUIC endpoint. No dedicated NixOS option for this header. # Adjust ma= (max age) as desired (86400 = 1 day). add_header Alt-Svc 'h3=":443"; ma=86400' always; # The 'always' ensures the header is added even on error pages etc. # === Kernel TLS (kTLS) === # Enable kTLS for TLS 1.3 over TCP connections. # Requires compatible kernel and Nginx built with OpenSSL 3.0+. # No dedicated NixOS option, so use ssl_conf_command. ssl_conf_command KTLSEnable on; # === Optional: HSTS Header === # While recommendedTlsSettings handles many security aspects, # HSTS is often added manually for fine control. add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; ''; # Example location block (use structured options) locations."/" = { root = "/var/www/your.domain.com"; # Or proxy pass: # proxyPass = "http://127.0.0.1:8080"; # extraConfig = '' # # Add proxy headers if needed # ''; }; }; }; # --- Firewall Configuration --- # Must allow UDP traffic on port 443 for HTTP/3 networking.firewall = { allowedTCPPorts = [ 80 443 ]; allowedUDPPorts = [ 443 ]; # For QUIC/HTTP3 }; # --- ACME (Let's Encrypt) Configuration (if using enableACME = true) --- security.acme = { acceptTerms = true; defaults.email = "your-email@example.com"; # For renewal notices # Consider using DNS challenge for wildcard certs or if port 80 is unavailable # defaults.challengeType = "dns-01"; # defaults.dnsProvider = "cloudflare"; # Example # environment.ACME_DNS_API_CREDENTIALS = "/path/to/creds.ini"; }; # Optional: Consider increasing UDP buffer limits for QUIC # boot.kernel.sysctl = { # "net.core.rmem_max" = 2500000; # "net.core.wmem_max" = 2500000; # }; }