Как заставить веб-браузеры в сторонних контейнерах в DDEV принимать мой SSL-сертификат mkcert?

Я использую DDEV 1.8.0.

Я запускаю тесты Behat, используя justinribeiro/chrome-headless. Он включен в мой проект DDEV через дополнительный файл Docker Compose с именем docker-compose.chrome.yaml. Вот содержание:

---
version: '3.6'
services:
  chrome:
    image: justinribeiro/chrome-headless
    restart: unless-stopped
    container_name: ddev-${DDEV_SITENAME}-chrome
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: $DDEV_APPROOT
      com.ddev.app-url: $DDEV_URL
    volumes:
      - ddev-global-cache:/mnt/ddev-global-cache
    external_links:
      - "ddev-router:fps.ddev.local"
      - "ddev-router:dev.fillpdf-service.com"
    cap_add:
      - SYS_ADMIN
    ports:
      - '9222:9222'
networks:
  default:
    external:
      name: ddev_default

Служба chrome не содержит mkcert, поэтому тесты Behat, в которых используется этот контейнер, завершаются ошибкой, поскольку безголовый экземпляр Chrome отклоняет сертификат SSL. Как я могу заставить Chrome и cURL / wget распознавать сертификаты, выданные центром сертификации mkcert?


person wizonesolutions    schedule 24.05.2019    source источник


Ответы (1)


Довольно просто заставить mkcert работать в стороннем контейнере. Заставить его работать с headless Chrome, Chromium, Firefox и другими браузерами, которые не используют системный магазин в Linux, немного менее интуитивно понятно.

Во-первых, давайте посмотрим, какие изменения нужно внести, чтобы все работало. При необходимости я включаю краткие пояснения под каждый файл. Я объясню их вместе в конце.

.ddev/docker-compose.chrome.yaml:

---
version: '3.6'
services:
  chrome:
    build:
      context: ./chrome-build
    restart: unless-stopped
    container_name: ddev-${DDEV_SITENAME}-chrome
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: $DDEV_APPROOT
    volumes:
      - ddev-global-cache:/mnt/ddev-global-cache
    external_links:
      - "ddev-router:fps.ddev.local"
      - "ddev-router:dev.fillpdf-service.com"
    cap_add:
      - SYS_ADMIN
    ports:
      - '9222:9222'
networks:
  default:
    external:
      name: ddev_default

Мы изменили параметр image на build и указываем ему новую папку, которую собираемся создать.

Новая папка: .ddev/chrome-build/Dockerfile

.ddev/chrome-build/Dockerfile

FROM justinribeiro/chrome-headless
ADD chrome-startup.sh /

ENV MKCERT_VERSION=v1.3.0
USER root
RUN apt-get update && apt-get install -y curl openssl libnss3-tools && curl -sSL https://github.com/FiloSottile/mkcert/releases/download/$MKCERT_VERSION/mkcert-$MKCERT_VERSION-linux-amd64 -o /usr/local/bin/mkcert && chmod +x /usr/local/bin/mkcert && apt-get purge -y curl && apt-get clean && chmod +x /chrome-startup.sh
ENTRYPOINT [ "/chrome-startup.sh" ]

.ddev/chrome-build/chrome-startup.sh

#!/bin/bash
if [[ ! -f /.mkcert-configured ]]; then
  #!/usr/bin/env bash
  # Install for root (system).
  CAROOT="/mnt/ddev-global-cache/mkcert" mkcert -install

  # Install for user: chrome.
  su chrome -c 'mkdir -p $HOME/.local/share/mkcert'
  cp -R /mnt/ddev-global-cache/mkcert/* /home/chrome/.local/share/mkcert/
  chown -R chrome: /home/chrome/.local/share/mkcert
  # Create the NSS trust store BEFORE running mkcert; mkcert doesn't reliably
  # work otherwise.
  su chrome -c 'mkdir -p $HOME/.pki/nssdb'
  su chrome -c 'certutil -d sql:$HOME/.pki/nssdb -N --empty-password'
  su chrome -c 'cd $HOME && TRUST_STORES=nss mkcert -install'

  touch /.mkcert-configured
fi

# Run headless Chrome in the foreground (the original container's command).
su chrome -c 'google-chrome --headless --disable-gpu --remote-debugging-address=0.0.0.0 --remote-debugging-port=9222'

Dockerfile создает собственный контейнер поверх justinribeiro/chrome-headless. Мы устанавливаем необходимые компоненты mkcert, сам mkcert и необязательный компонент libnss3-tools. В этом случае для нас это не обязательно.

Мы также меняем контекст пользователя на root, потому что для работы сценария запуска нам нужно быть root.

Скрипт chrome-startup.sh устанавливает mkcert. Мы должны установить его при запуске, потому что мы полагаемся на смонтированный том, содержащий сертификаты. Он недоступен во время сборки. Он устанавливает его в масштабе всей системы, а затем устанавливает для chrome пользователя, который в действительности запускает Chrome без головы, как в этом контейнере.

Одна заметная сложность при установке для chrome пользователя заключается в том, что нам нужно вручную создать базу данных NSS, которую используют Firefox, Chrome без головы и Chromium. Предполагается, что команда mkcert -install создает это автоматически, но не всегда. Однако, если мы сначала создадим базу данных NSS, она будет работать стабильно.

После добавления этих файлов просто используйте ddev start или ddev restart, настройте Behat для использования безголового Chrome на http://192.168.65.2:9222, и теперь вы сможете установить для своего _19 _._ 20_ значение https://mysite.ddev.local (где mysite заменяется именем вашего проекта). Теперь Headless Chrome должен принимать сертификат SSL. Я не объяснял конфигурацию Behat подробно, так как это выходит за рамки этого ответа.

Behat теперь должен работать (или продолжать работу).

Вы также можете проверить, распознает ли Chrome ваш сертификат SSL вручную.

SSH в контейнер: ddev ssh -s chrome

Распечатайте содержание веб-сайта: su chrome -c 'google-chrome --headless --disable-gpu --dump-dom https://mysite.ddev.local'

Если проверка сертификата не удалась, вы увидите вывод, содержащий следующее:

[0524/160648.082825:ERROR:cert_verify_proc_nss.cc(975)] CERT_PKIXVerifyCert for dev.fillpdf-service.com failed err=-8179

Если вместо этого вы видите кучу HTML-кода, значит, он работает!

person wizonesolutions    schedule 24.05.2019