Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Enable TLS for local development with docker compose #1479

Open
wants to merge 7 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# docker-compose secrets
src/docker-compose.certificates.yml

# local history
.history
.vshistory

# User-specific files
*.suo
*.user
Expand Down
4 changes: 4 additions & 0 deletions deploy/certificates/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.key
*.pem
*.pfx
*.txt
40 changes: 40 additions & 0 deletions deploy/certificates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Setup dev certificates deploying to Docker Desktop

1. Create a self-signed certificate
2. Install certificates
3. Configure the services

## 1 - Create the self-signed certificate (`.pem + .key`) and its `.pfx` file

**From WSL**, run the `create-docker-certificate.sh` script with a strong password for the certificate.

```bash
./create-docker-certificate.sh "secure-COMPLEX-and-SECRET-password"
```

The script creates a certificate for both `host.docker.internal` and `localhost`.

### 2 - Install the certificates

Run the `install-docker-certificate.ps1` with the same password you used above:

```powershell
.\install-docker-certificate.ps1 "secure-COMPLEX-and-SECRET-password"
```

The above script:

1. Imports the certificate in the current user root CA store.
2. Copies the certificate files to the `%USERPROFILE%\.aspnet\https` folder. Servers will serve the certificate from this folder.
3. Copies the `.pem` file as `.crt` to the src\certificates folder to add it as a root CA when building the images for some services.

### 3 - Configure some services to serve the certificates

1. Copy the `src\docker-compose.certificates.sample.yml` file as `src\docker-compose.certificates.yml`
2. Configure the password you assigned to the certificates in the settings `ASPNETCORE_Kestrel__Certificates__Default__Password`

> **IMPORTANT**
>
> The `src\docker-compose.certificates.yaml` file is .gitignore'd to avoid pushing it to the repo with the certificate password.
>
> To avoid security risks, **DON'T FORCE PUSH the file**.
22 changes: 22 additions & 0 deletions deploy/certificates/create-docker-certificate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
echo "creating base certificate (.pem) and private key (.key) files..."
openssl req \
-x509 \
-days 365 \
-out docker-self-signed.pem \
-keyout docker-self-signed.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=host.docker.internal' \
-extensions EXT \
-config <( \
printf "[dn]\nCN=host.docker.internal\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName='DNS.1:host.docker.internal,DNS.2:localhost'\nkeyUsage=digitalSignature,keyCertSign\nextendedKeyUsage=serverAuth")

echo "printing text version..."
openssl x509 -in docker-self-signed.pem -text -noout > docker-self-signed.txt

echo "generating certificate container file (.pfx)..."
openssl pkcs12 -export \
-inkey docker-self-signed.key \
-in docker-self-signed.pem \
-out docker-self-signed.pfx \
-name "Docker development certificate" \
-password pass:$1
17 changes: 17 additions & 0 deletions deploy/certificates/install-docker-certificate.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
param (
[Parameter(Mandatory = $true)]
[string]$Password
)

# Import into current user root CA store
$CertPassword = ConvertTo-SecureString -String "$Password" -Force -AsPlainText
Import-PfxCertificate -Exportable -FilePath .\docker-self-signed.pfx -CertStoreLocation Cert:\CurrentUser\Root\ -Password $CertPassword

# Copy to user profile to use as HTTPS certificate in server containers
mkdir $env:USERPROFILE\.aspnet\https -Force
Copy-Item docker-self-signed.pem $env:USERPROFILE\.aspnet\https -Force
Copy-Item docker-self-signed.key $env:USERPROFILE\.aspnet\https -Force
Copy-Item docker-self-signed.pfx $env:USERPROFILE\.aspnet\https -Force

# Copy to src folder to register as a root CA in client containers
Copy-Item docker-self-signed.pem ..\..\src\certificates\docker-self-signed.crt -Force
4 changes: 2 additions & 2 deletions src/.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

# Use this values to run the app locally in Windows
ESHOP_EXTERNAL_DNS_NAME_OR_IP=host.docker.internal
ESHOP_STORAGE_CATALOG_URL=http://host.docker.internal:5202/c/api/v1/catalog/items/[0]/pic/
ESHOP_STORAGE_MARKETING_URL=http://host.docker.internal:5110/api/v1/campaigns/[0]/pic/
ESHOP_STORAGE_CATALOG_URL=https://host.docker.internal:5202/c/api/v1/catalog/items/[0]/pic/
ESHOP_STORAGE_MARKETING_URL=https://host.docker.internal:5110/api/v1/campaigns/[0]/pic/

