dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.37k stars 9.99k forks source link

`dotnet dev-certs https` no longer creates a folder if one does not exist #58330

Open Gregory-Ledray opened 1 week ago

Gregory-Ledray commented 1 week ago

Describe the Bug

dotnet dev-certs https no longer creates a folder if one does not exist

Steps to Reproduce

Previously, running the following code worked:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build

RUN dotnet dev-certs https -v -ep /aspnet/https/aspnetapp.pfx -p somepassword

Now, it produces an error:

2.418 [26] An error has occurred while exporting the certificate: System.InvalidOperationException: The directory '/aspnet/https' does not exist.  Choose permissions carefully when creating it.
2.418    at Microsoft.AspNetCore.Certificates.Generation.CertificateManager.EnsureAspNetCoreHttpsDevelopmentCertificate(DateTimeOffset notBefore, DateTimeOffset notAfter, String path, Boolean trust, Boolean includePrivateKey, String password, CertificateKeyExportFormat keyExportFormat, Boolean isInteractive).
2.419 There was an error exporting the HTTPS developer certificate to a file.

Workaround - this works:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build

RUN mkdir -p /aspnet/https 

RUN dotnet dev-certs https -v -ep /aspnet/https/aspnetapp.pfx -p somepassword

Other Information

Deployment at Oct 8, 2024 10:12 AM (UTC-5:00) worked Deployment at Oct 9, 2024 11:21 AM (UTC-5:00) failed

Working output

1227 | Step 5/15 : RUN dotnet dev-certs https -ep /aspnet/https/aspnetapp.pfx -p somepassword
1228 | ---> Running in 040e6bd771d1
1229 | The HTTPS developer certificate was generated successfully.
1230 | Removing intermediate container 040e6bd771d1
1231 | ---> d021e0e54e7b

Failed output

Step 5/15 : RUN dotnet dev-certs https -ep /aspnet/https/aspnetapp.pfx -p somepassword
 ---> Running in 83d22d459576
There was an error exporting the HTTPS developer certificate to a file.
The command '/bin/sh -c dotnet dev-certs https -ep /aspnet/https/aspnetapp.pfx -p somepassword' returned a non-zero code: 3

Output of docker version

N/A happened on both Windows Docker Desktop & in Ubuntu CI build

Output of docker info

N/A happened on both Windows Docker Desktop & in Ubuntu CI build

dotnet-issue-labeler[bot] commented 1 week ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

dotnet-issue-labeler[bot] commented 1 week ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

MichaelSimons commented 1 week ago

dev-certs is a bundled global tool that comes into dotnet/installer. dev-certs comes from the aspnetcore repo so I am not sure the sdk repo is the best place for this issue...moving.

martincostello commented 1 week ago

Looks like #57108 changed this area

martincostello commented 1 week ago

/cc @amcasey

sironjuh commented 1 week ago

Just commenting on this, that our builds are now failing with this exact same error on GitHub Actions.

amcasey commented 1 week ago

That was an intentional change, made to improve security. The reasoning was that, if the tool created a directory, it would have to choose file access permissions on the user's behalf and that maximally conservative settings would break some apps. We decided instead to delegate that decision back to the user.

I'm sorry that you spent a bunch of time debugging this. My personal recommendation is to always pass --verbose to dev-certs - the behavior is hard to reason about otherwise.

amcasey commented 1 week ago

If this is common enough and we maintain our position on directory creation, we may want to have special output in this case that doesn't require --verbose.

tibble49 commented 1 week ago

@amcasey is there a suggested method/workaround we should use moving forward? is OP's work around the most ideal?

amcasey commented 1 week ago

Yes, the new expected flow is mkdir (optionally with chmod) then dev-certs.

amcasey commented 6 days ago

@tibble49, @sironjuh, @cgdallas, @Gregory-Ledray Can you help me understand how we can make the error experience more helpful? Putting aside that it's annoying to have the behavior of a tool suddenly change underneath you (sorry), what was it about the experience that made it unclear how to recover (i.e. by adding an explicit mkdir)? Did you see the verbose output and find it unclear or did you not see that output at all and just hit the generic "export failed" message?

Gregory-Ledray commented 6 days ago

I don't think it was unclear. It looks like it took me between 6 and 22 minutes to fix the problem. The error 2.418 [26] An error has occurred while exporting the certificate: System.InvalidOperationException: The directory '/aspnet/https' does not exist. Choose permissions carefully when creating it. is very specific and provides enough information to code a fix for the issue without using -v.

I opened an Issue because this is a change in behavior I didn't expect, so I assumed it was a bug.

cgdallas commented 6 days ago

In our case, we were using an out-of-the-box aspnet SPA template via dotnet new react that was trying to generate a developer certificate during the build process and the Node build step is what was failing. However, the error from Node had nothing regarding a missing directory or anything on that front, just that it couldn't create a certificate:

