https для локальных доменов с помощью mkcert

https для локальных доменов с помощью mkcert
Photo by Joshua Sortino / Unsplash

Возникла необходимость убрать из внешней сети несколько проектов и перенести их в домен .local с обеспечением https соединения. Искал способ организации https соединения, на которое не будут ругаться браузера (что происходит постоянно при использовании самоподписанных сертификатов. Спойлер: не в этот раз). На просторах сети наткнулся на утилиту mkcert, вот её и будем использовать.

Наш вариант использования - сборка из исходников.

Установка Go 1.13+

В Ubuntu 24.04.1 можно установить go актуальной версии прямо из пакетов.

sudo apt search golang-go

golang-go/noble,now 2:1.22~2build1 amd64
  Go programming language compiler, linker, compiled stdlib
sudo apt install golang-go

Устанавливаем mkcert

Как писалось выше, наш вариант - сборка из исходников, поэтому качаем исходники в директорию /opt:

cd /opt
git clone https://github.com/FiloSottile/mkcert
cd mkcert

Запускаем компиляцию полученных исходников:

go build -ldflags "-X main.Version=$(git describe --tags)"

Можно получить ошибку сборки:

fatal: detected dubious ownership in repository at '/opt/mkcert'
To add an exception for this directory, call:

        git config --global --add safe.directory /opt/mkcert
error obtaining VCS status: exit status 128
        Use -buildvcs=false to disable VCS stamping.

Следуя ошибке выполняем команду git'a и повторяем сборку:

git config --global --add safe.directory /opt/mkcert
sudo go build -ldflags "-X main.Version=$(git describe --tags)"

По факту сборки в директории /opt/mkcert должен появиться файл mkcert.

Создание и использование сертификата mkcert

Первый запуск выполняем с флагом -install:

sudo ./mkcert -install

Created a new local CA 💥
The local CA is now installed in the system trust store! ⚡️

Затем можем сгенерировать сертификаты для наших проектов. Так как все проекты локальные и из внешней сети не доступны я буду генерировать сертификат для всех поддоменов локального.

Для этого выбираю папку размещения сертификатов, в ней выполняю команду генерации сертификатов домена:

sudo /opt/mkcert/mkcert savenkoff.local "*.savenkoff.local"

Created a new certificate valid for the following names 📜
 - "savenkoff.local"
 - "*.savenkoff.local"

Reminder: X.509 wildcards only go one level deep, so this won't match a.b.savenkoff.local ℹ️

The certificate is at "./savenkoff.local+1.pem" and the key at "./savenkoff.local+1-key.pem" ✅

It will expire on 27 February 2027 🗓

Настраиваем Nginx

Перенастраиваем виртуальный хост NGinx для использования сертификатов. Редактируем в блоке server основные директивы:

server {
    server_name host.savenkoff.local;

    listen 443 ssl;
    ssl_certificate /var/www/certs/savenkoff.local+1.pem;
    ssl_certificate_key /var/www/certs/savenkoff.local+1-key.pem;
}

Перезагружаем nginx:

sudo systemctl restart nginx

Проверка

Заходим на адрес хоста, видим, что соединение https, но проверить подлинность сертификата браузер не может.

Поскриптум

Кого-то устроит и такой результат, но не меня. Мне нужно, чтобы браузеры различных устройств не запрашивали подтверждение на внутренних доменах, а устанавливать на каждый корневой сертификат в удостоверяющий центр - не совсем тот путь, которым хотелось бы идти. Не совсем тот результат, который мне нужен, поэтому будем рыть дальше, а этот материал оставим как заметку на всякий случай.