使用 .NET CLI 產生自我簽署憑證

建立和使用自我簽署憑證來進行開發和測試情節的方法有很多。 本文說明如何搭配 dotnet dev-certs 使用自我簽署憑證,以及 PowerShellOpenSSL 等其他選項。

之後您可以使用裝載於容器上的 ASP.NET Core 應用程式之類的範例,驗證該憑證是否確實載入。

必要條件

在此範例中,您可使用 .NET Core 3.1 或 .NET 5。

針對 dotnet dev-certs,請務必安裝適當的 .NET 版本:

此範例需要 Docker 17.06 或更新版本的 Docker 用戶端

準備範例應用程式

您必須根據想用於測試的執行階段準備範例應用程式,例如 .NET Core 3.1.NET 5

在本指南中,您會使用範例應用程式 (英文),並在適當時進行變更。

.NET Core 3.1 範例應用程式

取得範例應用程式。

git clone https://github.com/dotnet/dotnet-docker/

在本機瀏覽至存放庫,並在編輯器中開啟工作區。

注意

如果您想用 dotnet publish 參數修剪部署,則應確定已包含適當的相依性來支援 SSL 憑證。 更新 dotnet-docker\samples\aspnetapp\aspnetapp.csproj 來確保容器中包含適當的組件。 如需參考,請檢查如何於針對獨立式部署使用修剪時,更新 .csproj 檔案來支援 SSL 憑證

請確定 aspnetapp.csproj 包含適當的目標框架:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>.netcoreapp3.1</TargetFramework>
    <!--Other Properties-->
  </PropertyGroup>

</Project>

修改 Dockerfile 來確定執行階段指向 .NET Core 3.1:

# https://hub.docker.com/_/microsoft-dotnet-core
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /source

