Установка TLS-сертификата Минцифры

Инструкция по установке корневых сертификатов Russian Trusted CA на сервер

Зачем это нужно

CA/Browser Forum — международная организация, в которую входят крупнейшие центры сертификации и компании, разрабатывающие браузеры (Google, Apple, Microsoft, Mozilla). CA/Browser Forum ужесточила правила проверки организаций — сертификаты GlobalSign, которые многие используют сейчас, могут быть отозваны.

Когда это произойдет, API и сервисы перейдут на сертификаты Национального удостоверяющего центра Минцифры России (Russian Trusted CA).

Сертификаты Минцифры не входят в доверенные хранилища большинства операционных систем, языковых рантаймов и HTTP-библиотек по умолчанию. Поскольку ваш код обращается к API программно, а не через браузер, добавьте сертификаты в trust store серверного окружения, из которого выполняются запросы.

Вам нужно установить два сертификата:

Шаг 1. Скачайте сертификаты

Скачайте сертификаты с портала Госуслуг: https://www.gosuslugi.ru/crt. На странице перейдите в раздел для вашей операционной системы и скачайте два файла:

Проверьте формат файла сертификата. Файлы .cer бывают двух форматов:

Утилиты update-ca-certificates и keytool принимают только PEM.

DER-файл нужно сконвертировать в PEM:

# Проверить формат
openssl x509 -in cert.cer -noout -text >/dev/null 2>&1 && echo "PEM" || echo "DER (нужна конвертация)"

# Конвертировать DER в PEM
openssl x509 -inform DER -in cert.cer -out cert.pem

Шаг 2. Установите сертификаты

Установите сертификаты для вашего окружения. Если окружений несколько — например, JVM-приложение в Docker, выполните настройку для каждого из них.

Linux (Debian / Ubuntu)

sudo cp russian_trusted_root_ca.pem /usr/local/share/ca-certificates/russian_trusted_root_ca.crt
sudo cp russian_trusted_sub_ca.pem /usr/local/share/ca-certificates/russian_trusted_sub_ca.crt
sudo update-ca-certificates

Linux (RHEL / CentOS / Alma / Rocky)

sudo cp russian_trusted_*.pem /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

Java / JVM

JVM не использует системное хранилище ОС. Рекомендуем создать отдельный truststore, а не изменять cacerts внутри JRE. Изменения в cacerts сбрасываются при обновлении JDK, а в prod-среде на запись в этот файл часто нет прав.

# Создать отдельный truststore и импортировать оба сертификата
keytool -importcert -alias russian_trusted_root \
  -file russian_trusted_root_ca.pem \
  -keystore russian_truststore.jks \
  -storepass <пароль> -noprompt

keytool -importcert -alias russian_trusted_sub \
  -file russian_trusted_sub_ca.pem \
  -keystore russian_truststore.jks \
  -storepass <пароль> -noprompt

Укажите truststore при запуске приложения:

java -Djavax.net.ssl.trustStore=/path/to/russian_truststore.jks \
  -Djavax.net.ssl.trustStorePassword=<пароль> \
  -jar app.jar

Отдельный truststore не наследует системные доверенные CA — он содержит только явно добавленные сертификаты. Если приложению нужно доверять одновременно публичным CA и сертификатам Минцифры, импортируйте сертификаты Минцифры в копию стандартного cacerts и используйте ее или добавьте все необходимые корневые сертификаты в truststore.

Путь к стандартному хранилищу зависит от версии JDK: Java 8 — $JAVA_HOME/jre/lib/security/cacerts, Java 9+ — $JAVA_HOME/lib/security/cacerts.

Python (requests / httpx / aiohttp)

Эти библиотеки используют bundle certifi, а не системное хранилище. Доступны два варианта:

