HTTP/3 is the latest version of the HTTP protocol, built on top of QUIC transport protocol. It offers improved performance, especially on unreliable networks, and better connection handling. In this post, I’ll show you how to enable HTTP/3 on NixOS using nginx.

Prerequisites

To use HTTP/3, you’ll need:

  • NixOS (any recent version)
  • A domain name
  • SSL certificate (we’ll use Let’s Encrypt)

Firewall Configuration

First, we need to open the necessary ports. HTTP/3 uses UDP port 443 for QUIC, alongside the traditional TCP ports:

  networking.firewall.allowedTCPPorts = [
    80    # HTTP
    443   # HTTPS
  ];

  networking.firewall.allowedUDPPorts = [
    443   # Required for HTTP/3 QUIC
  ];

Nginx Configuration

The key to enabling HTTP/3 on NixOS is using the nginxQuic package instead of the regular nginx package. Here’s the complete configuration:

  services.nginx = {
    enable = true;
    package = pkgs.nginxQuic;
    recommendedProxySettings = true;
    recommendedTlsSettings = true;

    # Add HTTP/3 specific settings
    commonHttpConfig = ''
      http2 on;
      ssl_early_data on;
    '';

    virtualHosts = {
      "mydomain.com" = {
        enableACME = true;      # Automatic SSL certificates
        forceSSL = true;        # Redirect HTTP to HTTPS
        http3 = true;           # Enable HTTP/3
        quic = true;            # Enable QUIC transport
        root = "/var/www/mydomain.com";
        locations."/" = {
          index = "index.html";
          extraConfig = ''
            add_header Alt-Svc 'h3=":443"; ma=86400' always;
          '';
        };
      };
    };
  };

Let’s break down the important parts:

  1. package = pkgs.nginxQuic: This uses the nginx build with QUIC support
  2. http3 = true and quic = true: Enables HTTP/3 and QUIC transport
  3. ssl_early_data on: Enables TLS 1.3 early data
  4. add_header Alt-Svc: Tells browsers that HTTP/3 is available on this server

Verifying HTTP/3

After deploying the configuration, you can verify that HTTP/3 is working by:

  1. Using Chrome DevTools Network panel and enabling the “Protocol” column
  2. Using online tools like https://http3check.net
  3. Using curl with HTTP/3 support: curl --http3 https://your-domain.com

Conclusion

Enabling HTTP/3 on NixOS is straightforward thanks to the nginxQuic package. The configuration mainly involves:

  • Opening UDP port 443 for QUIC
  • Using the correct nginx package
  • Enabling HTTP/3 and QUIC in the virtual host configuration
  • Adding the Alt-Svc header

With these changes, your NixOS server will serve content using the latest HTTP protocol, providing better performance for your users.