HTTP/2 with ASP.NET Core 2.2
Asked Answered
A

1

6

I'm trying to get HTTP/2 working with ASP.Net Core 2.2. I'm testing on Windows 10 x64 1809.

I'm using the basic template with the following web host builder:

public static IWebHostBuilder CreateWebHostBuilderKestrel(string[] args)
{
    var builder = WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Listen(IPAddress.Any, 35000,
                lo =>
                {
                    lo.Protocols = HttpProtocols.Http1AndHttp2;
                    lo.UseHttps(@"path to cert");
                });
        });
    return builder;
}

When using Chrome it accepts the certificate and shows the site over HTTPS. The problem is that it's using HTTP/1.1 and not h2 when checking the network requests in the devtools section.

Using openssl s_client -connect 'host:35000' -cipher "EDH" gives the following output:

New, TLSv1.2, Cipher is DHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES256-GCM-SHA384
    Session-ID: FA0F0000C66FFFD36BE15AE79B2F48DF631EB83D0425DD534DAA278622CB30AE
    Session-ID-ctx:
    Master-Key: 2B10E9FD71B42328CAFAFBE18789777132565A98CE8CFD9B8E0452F6490929CB6D1B20AB57A000EDBFF40372C93EB547
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1552937526
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    Extended master secret: yes
---

The one thing that looks out of place is "No ALPN negotiated" and "Secure Renegotiation IS supported". Am I missing anything here?

The msdn site lists the following requirements:

TLS version 1.2 or later
Renegotiation disabled
Compression disabled
Minimum ephemeral key exchange sizes:
Elliptic curve Diffie-Hellman (ECDHE) [RFC4492] – 224 bits minimum
Finite field Diffie-Hellman (DHE) [TLS12] – 2048 bits minimum
Cipher suite not blacklisted

Not sure how I'd check most of these settings. Some of these seem like settings of the certificate, while others seem application specific.

Amalea answered 18/3, 2019 at 19:40 Comment(7)
Which version of OpenSSL are you using to test your site?Hydria
@Barry Old would be underselling it (I really only use it to create self signed certs for testing), but I'll try it tomorrow with an up-to-date version and update it with the results.Amalea
OpenSSL before 1.0.2 didn’t support ALPN so won’t negotiate it - eve if your server supports it.Hydria
@Barry I'm running OpenSSL 1.1.0i 14 Aug 2018, so that's not the problem.Amalea
Did you verify that you are targeting the right version? <TargetFramework>netcoreapp2.2</TargetFramework>Disrate
@Disrate Sure, but fair point. It's self-hosted with <TargetFramework>netcoreapp2.2</TargetFramework>, <PlatformTarget>x64</PlatformTarget>, and using <PackageReference Include="Microsoft.AspNetCore.App" />. I assume it might be a problem with the certificate, but no idea how to check that apart from the openssl output.Amalea
You can verify that if you e.g. generate a new one with dotnet dev-certs https and use the cert from the store with lo.UseHttps(StoreName.My, "localhost", allowInvalid: true);Disrate
V
1

I'm not sure if it's your case, but having similar issues, I've figured out an odd thing -

Here is the setup in the code that doesn't work -

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                 .UseKestrel(opt =>
                 {
                     int port = 44336;
                     opt.ListenAnyIP(port, listenOptions =>
                     {
                         listenOptions.UseHttps(@"cert.pfx", "...");
                         listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
                     });
                 })
                .UseStartup<Startup>();

Now, if I configure the same through the appsettings.json, it suddenly starts serving requests over HTTP/2 -

  public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .UseKestrel()
                    .UseStartup<Startup>();

  "AllowedHosts": "*",
  "Kestrel": {
    "EndPoints": {
      "HttpsInlineCertFile": {
        "Url": "https://localhost:44336",
        "Protocols": "Http1AndHttp2",
        "Certificate": {
          "Path": "./cert.pfx",
          "Password": "..."
        }
      }
    }
  }

Other from that, here are my thoughts on the requirements:

  • TLS version 1.2 or later - I guess any browser/Fiddler/Postman shall be able to provide you with this information.
  • Renegotiation disabled - if I'm not mistaken, server renegotiation has been disabled since TLS 1.2. Otherwise, setting DisableRenegoOnServer registry key to a non-zero value shall help - HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\DisableRenegoOnServer| DWORD=1
  • Compression disabled - not sure, but probably it's about response compression you would set in your Startup code
  • Minimum ephemeral key exchange sizes - you could check DevTools/Security tab in Chrome, and I know that FireFox could provide you with even more details. Check out How-to-identify-the-Cipher-used-by-an-HTTPS-Connection.
  • Cipher suite not blacklisted - once you know about the connection, you could check BadCipherSuites
Ventre answered 9/7, 2019 at 17:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.