63

I am currently using ASP.NET Core 2.x and I used to be able to get Kestrel to to use HTTPS / SSL by simply putting it in the UseUrls() method like so:

var host = new WebHostBuilder()
    .UseUrls("http://localhost", "https://111.111.111.111")
    .UseKestrel()
    .Build();

But now I get the exception:

 System.InvalidOperationException:
     HTTPS endpoints can only be configured using KestrelServerOptions.Listen().

How do I configure Kestrel to use SSL in ASP.NET Core 2.x?

Svek
  • 12,350
  • 6
  • 38
  • 69
  • 2
    Refer to this post https://blogs.msdn.microsoft.com/webdev/2017/11/29/configuring-https-in-asp-net-core-across-different-platforms/ and the full source code https://github.com/aspnet/samples/tree/master/samples/aspnetcore/security/KestrelHttps – natenho Dec 16 '17 at 02:59

2 Answers2

96

The basics. Using Server URLs

If you want to associate your server to use all the IP addresses assigned to the server/web host then you can do this:

WebHost.CreateDefaultBuilder(args)
    .UseUrls("http://localhost:5000", "http://*:80")
    .UseStartup<Startup>()
    .Build();

Note: The string format used in the UseUrls() method is: http://{ip address}:{port number}.
- If you use an * (asterisks) for the IP address, that means all available IP address on the host.
- The port number is not a requirement. If you leave it blank it will default to port 80.

There is a great amount of additional detail about the UseUrls() method over at the official Microsoft Docs here.

However, SSL will not work with the UseUrls() method --- so, that means if you try to add a URL starting with https:// the program will throw the exception

System.InvalidOperationException:
    HTTPS endpoints can only be configured using KestrelServerOptions.Listen().

Endpoint configuration. Using HTTPS and binding a SSL certificate

HTTPS endpoints can only be configured using KestrelServerOptions.

Here is an example of using TCP sockets using the Listen method:

WebHost.CreateDefaultBuilder(args)
    .UseKestrel(options =>
    {
        options.Listen(IPAddress.Loopback, 5000);  // http:localhost:5000
        options.Listen(IPAddress.Any, 80);         // http:*:80
        options.Listen(IPAddress.Loopback, 443, listenOptions =>
        {
            listenOptions.UseHttps("certificate.pfx", "password");
        });
    })
    .UseStartup<Startup>()
    .Build();

Note: That if you use both the Listen method and UseUrls, the Listen endpoints override the UseUrls endpoints.

You can find more info about setting up endpoints here at the official Microsoft Docs.

If you use IIS, the URL bindings for IIS override any bindings that you set by calling either Listen or UseUrls. For more information, see Introduction to ASP.NET Core Module.