#21 33.69   There was an error exporting the HTTPS developer certificate to a file.
#21 33.72   failed to load config from /src/src/apps/Project.Client/vite.config.ts
#21 33.72   error during build:
#21 33.72 EXEC : error : Could not create certificate. [/src/src/apps/Project.Client/Project.Client.esproj]
#21 33.72       at file:///src/src/apps/Project.Client/vite.config.ts.timestamp-1729011205871-e11e525c33175.mjs:39:11
#21 33.72       at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
#21 33.72       at async ModuleLoader.import (node:internal/modules/esm/loader:337:24)
#21 33.72       at async loadConfigFromBundledFile (file:///src/src/apps/Project.Client/node_modules/vite/dist/node/chunks/dep-9A4-l-43.js:68383:21)
#21 33.72       at async loadConfigFromFile (file:///src/src/apps/Project.Client/node_modules/vite/dist/node/chunks/dep-9A4-l-43.js:68240:28)
#21 33.72       at async resolveConfig (file:///src/src/apps/Project.Client/node_modules/vite/dist/node/chunks/dep-9A4-l-43.js:67841:28)
#21 33.72       at async build (file:///src/src/apps/Project.Client/node_modules/vite/dist/node/chunks/dep-9A4-l-43.js:67013:20)
#21 33.72       at async CAC.<anonymous> (file:///src/src/apps/Project.Client/node_modules/vite/dist/node/cli.js:845:9)
#21 33.74 /root/.nuget/packages/microsoft.visualstudio.javascript.sdk/0.5.126-alpha/Sdk/Sdk.targets(230,5): error MSB3073: The command "npm run build" exited with code 1. [/src/src/apps/Project.Client/Project.Client.esproj]

So I don't know how the dotnet tooling would have been able to surface something since the Node process is the one that ran into the issue. Had we seen an error similar to what Gregory mentioned above, that would have been way more clear as to what happened though - I'm just not sure its feasible.

amcasey commented 6 days ago

I opened an Issue because this is a change in behavior I didn't expect, so I assumed it was a bug.

Totally fair point and we appreciate it. 😄 In this case, it happens to have been expected, but keep filing those bugs.

amcasey commented 6 days ago

@cgdallas I didn't know there was a SPA template that depended on exporting the dev cert - I'll give that a shot. The template may need to be updated to do the directory creation. It's also possible we can change the error surfaced from node - I think There was an error exporting the HTTPS developer certificate to a file is verbatim from dev-certs.

amcasey commented 6 days ago

@cgdallas Can I bug you for repro steps? I did the trivial dotnet new react and dotnet run but didn't hit that error. I'm guessing you're deploying to a container somewhere in there?

cgdallas commented 6 days ago

Hey @amcasey

Correct that we encountered this issue as part of Docker container build being run by a Github Action.

FWIW, I just tried a dotnet new react command from my dev machine and it does not produce the same project structure as the solution that experienced this issue for us. Our solution is a split one - an esproj for the frontend and a csproj for the backend.

So I guess I can't say with 100% certainty how it was created since it predates me. I (incorrectly) assumed it was just a dotnet new react but maybe this was a VS template of some kind? (Or some amalgamation of various online snippets.)

And just for other references, this was the Vite issue where the possibility of my error being a dotnet issue came from:

amcasey commented 6 days ago

@cgdallas Thanks! I think that template had to change pretty regularly to stay up-to-date with react. However, I checked our docs and it looks like it may no longer be supported. Nevertheless, I got the info I needed and I've posted a PR (no promises).

cgdallas commented 6 days ago

Glad to hear it - we ended up fixing up our Vite build process to not run if it's running in the CI pipeline, there didn't seem much point in having dev-certs run for those builds anyways.

satiyeh commented 5 days ago

@amcasey did you also check out this template here? https://learn.microsoft.com/en-us/visualstudio/javascript/tutorial-asp-net-core-with-react?view=vs-2022

This template is the one that splits the project into a Project.Client and Project.Server similar to how @cgdallas described.

amcasey commented 4 days ago

Thanks! That does look more similar to what was described above. You need to enable container support to trigger cert export, which makes sense. I'm not sure yet whether the project is doing that or the VS tooling (I'm guessing the latter).

seangwright commented 2 days ago

I have an app that executes and npm build via <Exec Command="npm run build" /> in my .csproj. That npm build runs webpack and ensures the aspnet core dev certs are created on the filesystem for webpack to use so that the webpack dev server serves over https with a trusted certificate.

This dev-certs change caused my builds to start failing and the only output I saw was the message There was an error exporting the HTTPS developer certificate to a file. from MSBuild with error MSB3073.

Thankfully a search brought me here and I also disabled the dev cert creation during CI.

mderriey commented 1 day ago

Thanks for reporting, I stumbled on that issue today, and it would have taken me a while to figure out both using --verbose to get more information, and that the issue came from the fact that the containing directory doesn't exist.

amcasey commented 1 day ago

@seangwright @mderriey Thanks for the reports! The next patch should include a better error message.

amcasey commented 1 day ago

@amcasey did you also check out this template here? https://learn.microsoft.com/en-us/visualstudio/javascript/tutorial-asp-net-core-with-react?view=vs-2022

This template is the one that splits the project into a Project.Client and Project.Server similar to how @cgdallas described.

The template has already been updated and should have the appropriate mkdir in the next VS 17 patch. (vite.config.js in the client project does an export.) However, it looks like there's a second export somewhere in the VS tooling - I'm still tracking it down. It may not matter if it runs after the template code that exports to the same folder.