# Через переменные окружения (действуют на весь процесс)
export REQUESTS_CA_BUNDLE=/path/to/russian-trusted-ca-bundle.pem
export SSL_CERT_FILE=/path/to/russian-trusted-ca-bundle.pem
# Или явно в коде
import requests
requests.get("https://check.russian-trusted.ru/", verify="/path/to/russian-trusted-ca-bundle.pem")

Node.js

Node.js по умолчанию игнорирует системное хранилище:

NODE_EXTRA_CA_CERTS=/path/to/russian-trusted-ca-bundle.pem node app.js

Docker

Добавляйте сертификаты на этапе сборки образа, а не в рантайме:

COPY russian-trusted-ca-bundle.pem /usr/local/share/ca-certificates/russian-trusted-ca.crt
RUN update-ca-certificates
# Для Node.js и Python внутри контейнера задайте переменные окружения:
ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

Windows / .NET / IIS

.NET использует системное хранилище сертификатов Windows. Для установки в хранилище LocalMachine, которое используется сервисами и приложениями, работающими не от имени текущего пользователя, выполните команды:

# PowerShell с правами администратора
Import-Certificate -FilePath "C:\certs\russian_trusted_root_ca.cer" `
  -CertStoreLocation Cert:\LocalMachine\Root
Import-Certificate -FilePath "C:\certs\russian_trusted_sub_ca.cer" `
  -CertStoreLocation Cert:\LocalMachine\CA

Корневой сертификат устанавливается в хранилище Root (доверенные корневые CA), промежуточный — в CA (промежуточные CA). То же самое можно сделать через GUI в certlm.msc. После установки перезапустите пул приложений или сервис.

Шаг 3. Проверьте установку

curl -v https://check.russian-trusted.ru/
# Ожидаемый результат: SSL certificate verify ok
openssl s_client -connect check.russian-trusted.ru:443 -servername check.russian-trusted.ru -showcerts </dev/null
# Флаг -servername (SNI) обязателен: без него на shared-хостинге может вернуться не тот сертификат.
# В цепочке должны присутствовать Russian Trusted Root CA и Russian Trusted Sub CA.
# Проверить срок действия установленного сертификата
echo | openssl s_client -connect check.russian-trusted.ru:443 -servername check.russian-trusted.ru 2>/dev/null \
  | openssl x509 -noout -dates

Если сертификат Минцифры установлен — соединение будет успешным. Если нет — увидите ошибку SSL certificate problem: unable to get local issuer certificate.

Возможные проблемы

ПроблемаПричинаРешение
unable to get local issuer certificate Не установлен промежуточный сертификат (Sub CA) Установить оба сертификата
Ошибка сохраняется после update-ca-certificates Python/Node.js используют собственный bundle Задать переменные REQUESTS_CA_BUNDLE / NODE_EXTRA_CA_CERTS
В Docker всё падает в рантайме Сертификат добавлен после сборки Добавить сертификат на этапе build и пересобрать образ
Работает локально, падает в production Разные окружения или разные truststore Выполнить настройку в каждом окружении
update-ca-certificates отработал, но CA не доверяется Файл в формате DER вместо PEM Сконвертировать: openssl x509 -inform DER -in cert.cer -out cert.pem
Соединение отклонено при корректно установленном CA Включён certificate pinning Обновить pin на новый сертификат
При проверке возвращается не тот сертификат Не передан SNI Добавить флаг -servername check.russian-trusted.ru в команду openssl s_client

Откатить изменения

Если после установки возникли проблемы, удалите добавленные сертификаты:

# Debian / Ubuntu
sudo rm /usr/local/share/ca-certificates/russian_trusted_*.crt && sudo update-ca-certificates --fresh

# RHEL / CentOS
sudo rm /etc/pki/ca-trust/source/anchors/russian_trusted_*.pem && sudo update-ca-trust

# Java — уберите флаги -Djavax.net.ssl.trustStore и -Djavax.net.ssl.trustStorePassword при запуске

# Windows
# Remove-Item Cert:\LocalMachine\Root\<thumbprint>