Ddev: Add self-signed SSL certs to CA chain in web container

Created on 9 Nov 2018  路  8Comments  路  Source: drud/ddev

In some circumstances TYPO3 9.5 uses curl to fetch own content, f.e. for rendering error pages.
Trying to fetch these pages via https results in an error due to invalid SSL certificates, because they are self-signed but not known by the CA inside the web container.
As a workaround we added a volume pointing to ~/.ddev/certs and added a post-start hook to add all certs found in this directory to the CA:

.ddev/config.yaml

hooks:
    post-start:
      # add self-signed certs to ca to be used by curl, wget etc.
      - exec: bash -c "sudo /usr/local/bin/add-certs-to-ca"

.ddev/docker-compose.override.yaml

```version: '3.6'

use this file to make the hostnames available for dns in web container

only works with http because https is terminated by ddev-router (nginx proxy)

and self-signed ssl certificate is invalid for curl

services:
web:
external_links:
- ddev-router:$DDEV_HOSTNAME
volumes:
# mount certs into web container to add them to CA for using curl with https
# without complaining about insecure self-signed certificates
- ~/.ddev/certs:/usr/share/ca-certificates/ddev
- ../Build/Ddev/add-certs-to-ca.sh:/usr/local/bin/add-certs-to-ca

Build/Ddev/add-certs-to-ca.sh

!/bin/bash

search_dir=/usr/share/ca-certificates/ddev
ca_certs_file=/etc/ca-certificates.conf

remove already existing certs of ddev from certs file

sed -i '/^ddev\//d' "$ca_certs_file"

add all ddev certs

for entry in "$search_dir"/*.crt
do
b=ddev/$(basename "$entry")
echo "$b" >> "$ca_certs_file"
done

update-ca-certificates --fresh
```

Prioritized

All 8 comments

Thanks for this! A PR is welcome. FYI in v1.4.0, the certs are in a docker volume, not longer bind-mounted into ~/.ddev.

Oh, could you also please provide a way to test this situation? How can we get TYPO3 to do this?

To reproduce this in TYPO3 9.5.x go to backend module "SITE MANAGEMENT / Sites", create a site and goto tab "Error Handling". Create at least one error handling for HTTP Error Status Code 404 and select "Show content from page" from "How to handle errors" list. Select an existing page from TYPO3 page tree to be displayed as error page in "Show Content from page".
If you edit the site configuration directly in config.yaml then add the following for the proper error handling:

errorHandling:
  -
    errorCode: '404'
    errorHandler: Page
    errorContentSource: 't3://page?uid=5'

Where 5 is the uid of the page to be displayed as error page.

Switch to frontend (use an https URL) and enter a non existing slug. After that you should see a simple unstyled error page with the error message "Error handler could not fetch error page: Possible recursion detected." instead of the selected error page. After adding the described workaround you should see the selected error page instead.

FYI in v1.4.0, the certs are in a docker volume, not longer bind-mounted into ~/.ddev.

This volume definition works in v1.4.0:

# use this file to make the hostnames available for dns in web container
# only works with http because https is terminated by ddev-router (nginx proxy)
# and self-signed ssl certificate is invalid for curl
services:
  web:
    external_links:
      - ddev-router:$DDEV_HOSTNAME
    volumes:
      # mount certs into web container to add them to CA for using curl with https
      # without complaining about insecure self-signed certificates
      - type: "volume"
        source: ddev-router-cert-cache
        target: "/usr/share/ca-certificates/ddev"
        read_only: true
      - ../Build/Ddev/add-certs-to-ca.sh:/usr/local/bin/add-certs-to-ca
volumes:
  ddev-router-cert-cache:
    name: "ddev-router-cert-cache"

mkcert looks like a great cross-platform tool for doing this: https://blog.filippo.io/mkcert-valid-https-certificates-for-localhost/ [edited to correct url]

Another article on this, https://medium.com/@serheydolgushev/using-self-signed-ssl-certificates-in-local-development-f2ff3ddbdb30

Best case we'll also solve #1450 with this one.

I took a quick tour of mkcert and it looks great. I found it easy to get the host browser (and curl) to trust the result of content coming from ddev-router. However, there's more to do:

  • The web container also needs to trust those same certs, which means that it will have to trust the host CA set up by mkcert.
  • The web container should also serve https (with the trusted certs) on a host port (like https://127.0.0.1:33333). In the past, it has only provided an http port.
  • Add mkcert as a dependency of ddev in homebrew-ddev

As described you can either copy the root ca file to the right place in the container or I'm sure we can mount it, either way.

Was this page helpful?
0 / 5 - 0 ratings