Certificate problem starting Kestrel ASP.NET server - Windows 10, C#, VS2019 - c#

My ASP.NET server was running fine on Friday. Today (Monday) I can't even start it. Error is:
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions)
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
I have tried dotnet dev-certs https --trust many times to no avail. Each time it gives me the prompt to trust the certificate, each time with a different thumbprint.
... but nothing changes, the server still fails with the same error message. dotnet dev-certs https --check just says No valid certificate found. I have tried dotnet dev-certs https --clean which claims to succeed (but does not display any prompts), then dotnet dev-certs https --trust but still the same error when I start the server.
I have tried looking in the certificate manager in control panel (certmgr.msc) because doing so seemed to help someone else (on a different site) to solve the same error, but I have to admit I am none the wiser for having looked. Here's what shows up under Personal:
I have discovered that the server runs fine through IIS, running using the IIS profile from Visual Studio 2019. Ok, I could go adapt the client code to talk to a different TCP port, OR learn how to change the IIS server port (launchSettings.json right?).. but I would rather understand what has actually broken here, and learn how to fix it properly.
In case it helps, my Startup.Configure() says:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// for options and correct order, see https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.1
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
// app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
So:
How do I get a dev certificate into the default certificate location (wherever that is??) in a way that actually works? <-- my preferred fast solution today :/
Or, how do I create a dev certificate myself, and how do I tell my server where to find it?
Or, how do I make a real certificate (from my organisation's "official" certificate??) and then how do I use that to get client and server to actually check it, for good security? <-- my goal eventually, but I don't currently know enough yet to be able to do this - currently, my security comes from running client and server on a separate network.

Here's what finally worked for me.
The problem was that although the Certificate Manager was not showing any expired ASP.NET certificates, the Certificate Manager was only looking at the local machine store, not the user store.
I went to the Management Console (mmc from command line) and added a Snap-in for Certificates, for current user.
When I then ran that, I found a whole bunch of ASP.NET certificates under Personal / Certificates AND Trusted Root Certification Authorities / Certificates, some of them expired. I deleted all of them.
I then ran dotnet dev-certs https --trust again, and then my server started. Yay!

You need to delete all certificates issued for localhost, best way how to do it is with this Powershell script:
Get-ChildItem -Path Cert:\CurrentUser -Recurse `
| Where { $_.PSISContainer -eq $false } `
| Where { $_.Issuer -match 'localhost' } `
| Remove-Item;
Get-ChildItem -Path Cert:\LocalMachine -Recurse `
| Where { $_.PSISContainer -eq $false } `
| Where { $_.Issuer -match 'localhost' } `
| Remove-Item
After that you will be sure that all certificates issued for localhost are gone.
Then run
dotnet dev-certs https
That's it!

Related

DotNet Linux error - Unable to configure HTTPS endpoint. No server certificate was specified

I am trying to run a DotNet Core https server on a Linux container. When I tried running on http, there were no issues.
However, when I try to run using https, I get the following exception:
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions)
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
Unhandled exception. System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions)
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
at Chat.Program.Main(String[] args) in C:\Users\localadmin\source\repos\websocket-manager\samples\chat\Program.cs:line 14
Aborted (core dumped)
Now I know some of you managed to solve this using the commands in Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found, but my container doesn't have dotnet cli installed (that's because I'm not alowed to install it), my application being published as Self-Conatined for linux.
I wanted to ask you if there's a way to solve this issue, without having to install dotnet on the container? Thanks!
I think you should run the
dotnet dev-certs https
Or remove HTTPS support Configure function in remove code
app.UseHttpsRedirection();
You use docker image mcr.microsoft.com/dotnet/aspnet:5.0
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY . /app
WORKDIR /app
EXPOSE 80
EXPOSE 443
ENTRYPOINT ["dotnet", "dev_ops.dll"]
From MS docs: Hosting ASP.NET Core images with Docker over HTTPS - macOS or Linux
dotnet dev-certs https --trust is only supported on macOS and Windows.
You need to trust certs on Linux in the way that is supported by your
distribution. It is likely that you need to trust the certificate in
your browser.
Adding trusted root certificates to the server
Linux (Ubuntu, Debian)
Copy your CA to dir /usr/local/share/ca-certificates/ U
Use command: sudo cp foo.crt/usr/local/share/ca-certificates/foo.crt
Update the CA store: sudo update-ca-certificates
Then,
docker pull mcr.microsoft.com/dotnet/samples:aspnetapp
docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v %USERPROFILE%\.aspnet\https:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp
There is also example for docker-compose Hosting ASP.NET Core images with Docker Compose over HTTPS - macOS or Linux

