Skip to content

Commit f0d4a41

Browse files
Re-write ASP.NET Core HTTPS documentation (#6117)
Co-authored-by: Rick Anderson <[email protected]>
1 parent 52d3a0f commit f0d4a41

File tree

2 files changed

+58
-282
lines changed

2 files changed

+58
-282
lines changed

samples/host-aspnetcore-https.md

Lines changed: 5 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -2,97 +2,11 @@
22

33
ASP.NET Core uses [HTTPS by default](https://docs.microsoft.com/aspnet/core/security/enforcing-ssl). [HTTPS](https://en.wikipedia.org/wiki/HTTPS) relies on [certificates](https://en.wikipedia.org/wiki/Public_key_certificate) for trust, identity, and encryption.
44

5-
This document explains how to run pre-built container images with HTTPS.
5+
See [Hosting ASP.NET Core images with Docker over HTTPS](https://learn.microsoft.com/en-us/aspnet/core/security/docker-https) for [HTTPS](https://en.wikipedia.org/wiki/HTTPS) scenarios
66

7-
See [Developing ASP.NET Core Applications with Docker over HTTPS](run-aspnetcore-https-development.md) for development scenarios.
7+
## Get certificates into a container
88

9-
This sample requires [Docker 17.06](https://docs.docker.com/release-notes/docker-ce) or later of the [Docker client](https://www.docker.com/products/docker).
9+
The instructions show how to [bind-mount](https://docs.docker.com/engine/storage/bind-mounts/) certificates into containers. We recommend certificates ***NOT*** be added into the image with a `COPY` command in a Dockerfile for the following reasons:
1010

11-
## Certificates
12-
13-
You need a certificate from a [certificate authority](https://en.wikipedia.org/wiki/Certificate_authority) for [production hosting](https://blogs.msdn.microsoft.com/webdev/2017/11/29/configuring-https-in-asp-net-core-across-different-platforms/) for your domain. You may already have one. [Let's Encrypt](https://letsencrypt.org/) is a certificate authority that offers free certificates.
14-
15-
This document uses [self-signed development certificates](https://en.wikipedia.org/wiki/Self-signed_certificate) for hosting pre-built images over `localhost`. The instructions are similar to using production certificates.
16-
17-
For production certs, you do not need to use the `dotnet dev-certs` tool or store the certificates in the location used in the instructions. Any location should work, although storing certs within your site directory is an anti-pattern.
18-
19-
The instructions volume mount certificates into containers. You can add certificates into container images with a `COPY` command in a Dockerfile. Copying certificates into an image is an anti-pattern. It makes it harder to use the same image for testing with dev certificates and hosting with production certificates. There is also a significant risk of certificate disclosure if certificates are made part of container images.
20-
21-
## Running pre-built Container Images with HTTPS
22-
23-
Use the following instructions for your operating system configuration.
24-
25-
### Linux containers on Windows host
26-
27-
Generate cert and configure local machine:
28-
29-
> [!NOTE]
30-
> If you are using CMD instead of PowerShell, substitute `$env:USERPROFILE` with `%USERPROFILE%`.
31-
32-
```console
33-
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p <CREDENTIAL_PLACEHOLDER>
34-
dotnet dev-certs https --trust
35-
```
36-
37-
> [!NOTE]
38-
> `<CREDENTIAL_PLACEHOLDER>` is used as a stand-in for a password of your own choosing.
39-
40-
Run the container image with ASP.NET Core configured for HTTPS:
41-
42-
```console
43-
docker pull mcr.microsoft.com/dotnet/samples:aspnetapp
44-
docker run --rm -it -p 8001:8001 -e ASPNETCORE_HTTPS_PORTS=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="<CREDENTIAL_PLACEHOLDER>" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v $env:USERPROFILE\.aspnet\https:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp
45-
```
46-
47-
> [!NOTE]
48-
> The password must match the password used for the certificate.
49-
50-
### Linux containers on macOS or Linux host
51-
52-
Create a certificate directory with appropriate permissions:
53-
54-
```console
55-
mkdir -p -m 700 ${HOME}/.aspnet/https
56-
```
57-
58-
Generate cert and configure local machine:
59-
60-
```console
61-
dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p <CREDENTIAL_PLACEHOLDER>
62-
dotnet dev-certs https --trust
63-
```
64-
65-
> [!NOTE]
66-
> `<CREDENTIAL_PLACEHOLDER>` is used as a stand-in for a password of your own choosing.
67-
68-
Run the container image with ASP.NET Core configured for HTTPS:
69-
70-
```console
71-
docker pull mcr.microsoft.com/dotnet/samples:aspnetapp
72-
docker run --rm -it -p 8001:8001 -e ASPNETCORE_HTTPS_PORTS=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="<CREDENTIAL_PLACEHOLDER>" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v ${HOME}/.aspnet/https:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp
73-
```
74-
75-
> [!NOTE]
76-
> The password must match the password used for the certificate.
77-
78-
### Windows containers on Windows host
79-
80-
Generate cert and configure local machine:
81-
82-
```console
83-
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p <CREDENTIAL_PLACEHOLDER>
84-
dotnet dev-certs https --trust
85-
```
86-
87-
> [!NOTE]
88-
> `<CREDENTIAL_PLACEHOLDER>` is used as a stand-in for a password of your own choosing.
89-
90-
Run the container image with ASP.NET Core configured for HTTPS:
91-
92-
```console
93-
docker pull mcr.microsoft.com/dotnet/samples:aspnetapp
94-
docker run --rm -it -p 8001:8001 -e ASPNETCORE_HTTPS_PORTS=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="<CREDENTIAL_PLACEHOLDER>" -e ASPNETCORE_Kestrel__Certificates__Default__Path=\https\aspnetapp.pfx -v $env:USERPROFILE\.aspnet\https:C:\https\ --user ContainerAdministrator mcr.microsoft.com/dotnet/samples:aspnetapp
95-
```
96-
97-
> [!NOTE]
98-
> The password must match the password used for the certificate. Running as ContainerAdministrator is not recommended in production scenarios. The `--user ContainerAdministrator` flag has been added in this example since there is a potential and intermittent race condition that throws a `WindowsCryptographicException` at the container/app startup when using self-signed certificates. This is a known bug and it has been [reported here](https://github.com/dotnet/runtime/issues/70386).
11+
* It makes it harder to use the same image for testing with dev certificates and hosting with production certificates.
12+
* It increases the risk of certificate disclosure if certificates are made part of your container image.

samples/run-aspnetcore-https-development.md

Lines changed: 53 additions & 191 deletions
Original file line numberDiff line numberDiff line change
@@ -4,236 +4,98 @@ ASP.NET Core uses [HTTPS by default](https://docs.microsoft.com/aspnet/core/secu
44

55
This document demonstrates how to develop ASP.NET Core applications with HTTPS in Docker containers. It's recommended to try the [ASP.NET Core Docker Sample](README.md) first, which is simpler because the container only exposes HTTP. This more basic tutorial will help you validate that you have the sample working correctly, before adding the complication of certificates.
66

7-
See [Hosting ASP.NET Core Images with Docker over HTTPS](host-aspnetcore-https.md) for production scenarios.
7+
See [Hosting ASP.NET Core images with Docker over HTTPS](https://learn.microsoft.com/en-us/aspnet/core/security/docker-https) for production scenarios.
88

9-
The Windows examples below are written for PowerShell. CMD users will need to change the format of the environment variables in the instructions from `$env:USERPROFILE` to `%USERPROFILE%`.
9+
Windows instructions are written for PowerShell. If you are using CMD, change the format of environment variables from `${env:USERPROFILE}` to `%USERPROFILE%`.
1010

11-
This sample requires [Docker 17.06](https://docs.docker.com/release-notes/docker-ce) or later of the [Docker client](https://www.docker.com/products/docker).
11+
This example requires [Docker Desktop](https://www.docker.com/products/docker-desktop/). We recommend the latest version.
1212

13-
## Getting the sample
13+
## Getting the sample image
1414

15-
The easiest way to get the sample is by cloning the samples repository with git, using the following instructions:
15+
Pull the sample image:
1616

1717
```console
18-
git clone https://github.com/dotnet/dotnet-docker/
19-
```
20-
21-
You can also [download the repository as a zip](https://github.com/dotnet/dotnet-docker/archive/main.zip).
22-
23-
## Certificates
24-
25-
ASP.NET Core uses [self-signed development certificates](https://en.wikipedia.org/wiki/Self-signed_certificate) for development. Self-signed certificates are easy and free to create.
26-
27-
The instructions volume mount certificates into containers. You can add certificates into container images with a `COPY` command in a Dockerfile. This approach isn't recommended. It makes it harder to use the same image for testing with dev certificates and hosting with production certificates. There's also a significant risk of certificate disclosure if certificates are made part of container images.
28-
29-
## Application Secrets
30-
31-
These instructions assume that your project is configured for [application secrets](https://docs.microsoft.com/aspnet/core/security/app-secrets). The primary requirement is a [UserSecretsId](https://github.com/dotnet/dotnet-docker/blob/main/samples/aspnetapp/aspnetapp/aspnetapp.csproj#L5) element in your project file. If you're using the ASP.NET Core sample in this repo, you don't need to do anything. It's already correctly configured. If you're using your own project file, add an `UserSecretsId` element.
32-
33-
You can add the element manually or use Visual Studio to do it for you. The following image demonstrates the experience in Visual Studio.
34-
35-
![Manage user secrets in Visual Studio](https://user-images.githubusercontent.com/7681382/39641521-85d4a7b4-4f9c-11e8-9466-d1ff56db33cb.png)
36-
37-
The format of the `UserSecretsId` content doesn't matter. The sample in this repo used [Random String Generator](https://www.random.org/strings/?num=6&len=20&digits=on&unique=on&format=html&rnd=new) to produce a unique string.
38-
39-
> [!NOTE]
40-
> `User Secrets` and `Application Secrets` terms are used interchangebly.
41-
42-
## Building and Running the Sample with HTTPS
43-
44-
Use the following instructions, for your operating system configuration. The commands assume that you are in the root of the repository.
45-
46-
> [!NOTE]
47-
> The sample includes a banner to accept a cookie policy. When switching between HTTP and HTTPS, you may see the banner repeatedly. Delete the cookie for the site in `Developer Tools` in this case.
48-
49-
![Developer Tools -- Delete cookie](https://user-images.githubusercontent.com/2608468/40246148-875fee5a-5a7c-11e8-9728-7da89a491014.png)
50-
51-
Further, if you're loading SSL certificates and trimming assemblies as part of the publish, you'll also need to update the project file for the sample. See details for how you can [support SSL certificates](https://docs.microsoft.com/en-us/dotnet/core/deploying/trim-self-contained#support-for-ssl-certificates).
52-
53-
### Linux containers on Windows host
54-
55-
The following example uses PowerShell.
56-
57-
Navigate to sample:
58-
59-
```console
60-
cd samples\aspnetapp
61-
```
62-
63-
Generate cert and configure local machine:
64-
65-
```console
66-
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p <CREDENTIAL_PLACEHOLDER>
67-
dotnet dev-certs https --trust
68-
```
69-
70-
> [!NOTE]
71-
>
72-
> - The certificate name, in this case *aspnetapp*.pfx must match the project assembly name.
73-
> - `<CREDENTIAL_PLACEHOLDER>` is used as a stand-in for a password of your own choosing.
74-
> - If console returns "A valid HTTPS certificate is already present.", a trusted certificate already exists in your store. It can be exported using MMC Console.
75-
76-
Configure application secrets, for the certificate:
77-
78-
```console
79-
dotnet user-secrets init -p aspnetapp\aspnetapp.csproj
80-
dotnet user-secrets -p aspnetapp\aspnetapp.csproj set "Kestrel:Certificates:Development:Password" "<CREDENTIAL_PLACEHOLDER>"
81-
```
82-
83-
> [!NOTE]
84-
> The password must match the password used for the certificate.
85-
86-
Build a container image:
87-
88-
```console
89-
docker build --pull -t aspnetapp .
18+
docker pull mcr.microsoft.com/dotnet/samples:aspnetapp
9019
```
9120

92-
Run the container image with ASP.NET Core configured for HTTPS:
21+
Alternatively, you can build the sample image locally:
9322

9423
```console
95-
docker run --rm -it -p 8001:8001 -e ASPNETCORE_HTTPS_PORTS=8001 -e ASPNETCORE_ENVIRONMENT=Development -v $env:APPDATA\microsoft\UserSecrets\:/root/.microsoft/usersecrets -v $env:USERPROFILE\.aspnet\https:/root/.aspnet/https/ aspnetapp
24+
docker build --pull -t mcr.microsoft.com/dotnet/samples:aspnetapp 'https://github.com/dotnet/dotnet-docker.git#:samples/aspnetapp'
9625
```
9726

98-
After the application starts, navigate to `https://localhost:8001` in your web browser.
99-
100-
### Linux containers on macOS host
101-
102-
```console
103-
cd samples/aspnetapp
104-
```
27+
## Create and trust a development certificate
10528

106-
Create a certificate directory with appropriate permissions:
29+
Follow the instructions for creating a [.NET development certificate](https://learn.microsoft.com/dotnet/core/tools/dotnet-dev-certs) from [Running pre-built container images with HTTPS](https://learn.microsoft.com/aspnet/core/security/docker-https#running-pre-built-container-images-with-https).
10730

108-
```console
109-
mkdir -p -m 700 ${HOME}/.aspnet/https
110-
```
31+
## Enable HTTPS using environment variables
11132

112-
Generate cert and configure local machine:
33+
See [Hosting ASP.NET Core images with Docker over HTTPS](https://learn.microsoft.com/aspnet/core/security/docker-https). See the following section if you don't want to use environment variables to store your development
34+
certificate password.
11335

114-
```console
115-
dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p <CREDENTIAL_PLACEHOLDER>
116-
dotnet dev-certs https --trust
117-
```
36+
## Using user secrets for certificate password
11837

119-
> [!NOTE]
120-
>
121-
> - The certificate name, in this case *aspnetapp*.pfx must match the project assembly name.
122-
> - `<CREDENTIAL_PLACEHOLDER>` is used as a stand-in for a password of your own choosing.
38+
Rather than using environment variable to specify the development certificate password, use [.NET user secrets](https://learn.microsoft.com/aspnet/core/security/app-secrets) to store the password.
12339

124-
Configure application secrets, for the certificate:
40+
Initializing user-secrets for the first time on a project modifies the project file, so you will need a local copy of the `aspnetapp` sample. Clone this repo or [download the repository as a zip](https://github.com/dotnet/dotnet-docker/archive/main.zip).
12541

12642
```console
127-
dotnet user-secrets init -p aspnetapp/aspnetapp.csproj
128-
dotnet user-secrets -p aspnetapp/aspnetapp.csproj set "Kestrel:Certificates:Development:Password" "<CREDENTIAL_PLACEHOLDER>"
129-
```
130-
131-
> [!NOTE]
132-
> The password must match the password used for the certificate.
133-
134-
Build a container image:
135-
136-
```console
137-
docker build --pull -t aspnetapp .
138-
```
139-
140-
Run the container image with ASP.NET Core configured for HTTPS:
141-
142-
```console
143-
docker run --rm -it -p 8001:8001 -e ASPNETCORE_HTTPS_PORTS=8001 -e ASPNETCORE_ENVIRONMENT=Development -v ${HOME}/.microsoft/usersecrets/:/root/.microsoft/usersecrets -v ${HOME}/.aspnet/https:/root/.aspnet/https/ aspnetapp
43+
git clone https://github.com/dotnet/dotnet-docker/
14444
```
14545

146-
After the application starts, navigate to `https://localhost:8001` in your web browser.
147-
148-
### Linux containers on Linux host
46+
Initialize user secrets for your app, and set the certificate password:
14947

15048
```console
15149
cd samples/aspnetapp
152-
```
153-
154-
Create a certificate directory with appropriate permissions:
155-
156-
```console
157-
mkdir -p -m 700 ${HOME}/.aspnet/https
158-
```
159-
160-
Generate cert and configure local machine:
161-
162-
```console
163-
dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p <CREDENTIAL_PLACEHOLDER>
164-
```
165-
166-
> [!NOTE]
167-
>
168-
> - The certificate name, in this case *aspnetapp*.pfx must match the project assembly name.
169-
> - `<CREDENTIAL_PLACEHOLDER>` is used as a stand-in for a password of your own choosing.
170-
171-
Configure application secrets, for the certificate:
172-
173-
```console
17450
dotnet user-secrets init -p aspnetapp/aspnetapp.csproj
175-
dotnet user-secrets -p aspnetapp/aspnetapp.csproj set "Kestrel:Certificates:Development:Password" "<CREDENTIAL_PLACEHOLDER>"
51+
dotnet user-secrets -p aspnetapp/aspnetapp.csproj set "Kestrel:Certificates:Default:Password" $CREDENTIAL_PLACEHOLDER
17652
```
17753

178-
Build a container image:
54+
Since initializing user-secrets modified the project file, re-build the sample image:
17955

180-
```console
56+
```pwsh
18157
docker build --pull -t aspnetapp .
18258
```
18359

184-
Run the container image with ASP.NET Core configured for HTTPS:
185-
186-
```console
187-
docker run --rm -it -p 8001:8001 -e ASPNETCORE_HTTPS_PORTS=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Development__Password="<CREDENTIAL_PLACEHOLDER>" -v ${HOME}/.microsoft/usersecrets/:/root/.microsoft/usersecrets -v ${HOME}/.aspnet/https:/root/.aspnet/https/ aspnetapp
188-
```
189-
190-
After the application starts, navigate to `https://localhost:8001` in your web browser.
191-
192-
### Windows containers on Windows host
60+
In Linux containers, .NET looks under the `~/.microsoft/usersecrets/` directory for user secrets data. Bind-mount your host machine's user secrets directory to the container's filesystem. If you are running your container as the `root` user, replace `/home/app/` with the `root` user's home directory, `/root/`.
19361

194-
The following example uses PowerShell.
62+
**Linux containers on Windows:**
19563

196-
Navigate to sample:
197-
198-
```console
199-
cd samples\aspnetapp
64+
```pwsh
65+
docker run --rm -it `
66+
-p 8001:8001 `
67+
-e ASPNETCORE_HTTPS_PORTS=8001 `
68+
-e ASPNETCORE_ENVIRONMENT=Development `
69+
-v ${env:APPDATA}/microsoft/UserSecrets/:/home/app/.microsoft/usersecrets `
70+
-v ${env:USERPROFILE}/.aspnet/https/:/https/ `
71+
-e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx `
72+
aspnetapp
20073
```
20174

202-
Generate cert and configure local machine:
75+
**Linux containers on macOS or Linux:**
20376

204-
```console
205-
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p <CREDENTIAL_PLACEHOLDER>
206-
dotnet dev-certs https --trust
77+
```bash
78+
docker run --rm -it \
79+
-p 8001:8001 \
80+
-e ASPNETCORE_HTTPS_PORTS=8001 \
81+
-e ASPNETCORE_ENVIRONMENT=Development \
82+
-v ${HOME}/.microsoft/usersecrets/:/home/app/.microsoft/usersecrets \
83+
-v ${HOME}/.aspnet/https/:/https/ \
84+
-e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx \
85+
aspnetapp
20786
```
20887

209-
> [!NOTE]
210-
>
211-
> - The certificate name, in this case *aspnetapp*.pfx must match the project assembly name.
212-
> - `<CREDENTIAL_PLACEHOLDER>` is used as a stand-in for a password of your own choosing.
213-
> - If console returns "A valid HTTPS certificate is already present.", a trusted certificate already exists in your store. It can be exported using MMC Console.
88+
**Windows containers on Windows:**
21489

215-
Configure application secrets, for the certificate:
216-
217-
```console
218-
dotnet user-secrets init -p aspnetapp/aspnetapp.csproj
219-
dotnet user-secrets -p aspnetapp\aspnetapp.csproj set "Kestrel:Certificates:Development:Password" "<CREDENTIAL_PLACEHOLDER>"
90+
```pwsh
91+
docker run --rm -it `
92+
-p 8001:8001 `
93+
-e ASPNETCORE_HTTPS_PORTS=8001 `
94+
-e ASPNETCORE_ENVIRONMENT=Development `
95+
-v ${env:APPDATA}\microsoft\UserSecrets\:C:\Users\ContainerUser\AppData\Roaming\microsoft\UserSecrets `
96+
-v ${env:USERPROFILE}\.aspnet\https:C:\https `
97+
aspnetapp
22098
```
22199

222-
> [!NOTE]
223-
> The password must match the password used for the certificate.
224-
225-
Build a container image:
226-
227-
```console
228-
docker build --pull -t aspnetapp .
229-
```
230-
231-
Run the container image with ASP.NET Core configured for HTTPS.
232-
233-
```console
234-
docker run --rm -it -p 8001:8001 -e ASPNETCORE_HTTPS_PORTS=8001 -e ASPNETCORE_ENVIRONMENT=Development -v $env:APPDATA\microsoft\UserSecrets\:C:\Users\ContainerUser\AppData\Roaming\microsoft\UserSecrets -v $env:USERPROFILE\.aspnet\https:C:\Users\ContainerUser\AppData\Roaming\ASP.NET\Https aspnetapp
235-
```
236-
237-
After the application starts, navigate to `https://localhost:8001` in your web browser.
238-
239-
> In the case of using https, be sure to check the certificate you're using is trusted on the host. You can start with navigating to `https://localhost:8001` in the browser. If you're looking to test https with a domain name (e.g. `https://contoso.com:8001`), the certificate would also need the appropiate Subject Alternative Name included, and the DNS settings on the host would need to be updated. In the case of using the generated dev certificate, the trusted certificate will be issued from localhost and will not have the SAN added.
100+
After the application starts, navigate to `https://localhost:8001` in your web
101+
browser.

0 commit comments

Comments
 (0)