aspnetcore: don't expose a localhost https endpoint when there is no developer certificate

By default kestrel exposes an HTTPS endpoint for localhost using a development certificate.

On Linux, the dotnet dev-certs https --trust doesn’t work well leading to a bricked development experience.

It would be nice if there was a global way to opt-out of the HTTPS localhost bind.

One option may be to not bind localhost HTTPS when there is no development certificate.

I think the reason for having the HTTPS endpoint is to be secure by default, though not having it on localhost does not make things insecure by default.

@Tratcher @halter73 @jkotalik what do you think?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 37 (37 by maintainers)

Most upvoted comments

@tmds I’m glad that we sorted this out

The openssl issue that was fixed is this one: https://github.com/openssl/openssl/issues/1418

WRT to Firefox the problem with not setting it up at the system level is that it might impact automation tools. We could do it at the user profile level, however it will have to be “smarter” than looking at the *.default-release. There is a profiles.ini file or something like that and we would need to find the default profile in there.

Include the username in the certificate name to avoid conflict with other users at the system location.

This is a good idea, though not sure how many devs use the same machine with multiple users for development.

As far as I can tell, the “C,” overwrites the “P,” so only “C,” is needed.

This might be the case, we would need to test this out, since I read something about a bug requiring this when I did this the first time.

With regards to supporting this on .NET Core I think we would be open to it, however I want to set expectations here, since it’s not just about making --trust work. We would need to put in the work to make sure that --trust, --clean and --check options work within the expectations as well as do all the necessary work to ensure that we can maintain support and prevent regressions moving forward without this being a constant source of issues.

In addition to that, we wouldn’t support --trust on a single distro. Our support matrix for 6.0 looks as follows:

Alpine Linux 3.13+ x64, Arm64, Arm32 Alpine
CentOS 7+ x64 CentOS
Debian 10+ x64, Arm64, Arm32 Debian
Fedora 32+ x64 Fedora
openSUSE 15+ x64 OpenSUSE
Red Hat Enterprise Linux 7+ x64, Arm64 Red Hat
SUSE Enterprise Linux (SLES) 12 SP2+ x64 SUSE
Ubuntu 16.04, 18.04, 20.04+ x64, Arm64, Arm32 Ubuntu

If we add support for this, we would need to try and cover as many distros as possible.

We would need to make a list of the following per distro:

  • Steps to validate the tool works manually from a clean install
    • Steps to install chrome, edge (Firefox comes by default in all?)
    • Steps to install dotnet
    • Steps to install all prerequisites
      • openssl (a recent enough version if not present)
      • libnss3-tools (if edge/chrome are installed?).
    • A reference app we can use for validation that exercises browser trust and dotnet to dotnet trust. Something like this
    • A list of commands to run and facts to validate after each command.
      • We do have a list of things we validate on Mac and Windows and we would use that same list.
      • We check that you can run the app from a new install, that cleaning the certs removes all the state and trust.
      • That commands are idempotent and don’t fail if you repeat them.
      • Different sequences of --trust, --clean, etc.
  • We would need to update --clean to make sure we undo everything we do on a per-distro basis.
    • Remove the cert from the places we copied the cert.
    • Delete the cert from the chrome/edge db.
  • We would need to update --check to support determining if the certificate is already trusted
    • We can check dotnet-to-dotnet trust loading the cert and validating it or potentially looking into the Trusted Roots Store for it.
    • We will need to figure out how to validate it is trusted in Firefox and Chrome/Edge via nss-tools or other means.
  • We would need to include checks for installed tools on a per-distro basis:
    • Check openssl is recent enough.
    • Check if chrome and edge are installed.
    • Check if certutil is available.
  • We would need to make sure we don’t override things that a user has explicitly set, like a custom policy using policies.json in Firefox or an existing certificate in any of the locations on disk where we need them to be.

Implementation wise, we could potentially divide this into 3 areas:

  • Firefox trust
    • This seems to vary across distros.
  • Chrome/Edge trust
    • This seems to be the same across distros
  • dotnet-to-dotnet trust
    • This varies across distros.

I would avoid us having distro specific code where possible. It would be neat if we could embed distro/version specific scripts/metadata to drive the process so that there’s only one path available for Linux that is largely driven by distro specific resources. That way, when something changes we just need to update a resource for a specific distro/version which greatly limits the chances of regressing other distros (and creates an implicit boundary of the scenarios to revalidate).

All this is to say that this is a LOT of work and nothing that is planned for 6.0.

We would be open to getting this done in 6.0 provided that this goes through the right feature design/process if someone wants to tackle it, however its not something we will ourselves tackle.

The first thing we would require would be manual steps to setup and validate HTTPS on all distros and once we have that we could look at supporting it in dotnet dev-certs.

There is a big chance that this will bring in tons of new issues and maintenance work to the repo, and if we can’t ensure that we have a low cost story for validating that it works on each specifically supported distro and that we can make changes easily, we won’t want to sign up for owning this.

@tmds If this is something you are interested in contributing we would be open to accept it provided is based on the expectations set above. Let us know if this is the case and we can open a new issue for it.

Given the size of it, there might be some things that could be “parallelized” or split between folks to enable other people from the community to contribute. I wouldn’t expect you to tackle on all this work, since as you can tell this is a really large effort in terms of cost and maintenance for us.