bN
Posted on April 10, 2021
Image par skylarvision de Pixabay
As part of a little side project I'm working on, I want to host an ASP.NET Web API on my own server at home. The purpose of this API is to send push notifications to an Angular client application. It is the main reason why I had to set up SSL communication for my web site: service worker needs the communication to be secured by TLS with a valid certificate in order to allow push notications. But that's not the subject of this article. Here I will focus on creating the certificate and loading it into Kestrel.
For the development phase I used a self-signed certificate, but now that I want to deploy it I need a real certificate certified by a certification authority. Because it is not a commercial but personal project I want to keep it entirely free. So I decided to generate a certificate with Let's Encrypt. Until recently, ASP.Net core was only supporting .PFX files and not .PEM files provided by Let's Encrypt. But .NET 5 has rectified the situation in version 5.0.0-preview8.
I could use a reverse-proxy like nginx or haproxy and let it handle the SSL stuff, but I wanted to keep it as simple as possible, so I decided to directly serve it using Kestrel.
Prerequisites
- A domain name that you own. Personally I registered to Duck DNS to get a free one.
- An ASP.NET web site binded to your domain (to prove you are the owner of the domain)
- A bash, preferably Linux ;) but Windows is OK too
Most of Internet providers allow you to configure NAT/PAT and DynDNS, so it should not be a problem to bind your DNS to an open port on a machine in your local network.
Obtain a free certificate
Most of certification authorities sell their certificates and they are expensive. This is because the process of registering often inquires verification made by a human. Hopefully there is Let's Encrypt to the rescue. Let's Encrypt is also a certificate authority but it is nonprofit. It aims to create a more secure and privacy-respecting Web.
The first thing you have to do is to install Certbot. There are many ways to do so depending on your system so I won't go into details. The recommanded way is to use snap. Personnaly I simply made a
$ sudo apt-get install certbot
and it did the job.
Now that you have certbot installed you can generate a new certificate and a private key. Once again there are many ways to do this depending on your server and certbot can be configured to automatically renew your certificate before it expires. Personnaly I used the manual way and will configure autorenew later:
$ sudo certbot certonly --manual
Certbot first ask you what is your domain name and then request you to prove you are in control of it:
Create a file containing just this data:
eZ4dZ4xUrIn7Fkyuy0Vd9giY5FoEPnm5cfGQXs_EDy0.gj7wCMjUoSpRopo7wvqqw5spi23jZdjLjtlCa00Cf2c
And make it available on your web server at this URL:
http://ssldemo.dev.to/.well-known/acme-challenge/eZ4dZ4xUrIn7Fkyuy0Vd9giY5FoEPnm5cfGQXs_EDy0
Modify your website to make the file available at the requested URL and then press ENTER. Certbot will download the file and verify that the content matches with what was requested. It will then issue a new certificate associated with your domain name and the private key used to sign the certicate. Files are created under
/etc/letsencrypt/live/ssldemo.dev.to/fullchain.pem
/etc/letsencrypt/live/ssldemo.dev.to/privkey.pem
Copy these two files in a secure place on the machine hosting your website and make sure no one can access them except your web application.
Kestrel configuration
Make sure your website application target at least .NET 5.0. You should have <TargetFramework>net5.0</TargetFramework>
in your .csproj file.
You now have to instruct Kestrel how to load your certificate. Open appsetting.json file and add a Kestrel section :
"Kestrel": {
"Certificates": {
"Default": {
"Path": "path/to/fullchain.pem",
"KeyPath": "path/to/privkey.pem"
}
}
}
You could also use environment variables if you prefer
And that's it ! The method ConfigureWebHostDefaults
uses Kestrel as the web server so it will use the Kestrel section to configure itself. Just make sure you load appsettings.json at startup (it is the case by default when you use CreateDefaultBuilder
). Thus, the provided SSL certificate and the private key will be loaded and used by your server. If you don't use ConfigureWebHostDefaults
then ensure that you have UseKestrel
on your webBuilder and it should be OK.
Now when you request your web API via HTTPS you should see a valid certificate in the address bar of your web browser:
Conclusion
I wrote this article because I didn't find many documentation on how to configure Kestrel to load PEM SSL certificate. It is my first article and I hope you will find it interesting, maybe even usefull.
If you are interested in, you can find the source code of my current side-project for which I had to load PEM SSL certificate in Kestrel.
- https://github.com/bNobo/wind-forecast-api : the web API
- https://github.com/bNobo/wind-forecast-website : the Angular client
Posted on April 10, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.