HTTP get Status code 404 when trying to a .Net project in Ubuntu 20.04

i am trying to Run a .Net project in Linux machine, the build shows Successfull without any error.
Following is the General Header Information for the Browser.
Request URL: https://localhost:5001/
Request Method: GET
Status Code: 404
Remote Address: [::1]:5001
Referrer Policy: strict-origin-when-cross-origin
where as on the other hand on windows the Browser seems to run correct with 200 reason code. please advice.
A little checklist, which worked for me:
Comment try_files $uri $uri/ =404; line in your nginx host configuraion in
sudo nano /etc/nginx/sites-available/<your-site>
or/and
sudo nano /etc/nginx/sites-available/default
as it's testing if a certain url exists on the file system and if not return 404.
Also I commented all content in sudo nano /etc/nginx/sites-available/default file to be sure that nothing excess prevents the api from working (if your api configuration is in separate file like /etc/nginx/sites-available/<your-site>)
Restart nginx then
sudo systemctl restart nginx && systemctl status nginx
In your dotnet project, check that redirect middleware is only used in production environment or try to comment for all environments to detect if this is the problem (worked for my case)
if (!app.Environment.IsDevelopment())
{
app.UseHttpsRedirection(); //leave like this or try to comment it just for checking
}
Also in your dotnet project, check if you have your api path setting. Something like:
app.UsePathBase(apiBasePath);
Make sure, that this path is the same as location setting in files from step one.
Of course, don't forget to upload your project on server if changes happened and restart your api service:
sudo systemctl restart your-kestrel-api.service

Configure SSL certificate for Kestrel WebHost builder In .NET Console App

I'm creating an ASP.NET Web API endpoint inside a console app which I need to host as a Windows Service.
Now everything is working except the endpoint is in http. I want to use https.
When I run it via Visual Studio.
I believe the Kestrel is behind an IIS as a reverse proxy and SSL certificates are validated. But when I host it as a Windows service. I'm getting certificate errors when trying to reach the endpoint
This is my Kestrel WebHost builder
var configigurations = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false)
.Build();
var host = new WebHostBuilder()
.UseKestrel(options =>
{
options.ListenAnyIP(443, listenOptions =>
{
listenOptions.UseHttps("sslcertificate.pfx", "ssl#123");
});
})
.UseUrls(config.ApiBaseUrl)
.UseConfiguration(configigurations)
.UseStartup<Startup>()
.Build();
host.Run();
Since it runs as a Windows service and exposes the API, I cannot rely on IIS. I need to configure for Kestrel.
But how can I
Generate an SSL for localhost (I'm using Windows)
If I have already an SSL certificate in production (*.cert). How can I make a *.pfx (cert + RSA private key) from it on production server (also Windows)
This will create a certificate
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p crypticpassword
This will create a trust
dotnet dev-certs https --trust
.Net Core (and .Net 5) is bundled with a convenient tool to handle development self-signed certificates. Look into dotnet dev-certs. The commands are:
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p crypticpassword
dotnet dev-certs https --trust
This doc also describes how to do the same thing with PowerShell or openssl if that's your style
Look into this question. In short, you can do that by exporting certificate from Windows Certificate store and choosing "Yes, export Private key" which automatically enabled PFX format

net::ERR_CERT_AUTHORITY_INVALID in ASP.NET Core

I am getting the net::ERR_CERT_AUTHORITY_INVALID error in ASP.NET Core when I try to request my Web API from an SPA.
The first solution to fix the issue was to go my ASP.NET Core address from browser Advanced - Proceed to localhost (unsafe) and after that the requests from my SPA would work. But I would have to repeat the procedure each time I am starting to work on my project.
Another solution I found was this. In a nutshell the solution is to run the command: dotnet dev-certs https --trust. I am on Windows, so according to the linked article On Windows it'll get added to the certificate store.
But after I run the command I am still getting the net::ERR_CERT_AUTHORITY_INVALID issue on requests. What could I do about it?
Running the command dotnet dev-certs https --trust will create a self-signed certificate in your device. This certificate will be issued to the localhost domain. In my case, after running it, the certificate was created but it was not added to "Trusted Root Certification Authorities".
To add the certificate, you will need to open certmgr.msc (win+r and run certmgr.msc), then go to "Personal" certificates and export the .cer certificate issued to localhost with the correct expiration time.
If you cannot find the certificate there, you can go to the browser and click on the not secure connection icon, then open the invalid certificate and go to the Details tab and click "Copy to File...", which should create also a .cer certificate.
Next, go to "Trusted Root Certification Authorities" and import the certificate there. Once that is done, the certificate will be valid in your local machine. You may need to restart the browser and the service.
In your application, add a reference to the Microsoft.AspNetCore.Authentication.Certificate via NuGet package. Then in the Startup.ConfigureServices method write this:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(
CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate();
// All other service configuration
}
Also add app.UseAuthentication(); in the Startup.Configure method. Otherwise, the HttpContext.User will not be set to ClaimsPrincipal
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
// All other app configuration
}
Source: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.1
Do this in the order
dotnet dev-certs https --clean
Remove your keys and pem from AppData\Roaming\ASP.NET\https
dotnet dev-certs https --trust
Run SPA project with "start": "set HTTPS=true&&react-scripts start"
If you run your project(Point 4) before anything else. The authority is not trusted(done by 2) and results in authority invalid errors
I followed these steps and it didn't stop the "Not secure" message appearing in Chrome. So then I tried commenting the following line //app.UseHttpsRedirection(); in startup.cs in the Configure() method and it fixed the problem.

