Snippet content copied to clipboard.
Are you sure to delete this snippet? No, don't delete
# 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;
# };
}

Edit this Snippet