Создайте правильные сертификаты для докера nginx: Angular и .NET Core API - PullRequest
0 голосов
/ 25 сентября 2019

У меня проблема с HTTPS-связью между Docker nginx: Angular и .NET Core API.

Я создал цепные самоподписанные сертификаты для двух API и угловой страницы, используя:

    mkdir certs

    openssl genrsa -des3 -out certs/RootCA.key 4096
    openssl req -x509 -new -nodes -key certs/RootCA.key -sha256 -days 1024 -out certs/RootCA.crt -subj "/C=PL/ST=WR/O=Solteq/CN=ROOT Cert"

    openssl genrsa -out certs/angular.key 2048
    openssl genrsa -out certs/api.key 2048
    openssl genrsa -out certs/identityserver.key 2048

    openssl req -new -sha256 -key certs/angular.key -subj "/C=PL/ST=WR/O=Solteq/CN=angular" -out certs/angular.csr
    openssl req -new -sha256 -key certs/api.key -subj "/C=PL/ST=WR/O=Solteq/CN=api" -out certs/api.csr
    openssl req -new -sha256 -key certs/identityserver.key -subj "/C=PL/ST=WR/O=Solteq/CN=identityserver" -out certs/identityserver.csr

    openssl x509 -req -in certs/angular.csr -CA certs/RootCA.crt -CAkey certs/RootCA.key -CAcreateserial -out certs/angular.crt -days 1500 -sha256
    openssl x509 -req -in certs/api.csr -CA certs/RootCA.crt -CAkey certs/RootCA.key -CAcreateserial -out certs/api.crt -days 1500 -sha256
    openssl x509 -req -in certs/identityserver.csr -CA certs/RootCA.crt -CAkey certs/RootCA.key -CAcreateserial -out certs/identityserver.crt -days 1500 -sha256

    openssl pkcs12 -export -out certs/RootCA.pfx -inkey certs/RootCA.key -in certs/RootCA.crt
    openssl pkcs12 -export -out certs/angular.pfx -inkey certs/angular.key -in certs/angular.crt
    openssl pkcs12 -export -out certs/api.pfx -inkey certs/api.key -in certs/api.crt
    openssl pkcs12 -export -out certs/identityserver.pfx -inkey certs/identityserver.key -in certs/identityserver.crt

Первая часть - успешная, это означает, что я могу подключить два API через HTTPS, они настроеныследующим образом:

API:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["src/Demo.Api/Demo.Api.csproj", "src/Demo.Api/"]
COPY ["src/Demo.Context/Demo.Context.csproj", "src/Demo.Context/"]
COPY ["src/Demo.Domain/Demo.Domain.csproj", "src/Demo.Domain/"]
RUN dotnet restore "src/Demo.Api/Demo.Api.csproj"
COPY . .
WORKDIR "/src/src/Demo.Api"
RUN dotnet build "Demo.Api.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "Demo.Api.csproj" -c Release -o /app

FROM base AS final

WORKDIR /app
COPY --from=publish /app .

COPY certs/api.pfx /root/.dotnet/https
COPY certs/RootCA.crt /usr/local/share/ca-certificates/RootCA.crt
RUN chmod 644 /usr/local/share/ca-certificates/RootCA.crt
RUN update-ca-certificates

ENTRYPOINT ["dotnet", "Demo.Api.dll"]

Identity Server:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["src/Demo.IdentityServer/Demo.IdentityServer.csproj", "src/Demo.IdentityServer/"]
RUN dotnet restore "src/Demo.IdentityServer/Demo.IdentityServer.csproj"
COPY . .
WORKDIR "/src/src/Demo.IdentityServer"
RUN dotnet build "Demo.IdentityServer.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "Demo.IdentityServer.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .

COPY certs/identityserver.pfx /root/.dotnet/https

COPY certs/RootCA.crt /usr/local/share/ca-certificates/RootCA.crt
RUN chmod 644 /usr/local/share/ca-certificates/RootCA.crt
RUN update-ca-certificates

ENTRYPOINT ["dotnet", "Demo.IdentityServer.dll"]

И последняя часть, которая не будет работать, - это Angular APP, который настроен следующим образом: Dockerfile:

### STAGE 1: Build ###

# We label our stage as ‘builder’
FROM node:12-alpine as build

COPY src/Demo.angular/ClientApp/package.json src/Demo.angular/ClientApp/package-lock.json ./

## Storing node modules on a separate layer will prevent unnecessary npm installs at each build

RUN npm ci && mkdir /ng-app && mv ./node_modules ./ng-app

WORKDIR /ng-app

COPY src/Demo.angular/ClientApp/ .

## Build the angular app in production mode and store the artifacts in dist folder

WORKDIR /ng-app

RUN npm run build-locale-dev


### STAGE 2: Setup ###

FROM nginx:1.17.3-alpine as runtime

# copy artifact build from the 'build environment'
COPY --from=build /ng-app/dist /etc/nginx/html/

# expose port 443
EXPOSE 443
COPY src/Demo.angular/ClientApp/nginx.conf /etc/nginx/nginx.conf
COPY certs/angular.crt /etc/ssl/certs/
COPY certs/angular.key /etc/ssl/keys/

COPY certs/RootCA.crt /usr/local/share/ca-certificates/RootCA.crt
RUN chmod 644 /usr/local/share/ca-certificates/RootCA.crt

# run nginx
CMD ["nginx", "-g", "daemon off;"]

nginx.conf:

events {
}
http {
  server {
    listen              443 ssl;
    server_name         bvl;
    ssl_certificate     /etc/ssl/certs/angular.crt;
    ssl_certificate_key /etc/ssl/keys/angular.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;

    index index.html;

    location /en {
      try_files $uri $uri/ /en/index.html =404;
    }
    location /de {
      try_files $uri $uri/ /de/index.html =404;
    }
    location = / {
      return 301 https://$http_host/en$request_uri;
    }
    location ~ \.css {
      add_header Content-Type text/css;
    }
    location ~ \.js {
      add_header Content-Type application/x-javascript;
    }
  }
}

Я пробовал другую конфигурацию, но все еще не могу пройти проверку сертификата API:

api_1             | [06:59:30 DBG] Failed to authenticate HTTPS connection.
api_1             | System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. ---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL. ---> Interop+Crypto+OpenSslCryptographicException: error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown
api_1             |    --- End of inner exception stack trace ---
api_1             |    at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, Byte[] recvBuf, Int32 recvOffset, Int32 recvCount, Byte[]& sendBuf, Int32& sendCount)
api_1             |    at System.Net.Security.SslStreamPal.HandshakeInternal(SafeFreeCredentials credential, SafeDeleteContext& context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
api_1             |    --- End of inner exception stack trace ---
api_1             |    at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
api_1             |    at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
api_1             |    at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
api_1             |    at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
api_1             |    at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
api_1             |    at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
api_1             | --- End of stack trace from previous location where exception was thrown ---
api_1             |    at System.Net.Security.SslState.ThrowIfExceptional()
api_1             |    at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
api_1             |    at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
api_1             |    at System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult asyncResult)
api_1             |    at System.Net.Security.SslStream.<>c.<AuthenticateAsServerAsync>b__51_1(IAsyncResult iar)
api_1             |    at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...