# copy csproj and restore as distinct layers
COPY *.sln .
COPY aspnetapp/*.csproj ./aspnetapp/
RUN dotnet restore

# copy everything else and build app
COPY aspnetapp/. ./aspnetapp/
WORKDIR /source/aspnetapp
RUN dotnet publish -c release -o /app --no-restore

# final stage/image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["dotnet", "aspnetapp.dll"]

確定您指向範例應用程式。

cd .\dotnet-docker\samples\aspnetapp

組建容器以在本機進行測試。

docker build -t aspnetapp:my-sample -f Dockerfile .

.NET 5 範例應用程式

針對本指南,應該檢查範例 aspnetapp 是否為 .NET 5。

檢查範例應用程式 Dockerfile 是否使用 .NET 5。

根據主機作業系統,ASP.NET 執行階段可能需要更新。 例如,在 Dockerfile 中將 mcr.microsoft.com/dotnet/aspnet:5.0-nanoservercore-2009 AS runtime 變更為 mcr.microsoft.com/dotnet/aspnet:5.0-windowsservercore-ltsc2019 AS runtime,將有助鎖定適當的 Windows 執行階段。

例如,以下有助於在 Windows 上測試憑證:

# https://hub.docker.com/_/microsoft-dotnet
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /source

# copy csproj and restore as distinct layers
COPY *.sln .
COPY aspnetapp/*.csproj ./aspnetapp/
RUN dotnet restore -r win-x64

# copy everything else and build app
COPY aspnetapp/. ./aspnetapp/
WORKDIR /source/aspnetapp
RUN dotnet publish -c release -o /app -r win-x64 --self-contained false --no-restore

# final stage/image
# Uses the 2009 release; 2004, 1909, and 1809 are other choices
FROM mcr.microsoft.com/dotnet/aspnet:5.0-windowsservercore-ltsc2019 AS runtime
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["aspnetapp"]

如果我們在 Linux 上測試憑證,您可以使用現有的 Dockerfile。

請確定 aspnetapp.csproj 包含適當的目標框架:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <!--Other Properties-->
  </PropertyGroup>

</Project>

注意

如果您想用 dotnet publish 參數修剪部署,請確定已包含適當的相依性來支援 SSL 憑證。 更新 dotnet-docker\samples\aspnetapp\aspnetapp.csproj 來確保容器中包含適當的組件。 如需參考,請檢查如何於針對獨立式部署使用修剪時,更新 .csproj 檔案來支援 SSL 憑證

確定您指向範例應用程式。

cd .\dotnet-docker\samples\aspnetapp

組建容器以在本機進行測試。

docker build -t aspnetapp:my-sample -f Dockerfile .

建立自我簽署憑證

您可以建立自我簽署憑證:

使用 dotnet dev-certs

您可以使用 dotnet dev-certs 來處理自我簽署憑證。

dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p crypticpassword
dotnet dev-certs https --trust

注意

在此情況下,憑證名稱 aspnetapp.pfx 必須符合專案組件名稱。 crypticpassword 會作為您所選密碼的替代。 如果主控台傳回「有效的 HTTPS 憑證已存在」,則存放區中已有受信任的憑證。 您可以使用 MMC 主控台匯出之。

針對憑證設定應用程式祕密:

dotnet user-secrets -p aspnetapp\aspnetapp.csproj set "Kestrel:Certificates:Development:Password" "crypticpassword"

注意

注意:密碼必須與憑證使用的密碼一致。

使用針對 HTTPS 設定的 ASP.NET Core 執行容器映像:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=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 mcr.microsoft.com/dotnet/samples:aspnetapp

應用程式啟動後,瀏覽至網頁瀏覽器中的 https://localhost:8001

清理

如果秘密和憑證未處於使用中狀態,請務必加以清除。

dotnet user-secrets remove "Kestrel:Certificates:Development:Password" -p aspnetapp\aspnetapp.csproj
dotnet dev-certs https --clean

透過 PowerShell

您可使用 PowerShell 來產生自我簽署憑證。 PKI 用戶端 可用來產生自我簽署憑證。

$cert = New-SelfSignedCertificate -DnsName @("contoso.com", "www.contoso.com") -CertStoreLocation "cert:\LocalMachine\My"

系統會產生憑證,但為了進行測試,憑證應放在憑證存放區中,以便在瀏覽器中進行測試。

$certKeyPath = "c:\certs\contoso.com.pfx"
$password = ConvertTo-SecureString 'password' -AsPlainText -Force
$cert | Export-PfxCertificate -FilePath $certKeyPath -Password $password
$rootCert = $(Import-PfxCertificate -FilePath $certKeyPath -CertStoreLocation 'Cert:\LocalMachine\Root' -Password $password)

此時,憑證應該可從 MMC 嵌入式管理單元 檢視。

您可在 Windows 子系統 Linux 版 (WSL) 中執行範例容器:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/contoso.com.pfx -v /c/certs:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp

注意

請注意,使用磁碟區掛接時,檔案路徑可根據主機以不同的方式處理。 例如,在 WSL 中,我們可以將 /c/certs 取代為 /mnt/c/certs

如果您使用稍早針對 Windows 組建的容器,則執行命令看起來會如下所示:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" -e ASPNETCORE_Kestrel__Certificates__Default__Path=c:\https\contoso.com.pfx -v c:\certs:C:\https aspnetapp:my-sample

應用程式啟動後,瀏覽至瀏覽器中的 contoso.com:8001。

確定主機項目已針對 contoso.com 更新,以便在適當的 IP 位址上應答 (例如 127.0.0.1)。 如果無法辨識憑證,請確定與容器一起載入的憑證也在主機上受到信任,且 contoso.com 具備適當的 SAN/DNS 項目。

清理

$cert | Remove-Item
Get-ChildItem $certKeyPath | Remove-Item
$rootCert | Remove-item

使用 OpenSSL

您可以使用 OpenSSL 來建立自我簽署憑證。 此範例會使用 WSL/Ubuntu 和 bash shell 搭配 OpenSSL

這麼做會產生 .crt 和 .key。

PARENT="contoso.com"
openssl req \
-x509 \
-newkey rsa:4096 \
-sha256 \
-days 365 \
-nodes \
-keyout $PARENT.key \
-out $PARENT.crt \
-subj "/CN=${PARENT}" \
-extensions v3_ca \
-extensions v3_req \
-config <( \
  echo '[req]'; \
  echo 'default_bits= 4096'; \
  echo 'distinguished_name=req'; \
  echo 'x509_extension = v3_ca'; \
  echo 'req_extensions = v3_req'; \
  echo '[v3_req]'; \
  echo 'basicConstraints = CA:FALSE'; \
  echo 'keyUsage = nonRepudiation, digitalSignature, keyEncipherment'; \
  echo 'subjectAltName = @alt_names'; \
  echo '[ alt_names ]'; \
  echo "DNS.1 = www.${PARENT}"; \
  echo "DNS.2 = ${PARENT}"; \
  echo '[ v3_ca ]'; \
  echo 'subjectKeyIdentifier=hash'; \
  echo 'authorityKeyIdentifier=keyid:always,issuer'; \
  echo 'basicConstraints = critical, CA:TRUE, pathlen:0'; \
  echo 'keyUsage = critical, cRLSign, keyCertSign'; \
  echo 'extendedKeyUsage = serverAuth, clientAuth')

openssl x509 -noout -text -in $PARENT.crt

若要取得 .pfx,請使用下列命令:

openssl pkcs12 -export -out $PARENT.pfx -inkey $PARENT.key -in $PARENT.crt

注意

.aspnetcore 3.1 範例會使用 .pfx 和密碼。 從 .net 5 執行階段開始,Kestrel 也可以使用 .crt 和 PEM 編碼的 .key 檔案。

根據主機作業系統,憑證必須受到信任。 在 Linux 主機上,'trusting' 憑證不同,且會發佈相依性。

針對本指南的內容,以下提供使用 PowerShell 的 Windows 範例:

Import-Certificate -FilePath $certKeyPath -CertStoreLocation 'Cert:\LocalMachine\Root'

針對 .NET Core 3.1,在 WSL 中執行下列命令:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/contoso.com.pfx -v /c/path/to/certs/:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp

從 .NET 5 開始,Kestrel 可以取得 .crt 和 PEM 編碼的 .key 檔案。 您可以使用下列針對 .NET 5 的命令執行範例:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/contoso.com.crt -e ASPNETCORE_Kestrel__Certificates__Default__KeyPath=/https/contoso.com.key -v /c/path/to/certs:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp

注意

請注意,在 WSL 中,磁碟區掛接路徑可能會依設定而異。

針對 Windows 中的 .NET Core 3.1,請在 Powershell 中執行下列命令:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" -e ASPNETCORE_Kestrel__Certificates__Default__Path=c:\https\contoso.com.pfx -v c:\certs:C:\https aspnetapp:my-sample

針對 Windows 中的 .NET 5,請在 PowerShell 中執行下列命令:

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_Kestrel__Certificates__Default__Path=c:\https\contoso.com.crt -e ASPNETCORE_Kestrel__Certificates__Default__KeyPath=c:\https\contoso.com.key -v c:\certs:C:\https aspnetapp:my-sample

應用程式啟動後,瀏覽至瀏覽器中的 contoso.com:8001。

確定主機項目已針對 contoso.com 更新,以便在適當的 IP 位址上應答 (例如 127.0.0.1)。 如果無法辨識憑證,請確定與容器一起載入的憑證也在主機上受到信任,且 contoso.com 具備適當的 SAN/DNS 項目。

清理

完成測試之後,請務必清除自我簽署憑證。

Get-ChildItem $certKeyPath | Remove-Item

另請參閱