76

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?

Hasta Tamang
  • 2,205
  • 1
  • 18
  • 17
Kob4
  • 861
  • 1
  • 6
  • 4
  • That link you've provided to the reading tutorial seems to lead to a page in Japanese. Surely a great read but the language barrier might be an issue. – Konrad Viltersten Jul 04 '21 at 09:35

5 Answers5

125

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:

$ 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)

  1. manually generate self-signed cert
  2. trust this cert
  3. force your application to use this cert

In detail:

  1. 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
  1. 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
  1. force your application to use this cert

    • update your appsettings.json with the following settings:
"Kestrel": {
  "Certificates": {
    "Default": {
      "Path": "localhost.pfx",
      "Password": ""
    }
  }
}
István
  • 5,057
  • 10
  • 38
  • 67
chrisvdb
  • 2,080
  • 2
  • 20
  • 28
  • 3
    Incredibly helpful, thank you. The only caveat for me was that this does not work with openssl 1.0.1, I had to update to 1.1.1 to succeed. Also worth mentioning this issue: https://github.com/dotnet/aspnetcore/issues/7246 which talks through this in detail. – Michael Armitage Jan 16 '20 at 10:49
  • 2
    Thanks, wasn't aware of that thread... would have saved me a lot of time! – chrisvdb Jan 17 '20 at 08:14
  • 1
    Thanks. As I am using Ubuntu on WSL I also installed the .pfx file on Windows Certificate Store: "Trusted Root Certification Authorities". – Juan Rojas May 04 '20 at 04:03
  • Thanks for this! This post solved my issue. You may want to add one more step for those accessing through the browser, that you need to export the certificate (localhost) from the browser and import it using the certificate manager into the Trusted Root Certificate Authorities/Certificates folder in order for the browser to trust the localhost certficate and not display the (site note secure) warning. – mike gold May 31 '20 at 00:12
  • For those who have signed certificates from Comodo Digicert Verisign etc or self signed, point 3 solves all to add path to PFX in appsettings.json. To create PFX : openssl pkcs12 -export -out host.pfx -inkey host.key -in host.crt – Mihai Jul 16 '20 at 14:35
  • 3
    Following the steps i'm getting: ▶ ls -la /etc/ssl/certs/localhost.pem | grep localhost lrwxrwxrwx 1 root root 46 Oct 18 04:19 /etc/ssl/certs/localhost.pem -> /usr/local/share/ca-certificates/localhost.crt Repositories/dotnet/TodoApi ▶ openssl verify localhost.crt CN = ubuntu-machine error 18 at 0 depth lookup: self signed certificate error localhost.crt: – Snewedon Oct 18 '20 at 03:21
  • 1
    @Snewedon sorry to hear it didn't work. I followed exactly the same steps and it did work for me. Hard to debug based on the limited information available. Maybe different openssl version? Needs v1.1.1 or higher. – chrisvdb Oct 18 '20 at 16:00
  • Your answer solve my problem but I had several issues "after it". I add an answer that is the continuation to yours for people who run into Apache2. In any case I don't want to steal your reputation, just complete the answer. Thanks a lot for your explanation and time, you really help me!!! You deserve more votes. – Leandro Bardelli Dec 29 '20 at 04:36
  • 1
    @Snewedon It seems that the error is caused by the same common name: https://stackoverflow.com/a/19738223/3184351. From [this guide on Gist](https://gist.github.com/kyledrake/d7457a46a03d7408da31), there're two sets of key (root key and domain key). It seems that `localhost.pem` corresponds to the domain key. – GNUSupporter 8964民主女神 地下教會 Feb 18 '21 at 10:44
  • 1
    @Snewedon I had the same error and answer that `GNUSupporter 8964[chinese...]` recommended - it helped me! The problem was with same common name. – alexkovelsky Mar 30 '21 at 21:12
  • * generate cert using `openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt -config localhost.conf` asks an undesired question. Namely. `Common Name (e.g. server FQDN or YOUR name) [localhost]:^C`. To avoid this, I appended the following parameter with value: `-subj '/CN=localhost'`. I found it here in answer: https://stackoverflow.com/questions/10175812/how-to-generate-a-self-signed-ssl-certificate-using-openssl/10176685#10176685. Now I am considering to edit the answer by including this parameter for copy-pasting instead of thinking where to fing it. – moudrick Jun 14 '21 at 15:21
  • If you are renovating the cert, and using the same names, take in consideration that you should remove your pem file from etc/ssl/certs - I upgrade this answer with my answer, but read this one before mine. – Leandro Bardelli Dec 29 '21 at 02:05
  • Running `dotnet dev-certs https -v` returns: A valid HTTPS certificate is already present. – variable Jan 14 '22 at 13:04
  • 1
    if you run `sudo update-ca-certificates` as initial of step 2, you will get the correct route to copy the cert. Check my complementary answer to this one. – Leandro Bardelli May 04 '22 at 12:31
  • I get error when starting asp.net & I'm supplying full path & password for .pfx file "Crypto+OpenSslCryptographicException: error:10000080:BIO routines::no such file" – zezba9000 May 17 '22 at 00:00
  • Make sure you give full path to .pfx file. Don't use "~/..." use "/home/..." instead – zezba9000 May 17 '22 at 00:06
  • Fails generating the cert: 'Common Name (e.g. server FQDN or YOUR name) [localhost]:problems making Certificate Request'. OpenSSL version 1.1.1n – Neurion Jan 05 '23 at 11:03
  • If you have archlinux then follow this https://unix.stackexchange.com/questions/525601/update-ca-trust-extract-not-adding-certificates-to-ca-bundle and this https://man.archlinux.org/man/update-ca-trust.8 – Dragno Jan 09 '23 at 19:50
8

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

Boris Wilhelms
  • 621
  • 6
  • 9
  • this is the answer!!! Great tool, spent a whole afternoon trying to make a simple blazor app work without success. After all that time I came across this super script, wonderful, worked like a charm and only took 10 seconds. – Rui Lima May 12 '21 at 18:31
  • 1
    The script worked fine for me, running .NET 5.0 on Linux Mint 20.2. Thanks. – Jeff Dege Oct 03 '21 at 22:15
5

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.

  1. You can make your cert in any folder, can be or can't be in the same folder of the app.
  2. Take openssl verify -CAfile localhost.crt localhost.crt as not optional step, mandatory. It will help.
  3. Do not recompile or touch the code meanwhile you are doing this, in order to get first scenario clean.
  4. If you run sudo update-ca-certificates that will answer you in wich folder the certified should be copied.
  5. 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.
  6. 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.
  7. If you use a password while making the certificate, you should use it in the appsettings.json
  8. 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",
  1. 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
  1. 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

Leandro Bardelli
  • 10,561
  • 15
  • 79
  • 116
4

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.

A-A-ron
  • 529
  • 1
  • 5
  • 14
4

For Chrome:

  1. Click "Not Secure" in address bar.
  2. Click Certificate.
  3. Click Details.
  4. Click Export.

Run: certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n {FILE_NAME} -i {FILE_NAME}

Restart Chrome.

John Duffy
  • 164
  • 4
  • 10