# Use this values to run the app locally in Mac
# ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.mac.localhost
Expand Down
1 change: 1 addition & 0 deletions src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
certificates
108 changes: 106 additions & 2 deletions src/ApiGateways/Envoy/config/webshopping/envoy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ admin:
port_value: 8001
static_resources:
listeners:
- address:
- name: listener_https
address:
socket_address:
address: 0.0.0.0
port_value: 80
port_value: 443
filter_chains:
- filters:
- name: envoy.http_connection_manager
Expand All @@ -22,6 +23,109 @@ static_resources:
- name: eshop_backend
domains:
- "*"
# - "localhost"
# - "host.docker.internal"
routes:
- name: "c-short"
match:
prefix: "/c/"
route:
auto_host_rewrite: true
prefix_rewrite: "/catalog-api/"
cluster: catalog
- name: "c-long"
match:
prefix: "/catalog-api/"
route:
auto_host_rewrite: true
cluster: catalog
- name: "o-short"
match:
prefix: "/o/"
route:
auto_host_rewrite: true
prefix_rewrite: "/ordering-api/"
cluster: ordering
- name: "o-long"
match:
prefix: "/ordering-api/"
route:
auto_host_rewrite: true
cluster: ordering
- name: "h-long"
match:
prefix: "/hub/notificationhub"
route:
auto_host_rewrite: true
cluster: signalr-hub
timeout: 300s
upgrade_configs:
upgrade_type: "websocket"
enabled: true
- name: "b-short"
match:
prefix: "/b/"
route:
auto_host_rewrite: true
prefix_rewrite: "/basket-api/"
cluster: basket
- name: "b-long"
match:
prefix: "/basket-api/"
route:
auto_host_rewrite: true
cluster: basket
- name: "agg"
match:
prefix: "/"
route:
auto_host_rewrite: true
prefix_rewrite: "/"
cluster: shoppingagg
http_filters:
- name: envoy.router
access_log:
- name: envoy.file_access_log
filter:
not_health_check_filter: {}
config:
json_format:
time: "%START_TIME%"
protocol: "%PROTOCOL%"
duration: "%DURATION%"
request_method: "%REQ(:METHOD)%"
request_host: "%REQ(HOST)%"
path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
response_flags: "%RESPONSE_FLAGS%"
route_name: "%ROUTE_NAME%"
upstream_host: "%UPSTREAM_HOST%"
upstream_cluster: "%UPSTREAM_CLUSTER%"
upstream_local_address: "%UPSTREAM_LOCAL_ADDRESS%"
path: "/tmp/access.log"
tls_context:
common_tls_context:
tls_certificates:
- certificate_chain:
filename: "/https/docker-self-signed.pem"
private_key:
filename: "/https/docker-self-signed.key"
- name: listener_http
address:
socket_address:
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: eshop_backend_route
virtual_hosts:
- name: eshop_backend
domains:
- "webshoppingapigw"
routes:
- name: "c-short"
match:
Expand Down
4 changes: 3 additions & 1 deletion src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
WORKDIR /usr/local/share/ca-certificates
COPY "certificates/docker-self-signed.crt" .
RUN update-ca-certificates
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
Expand Down
2 changes: 1 addition & 1 deletion src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF
app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();
// app.UseHttpsRedirection();

app.UseSwagger().UseSwaggerUI(c =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private IEnumerable<int> GetConfirmedGracePeriodOrders()
conn.Open();
orderIds = conn.Query<int>(
@"SELECT Id FROM [ordering].[orders]
WHERE DATEDIFF(minute, [OrderDate], GETDATE()) >= @GracePeriodTime
WHERE DATEDIFF(second, [OrderDate], GETDATE()) >= @GracePeriodTime
AND [OrderStatusId] = 1",
new { _settings.GracePeriodTime });
}
Expand Down
4 changes: 3 additions & 1 deletion src/Web/WebMVC/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
WORKDIR /usr/local/share/ca-certificates
COPY "certificates/docker-self-signed.crt" .
RUN update-ca-certificates
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
Expand Down
15 changes: 6 additions & 9 deletions src/Web/WebMVC/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,15 @@ private static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
{
var seqServerUrl = configuration["Serilog:SeqServerUrl"];
var logstashUrl = configuration["Serilog:LogstashgUrl"];
var cfg = new LoggerConfiguration()
return new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.Enrich.WithProperty("ApplicationContext", AppName)
.Enrich.FromLogContext()
.WriteTo.Console();
if (!string.IsNullOrWhiteSpace(seqServerUrl)) {
cfg.WriteTo.Seq(seqServerUrl);
}
if (!string.IsNullOrWhiteSpace(logstashUrl)) {
cfg.WriteTo.Http(logstashUrl);
}
return cfg.CreateLogger();
.WriteTo.Console()
.WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl)
.WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}

private static IConfiguration GetConfiguration()
Expand Down
39 changes: 39 additions & 0 deletions src/docker-compose.certificates.sample.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: '3.4'

services:

identity-api:
environment:
- ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_Kestrel__Certificates__Default__Password=<secure-COMPLEX-and-SECRET-password>
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/docker-self-signed.pfx
volumes:
- ~/.aspnet/https:/https:ro

webstatus:
environment:
- ASPNETCORE_URLS=https://+:443
- ASPNETCORE_Kestrel__Certificates__Default__Password=<secure-COMPLEX-and-SECRET-password>
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/docker-self-signed.pfx
volumes:
- ~/.aspnet/https:/https:ro

webmvc:
environment:
- ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_Kestrel__Certificates__Default__Password=<secure-COMPLEX-and-SECRET-password>
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/docker-self-signed.pfx
volumes:
- ~/.aspnet/https:/https:ro

webspa:
environment:
- ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_Kestrel__Certificates__Default__Password=<secure-COMPLEX-and-SECRET-password>
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/docker-self-signed.pfx
volumes:
- ~/.aspnet/https:/https:ro

webshoppingapigw:
volumes:
- ~/.aspnet/https:/https:ro
Loading