Traefik — 9. Настройка для работы с сертификатом НУЦ Минцифры
22 апреля 2026
В этой статье я расскажу как получить отечественный SSL-сертификат Национального Удостоверяющего Центра Минцифры России и подключить его к Traefik. А также о граблях, на которые я наступил.
Получение сертификата
Для получения сертификата необходимо перейти на Госуслуги. Набираем в поиске «Получение DV-сертификата безопасности».
Определяемся с типом сертификата: OV (Organization Validation) и DV (Domain Validation). Выбираем DV-сертификат. Также пока воспользуемся RSA вариантом шифрования. ГОСТ нас пока не интересует.
Теперь нас просят загрузить запрос на выпуск сертификата.
Его можно подготовить по инструкции на Госуслугах, а можно воспользоваться простым скриптом, который упрощает эту задачу:
#!/bin/bash set -e # Проверяем, передан ли параметр домена if [ -z "$1" ]; then echo "Использование: $0 <домен>" echo "Пример: $0 19dx.ru" exit 1 fi DOMAIN="$1" CSR_FILE="${DOMAIN}.csr" KEY_FILE="${DOMAIN}.key" CNF_FILE="${DOMAIN}.cnf" # Предупреждение при наличии старых файлов if [ -f "$KEY_FILE" ] || [ -f "$CSR_FILE" ]; then echo "⚠️ Файлы $KEY_FILE или $CSR_FILE уже существуют и будут перезаписаны." fi # Автоматическое создание конфигурационного файла echo "📝 Генерация конфигурационного файла: $CNF_FILE" cat > "$CNF_FILE" <<EOF [ req ] distinguished_name = req_distinguished_name req_extensions = v3_req x509_extensions = v3_req prompt = no string_mask = utf8only utf8 = yes [ req_distinguished_name ] CN = ${DOMAIN} C = RU [ v3_req ] keyUsage = digitalSignature, keyEncipherment, keyAgreement extendedKeyUsage = serverAuth, clientAuth subjectAltName = DNS:${DOMAIN} EOF # Генерация CSR и приватного ключа echo "🔑 Генерация CSR и приватного ключа для домена: $DOMAIN..." openssl req -out "$CSR_FILE" -new -newkey rsa:2048 -nodes -keyout "$KEY_FILE" -config "$CNF_FILE" # Проверка/вывод содержимого CSR echo "📄 Проверка содержимого CSR..." openssl req -in "$CSR_FILE" -noout -text -nameopt utf8 -config "$CNF_FILE" echo "✅ Готово. Созданы файлы:" echo " • $CSR_FILE" echo " • $KEY_FILE" echo " • $CNF_FILE"
Этот скрипт автоматически создаёт файл запроса, вписывает туда имя домена, подписывает его и формирует закрытый ключ. Для этого просто необходимо передать имя домена в качестве параметра скрипту:
./gen_csr.sh example.ru
В результате будут сформированы три файла:
- domain.ru.cnf - файл запроса.
- domain.ru.csr - подписанный файл запроса.
- domain.ru.key - закрытый ключ.
csr-файл загружаем на Госуслуги.
После этого нас попросят подтвердить права владения доменом. Это можно сделать либо с помощью размещения текстового файла на сервере (он должен быть доступен по HTTP-протоколу!), либо TXT-записи в DNS:
Если всё успешно, то через пару минут в Госуслуги придёт сертификат (в форматах cer и crt, но по сути это полные копии с разными расширениями).
Подключение сертификата
Сначала я пытался скачанный из Госуслуг сертификат сразу подключить к Traefik, потратил много времени, но ничего не заработало. В результате оказалось, что для Traefik нужен сертификат в PEM формате. Сконвертировать его очень просто с помощью команды:
openssl x509 -inform DER -in domain.crt -out domain.pem
Или воспользоваться скриптом:
#!/bin/bash set -e # Проверяем, передан ли параметр домена if [ -z "$1" ]; then echo "Использование: $0 <домен>" echo "Пример: $0 example.ru" exit 1 fi DOMAIN="$1" CRT_FILE="${DOMAIN}.crt" PEM_FILE="${DOMAIN}.pem" BAK_FILE="${DOMAIN}.crt.bak" openssl x509 -inform DER -in "$CRT_FILE" -out "$PEM_FILE" mv "$CRT_FILE" "$BAK_FILE" mv "$PEM_FILE" "$CRT_FILE"
./convert_cert.sh example.ru
В результате выполнения скрипта исходный crt файл будет перезаписан его pem-версией, а исходный файл сохранён с расширением bak.
Создаём каталог для хранения сертификатов ./data/certs/ и пробрасываем его в контейнер. Для этого правим docker-compose.yml:
services: traefik: image: traefik:v3 container_name: traefik restart: unless-stopped security_opt: - no-new-privileges:true ports: - 80:80 - 443:443 networks: proxy-net: volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/traefik.yml:/traefik.yml:ro - ./data/custom/:/custom/:ro - ./data/certs/:/certs/:ro - ./data/acme.json:/acme.json - /var/log/traefik:/var/log/traefik ...
Помещаем crt и key файлы в ./data/certs/ и создаём файл ./data/custom/tls.yml со следующим содержимым:
tls: certificates: - certFile: /certs/example.ru.crt keyFile: /certs/example.ru.key - certFile: /certs/test.example.ru.crt keyFile: /certs/test.example.ru.key
Здесь, для примера, присутствует два сертификата: для доменов example.ru и test.example.ru.
P.S. Сначала я пытался поместить эти строки в файл статической конфигурации, но почему-то ничего не заработало. Traefik отказывался загружать сертификаты.
Теперь правим файл динамической конфигурации ./data/custom/host.yml . Вместо «tls: certResolver: letsEncrypt» в роутере необходимо прописать строку «tls: {}»:
http: routers: test-router: entryPoints: - https service: service-test rule: Host(`example.ru`) tls: {}
Теперь можно и проверить работоспособность. Для этого выполняем команду:
openssl s_client -connect example.ru:443 </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer
Результат должен быть следующим:
subject=CN = example.ru, C = RU issuer=C = RU, O = The Ministry of Digital Development and Communications, CN = Russian Trusted Sub CA
В выводе видно, что сертификат сервера выдан Национальным Удостоверяющим Центром.
Теперь главное не забывать каждые 90 дней перевыпускать сертификат.