Install ssl certificate for ASP.NET Core hosted on nginx on raspberrypi (raspbian) [duplicate]

I'm new in ASP.NET.
Environment:
Ubuntu 18.04
Visual Studio Code
.NET SDK 2.2.105
I'm in trouble with some command running.
I was reading tutorial at
https://learn.microsoft.com/ja-jp/aspnet/core/tutorials/razor-pages/razor-pages-start?view=aspnetcore-2.2&tabs=visual-studio-code
and ran this command:
dotnet dev-certs https --trust
I expect https://localhost should be trusted.
but I found the error message;
$ Specify --help for a list of available options and commands.
It seems that the command "dotnet dev-certs https" has no --trust options.
How to resolve this problem?
On Ubuntu the standard mechanism would be:
dotnet dev-certs https -v to generate a self-signed cert
convert the generated cert in ~/.dotnet/corefx/cryptography/x509stores/my from pfx to pem using openssl pkcs12 -in <certname>.pfx -nokeys -out localhost.crt -nodes
copy localhost.crt to /usr/local/share/ca-certificates
trust the certificate using sudo update-ca-certificates
verify if the cert is copied to /etc/ssl/certs/localhost.pem (extension changes)
verify if it's trusted using openssl verify localhost.crt
Unfortunately this does not work:
dotnet dev-certs https generates certificates that are affected by the issue described on https://github.com/openssl/openssl/issues/1418 and https://github.com/dotnet/aspnetcore/issues/7246:
$ openssl verify localhost.crt
CN = localhost
error 20 at 0 depth lookup: unable to get local issuer certificate
error localhost.crt: verification failed
due to that it's impossible to have a dotnet client trust the certificate
Workaround: (tested on Openssl 1.1.1c)
manually generate self-signed cert
trust this cert
force your application to use this cert
In detail:
manually generate self-signed cert:
create localhost.conf file with the following content:
[req]
default_bits = 2048
default_keyfile = localhost.key
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_ca
[req_distinguished_name]
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = localhost
commonName_max = 64
[req_ext]
subjectAltName = #alt_names
[v3_ca]
subjectAltName = #alt_names
basicConstraints = critical, CA:false
keyUsage = keyCertSign, cRLSign, digitalSignature,keyEncipherment
[alt_names]
DNS.1 = localhost
DNS.2 = 127.0.0.1
generate cert using openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt -config localhost.conf
convert cert to pfx using openssl pkcs12 -export -out localhost.pfx -inkey localhost.key -in localhost.crt
(optionally) verify cert using openssl verify -CAfile localhost.crt localhost.crt which should yield localhost.crt: OK
as it's not trusted yet using openssl verify localhost.crt should fail with
CN = localhost
error 18 at 0 depth lookup: self signed certificate
error localhost.crt: verification failed
trust this cert:
copy localhost.crt to /usr/local/share/ca-certificates
trust the certificate using sudo update-ca-certificates
verify if the cert is copied to /etc/ssl/certs/localhost.pem (extension changes)
verifying the cert without the CAfile option should work now
$ openssl verify localhost.crt
localhost.crt: OK
force your application to use this cert
update your appsettings.json with the following settings:
"Kestrel": {
"Certificates": {
"Default": {
"Path": "localhost.pfx",
"Password": ""
}
}
}
While the answer provided by #chrsvdb is helpful it does not solve all problems. I still had issue with service-to-service communication (HttpClient - PartialChain error) and also you must reconfigure Kestrel to use your own certificate. It is possible to create a self-signed certificate and import it to the .NET SDK. All you need is to specify the 1.3.6.1.4.1.311.84.1.1 extension in the certificate.
After that the cert can be imported into .NET Core SDK and trusted. Trusting in Linux is a bit hard as each application can have it's own certificate store. E.g. Chromium and Edge use nssdb which can be configured with certutil as described John Duffy. Unfortunately the location to the nssdb maybe different when you install application as snap. Then each application has its own database. E.g. for Chromium Snap the path will be $HOME/snap/chromium/current/.pki/nssdb, for Postman Snap the will be $HOME/snap/postman/current/.pki/nssdb and so on.
Therefor I have created a script which generates the cert, trusts it for Postman Snap, Chmromium Snap, current user nssdb and on system level. It also imports the script into the .NET SDK so it will be used by ASP.NET Core without changing the configuration. You can find more informations about the script in my blog post https://blog.wille-zone.de/post/aspnetcore-devcert-for-ubuntu
In adition to crisvdb answer, I've several information to add and is the continuation of the walktrough. I don't comment because is pretty complex comment this, but before this answer take a look to crisvdb answer first and then return to continue.
Take the "in detail" crisdb answer.
You can make your cert in any folder, can be or can't be in the same folder of the app.
Take openssl verify -CAfile localhost.crt localhost.crt as not optional step, mandatory. It will help.
Do not recompile or touch the code meanwhile you are doing this, in order to get first scenario clean.
If you run sudo update-ca-certificates that will answer you in wich folder the certified should be copied.
In some distributions, as Raspbian for Raspberry Pi, CA certificates are located in /etc/ssl/certs as well as /usr/share/ca-certificates/ and in some cases /usr/local/share/certificates.
Do not copy the cert manually to trusted certs, run sudo update-ca-certificates after you copy the cert in the right folder. If it doesn't work (doesn't update or add any certificate) copy it to every folder possible.
If you use a password while making the certificate, you should use it in the appsettings.json
If you get this error:
Interop+Crypto+OpenSslCryptographicException: error:2006D002:BIO
routines:BIO_new_file:system lib
Take in consideration that error means "access denied". It can be because you don't have permissions or related.
7b) Could be also that the file is not found, I use the entire path in the config:
"Path": "/home/user/www/myfolder1/myapp/localhost.pfx",
After that, and if everything works, you could see a 500 error if you are using Apache or Apache2.
If you get the following error in the apache logs of the site:
[ssl:error] [remote ::1:yourport] AH01961: SSL Proxy requested for
yoursite.com:443 but not enabled [Hint: SSLProxyEngine] [proxy:error]
AH00961: HTTPS: failed to enable ssl support for [::1]:yourport
(localhost)
you must set in the VirtualHost the following configuration after SSLEngine On and before your ProxyPass
SSLProxyEngine on
After that, and if everything works, you could see a 500 error if you are using Apache or Apache2.
If you get the following error in the apache logs of the site:
[proxy:error] [client x.x.x.x:port] AH00898: Error during SSL
Handshake with remote server returned by /
[proxy_http:error] [client x.x.x.x:port] AH01097: pass request body failed to [::1]:port
(localhost) from x.x.x.x()
you must set in the VirtualHost the following configuration after SSLProxyEngine on and before your ProxyPass
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
UPDATE
If you are renovating this, and using the same names, take in consideration that you should remove your pem file from etc/ssl/certs
UPDATE 2
If it returns:
Unhandled exception. Interop+Crypto+OpenSslCryptographicException: error:2006D002:BIO routines:BIO_new_file:system lib
Check that your pfx file is on 755 permissions.
If appsettings.json seems to be don't load (on port 5000 by default or SQL or any configuration doesn't load or can't be read), take in consideration that the dotnet must be executed on the same directory where is appsettings.json
Looks like this is a known issue with dotnet global tools and that specific command is only available for MacOS and Windows. See this issue on github: Issue 6066.
It seems like there may be a work around for Linux users based on this SO post: ASP.Net Core application service only listening to Port 5000 on Ubuntu.
For Chrome:
Click "Not Secure" in address bar.
Click Certificate.
Click Details.
Click Export.
Run: certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n {FILE_NAME} -i {FILE_NAME}
Restart Chrome.
It looks like the following could help to trust the dotnet dev certs:
https://blog.wille-zone.de/post/aspnetcore-devcert-for-ubuntu/
Then you will see also in the browser that certificate is OK and valid for the next yeat.
Give it a try...
Good luck!

Categories

Resources