Commit 75545814 authored by toastal's avatar toastal
Browse files

nixos/h2o: enable HTTP/3 via QUIC

parent 301581e0
Loading
Loading
Loading
Loading
+19 −12
Original line number Diff line number Diff line
@@ -221,10 +221,7 @@ let
                            headerSet ++ [ hsts ];
                      }
                    );
              in
              value.settings
              // headerRecAttrs
              // {

                listen =
                  let
                    identity =
@@ -233,7 +230,8 @@ let
                        key-file = "${certs.${names.cert}.directory}/key.pem";
                        certificate-file = "${certs.${names.cert}.directory}/fullchain.pem";
                      };
                  in

                    baseListen =
                      {
                        port = port.TLS;
                        ssl = (lib.recursiveUpdate tlsRecAttrs value.tls.extraSettings) // {
@@ -243,7 +241,16 @@ let
                      // lib.optionalAttrs (value.host != null) {
                        host = value.host;
                      };

                    # QUIC, if used, will duplicate the TLS over TCP directive, but
                    # append some extra QUIC-related settings
                    quicListen = lib.optional (value.tls.quic != null) (baseListen // { inherit (value.tls) quic; });
                  in
                  {
                    listen = [ baseListen ] ++ quicListen;
                  };
              in
              value.settings // headerRecAttrs // listen;
          };
    in
    # With a high likelihood of HTTP & ACME challenges being on the same port,
+19 −0
Original line number Diff line number Diff line
@@ -152,6 +152,25 @@ in
                  '';
            };
            recommendations = tlsRecommendationsOption;
            quic = mkOption {
              type = types.nullOr types.attrs;
              default = null;
              description = ''
                Enables HTTP/3 over QUIC on the UDP port for TLS. The attrset
                provides fine-turning for QUIC behavior, but can be empty. See
                <https://h2o.examp1e.net/configure/http3_directives.html#quic-attributes>.
              '';
              example =
                literalExpression
                  # nix
                  ''
                    {
                      amp-limit = 2;
                      handshake-timeout-rtt-multiplier = 300;
                      retry = "ON";
                    }
                  '';
            };
            extraSettings = mkOption {
              type = types.attrs;
              default = { };
+23 −4
Original line number Diff line number Diff line
@@ -43,6 +43,10 @@ in
    server =
      { pkgs, ... }:
      {
        environment.systemPackages = [
          pkgs.curlHTTP3
        ];

        services.h2o = {
          enable = true;
          defaultHTTPListenPort = port.HTTP;
@@ -60,6 +64,9 @@ in
            "${domain.TLS}" = {
              tls = {
                policy = "force";
                quic = {
                  retry = "ON";
                };
                identity = [
                  {
                    key-file = ../../common/acme/server/acme.test.key.pem;
@@ -99,10 +106,15 @@ in
        ];

        networking = {
          firewall.allowedTCPPorts = with port; [
          firewall = {
            allowedTCPPorts = with port; [
              HTTP
              TLS
            ];
            allowedUDPPorts = with port; [
              TLS
            ];
          };
          extraHosts = ''
            127.0.0.1 ${domain.HTTP}
            127.0.0.1 ${domain.TLS}
@@ -130,6 +142,13 @@ in

      assert "${sawatdi_chao_lok}" in server.succeed("curl -v --http2 --tlsv1.3 --compressed --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'")

      quic_hello_world_head = server.succeed("curl -v --head --compressed --http3-only --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'").lower()
      assert "http/3 200" in quic_hello_world_head
      assert "server: h2o" in quic_hello_world_head
      assert "content-type: text/x-rst" in quic_hello_world_head

      assert "${sawatdi_chao_lok}" in server.succeed("curl -v --http3-only --compressed --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'")

      assert "redirected" in server.succeed("curl -v --head --fail-with-body 'http://${domain.TLS}:${portStrHTTP}/hello_world.rst'").lower()

      server.fail("curl --location --max-redirs 0 'http://${domain.TLS}:${portStrHTTP}/hello_world.rst'")