Svek
  • 12,350
  • 6
  • 38
  • 69
  • 1
    You could provide info on how to generate `certificate.pfx`, for example use https://andrewlock.net/creating-and-trusting-a-self-signed-certificate-on-linux-for-use-in-kestrel-and-asp-net-core/ as a starting point? – Andrei Rînea Nov 15 '17 at 16:49
  • 1
    @AndreiRînea - That's a really broad question. You could obtain an SSL certificate by purchasing one or you can self-sign it too. The process also depends on your operating system, etc. If you are using windows, maybe take a look at `certreq.exe` or you could use IIS too. – Svek Nov 15 '17 at 17:17
  • 6
    Kestrel for ASP.NET Core 2 is secure enough for a public endpoint. Kestrel for ASP.NET Core 1 was not. – robrich Nov 23 '17 at 06:43
  • 2
    @robrich Any references for this statement? – Anttu Nov 27 '17 at 08:57
  • 3
    @Anttu: head to https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore2x#when-to-use-kestrel-with-a-reverse-proxy, and switch between the 2.0 and 1.1 tabs. – robrich Dec 14 '17 at 07:21
  • You use a pfx file, but how to load from a certificate store? I have tried with `listenOptions.UseHttps(httpsOptions=>{ var localhostCert = CertificateLoader.LoadFromStoreCert("Test certificate", "My", StoreLocation.CurrentUser, allowInvalid:true);...`. I have generated certificate using powershell but NET Core cannot find it – Junior Mayhé Jun 17 '18 at 16:30
  • You may need to use a high numbered port (eg. 44300) if not running as admin. If you want to access the https site from another device you must use `IPAddress.Any` which allows 'outside' listening. – Simon_Weaver Dec 30 '18 at 08:12
  • I want my code to be agnostic about whether it's using IIS or Kestrel. I've got this working so that, with IIS, it can find the certificate associated with port 443 using the **netsh http** command. How do I do this for Kestrel? – Quark Soup Apr 04 '19 at 15:50
  • @AndreiRînea please refer [this](https://devblogs.microsoft.com/aspnet/configuring-https-in-asp-net-core-across-different-platforms/). Maybe it could be of any help. Maybe it's not too late to comment. :P – Praveen May 09 '19 at 07:30
  • @Svek totally worked! But remember you must use Kestrel in order to function; Using nginx means a totally different way to configure. – zion Oct 22 '19 at 13:51
  • Very useful, except that I had to explicitly remove `UseUrls`. Only after removing, the endpoints configured via `Listen` were working successfully. – Pieter Meiresone Mar 29 '20 at 11:31
  • @Svek If we want to use two certificates like below will this works. .UseKestrel(options => { options.Listen(IPAddress.Loopback, 5000); // http:localhost:5000 options.Listen(IPAddress.Any, 80); // http:*:80 options.Listen(IPAddress.Loopback, 443, listenOptions => { listenOptions.UseHttps("certificate.pfx", "password"); listenOptions.UseHttps("certificate1.pfx", "password1"); }); }) Please suggest me. – Mohan Gopi Oct 09 '20 at 04:26
  • how to use different pfx cert path for dev and prod env? above code seems like hardcoded. – Lei Yang Jan 14 '21 at 01:39
  • @LeiYang you would probably want to get that from your `IHostingEnvironment` and then do an `if` – Svek Jan 14 '21 at 08:32
  • but the code section you posted doesn't have a `IHostingEnvironment` **refererence** anywhere, that's why i ask this question. – Lei Yang Jan 14 '21 at 08:47
-1

You don't need to implement https with kestrel by itself. If you are running an application that requires https, it is most likely going to face outward to the internet. This means you need to run kestrel behind nginx or Apache and have one of those handle the https request for you.

Michael
  • 339
  • 4
  • 13
  • 18
    That's not true. There are many cases where encrypted communication for Kestrel is used internally and/or not hosted over a public endpoint. – Svek Oct 07 '17 at 17:19
  • 2
    Yes, internally is ok. But, the OP is talking about https. So, I assumed that it would be outward facing. Also, just because someone uses kestrel over a public endpoint, does not mean it is good to do. In my experience, I would never trust kestrel enough to face it toward the public. Especially when Microsoft doesn't recommend it themselves. – Michael Oct 07 '17 at 17:21
  • 5
    Downvoted. Plenty of reasons to need https with kestrel by itself. Kestrel is now a supported-but-not-certified edge server, per Damian Edwards. – Rich S Dec 02 '17 at 23:46
  • @RichS I see plenty of content by Damian Edwards where he recommends _always_ running Kestrel behind another "full featured" web server. I cannot find a case where he recommends it as an edge server without that. Would you mind sharing a reference? – Charlie Flowers Apr 10 '18 at 20:34
  • 8
    @Michael The question was "How do I *configure Kestrel* to use SSL in ASP.NET Core 2.x?", the answer "why don't you use a reverse proxy" isn't answering the question. – Rich S Apr 15 '18 at 20:34
  • 1
    @CharlieFlowers You can use Kestrel without an edge server with SSL on an internal network: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.1&tabs=aspnetcore2x#when-to-use-kestrel-with-a-reverse-proxy – Rich S Apr 15 '18 at 20:37
  • 1
    I think @Michael suggestion still holds, but maybe it's not a direct answer to the OP, so for StackOverflow etiquette it could have looked better as a comment to initial question. – superjos Apr 17 '18 at 14:34
  • We use Kestrel internally, but our network admins require that all servers use SSL. – Michael Earls Aug 07 '18 at 15:23