How to run 'dotnet dev-certs https --trust'?
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.crtCN = localhosterror 20 at 0 depth lookup: unable to get local issuer certificateerror 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 = 2048default_keyfile = localhost.keydistinguished_name = req_distinguished_namereq_extensions = req_extx509_extensions = v3_ca[req_distinguished_name]commonName = Common Name (e.g. server FQDN or YOUR name)commonName_default = localhostcommonName_max = 64[req_ext]subjectAltName = @alt_names[v3_ca]subjectAltName = @alt_namesbasicConstraints = critical, CA:falsekeyUsage = keyCertSign, cRLSign, digitalSignature,keyEncipherment[alt_names]DNS.1 = localhostDNS.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 yieldlocalhost.crt: OK
- as it's not trusted yet using
openssl verify localhost.crt
should fail with
CN = localhosterror 18 at 0 depth lookup: self signed certificateerror 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
- copy localhost.crt to
$ 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": "" } }}
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.
- 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.
- 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
- 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:BIOroutines: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 foryoursite.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 SSLHandshake 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 noneSSLProxyCheckPeerCN offSSLProxyCheckPeerName off
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.