Как подружить .NET-контейнер с сертификатами Минцифры

30.09.2026 · 4 мин чтения

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

Для .NET-приложений, работающих в Docker, есть два надёжных способа настроить доверие к сертификатам Минцифры:

  1. Через системное хранилище сертификатов (ca-certificates).
  2. Через переменную окружения SSL_CERT_FILE, которая принудительно указывает путь к PEM-файлу.

Ниже приведены оба варианта реализации в Dockerfile.

Вариант 1: Установка в системное хранилище (рекомендуется для curl/wget и нативного HttpClient) Этот метод обновляет глобальный список доверенных центров сертификации внутри образа.

FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble AS base

# Устанавливаем пакет для работы с системными сертификатами
RUN apt-get update && \
    apt-get install -y --no-install-recommends ca-certificates wget && \
    rm -rf /var/lib/apt/lists/*

# Создаём директорию для российских сертификатов
WORKDIR /usr/local/share/ca-certificates/russian-trusted/

# Скачиваем актуальные корневой и выпускающий сертификаты напрямую
# (Эти ссылки ведут на инфраструктуру Госуслуг/НУЦ)
RUN wget https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crt -O russian_trusted_root_ca.crt && \
wget https://gu-st.ru/content/lending/russian_trusted_sub_ca_pem.crt -O russian_trusted_sub_ca.crt

# Возвращаемся в корень и обновляем системный bundle
WORKDIR /
RUN cat /usr/local/share/ca-certificates/russian-trusted/*.crt > /usr/local/share/ca-certificates/russian_trusted_ca_bundle.crt && \
update-ca-certificates

WORKDIR /app
COPY ./bin/Release/net10.0/publish/ .
ENTRYPOINT ["dotnet", "YourAppName.dll"]

В этом случае большинство инструментов (.NET HttpClient при использовании стандартных настроек, curl) начнут видеть цепочку доверия автоматически.

Вариант 2: Использование переменной SSL_CERT_FILE (универсальный вариант для SslStream) Если ваше приложение использует кастомные настройки HttpClientHandler или работает с низкоуровневым SslStream, надёжнее всего явно указать файл со всеми корнями.

FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble AS base

# Копируем заранее скачанные сертификаты из контекста сборки в образ
# Положите файлы russian_trusted_root_ca.crt и russian_trusted_sub_ca.crt рядом с Dockerfile
COPY ./certs/ /usr/local/share/ca-certificates/russian-trusted/

# Объединяем их в один бандл (это удобнее для передачи в ENV)
RUN cat /usr/local/share/ca-certificates/russian-trusted/*.crt > /usr/local/share/ca-certificates/russian_trusted_ca_bundle.crt

# Указываем среде выполнения .NET использовать этот файл
ENV SSL_CERT_FILE=/usr/local/share/ca-certificates/russian_trusted_ca_bundle.crt

WORKDIR /app
COPY ./bin/Release/net10.0/publish/ .
ENTRYPOINT ["dotnet", "YourAppName.dll"]

Среда выполнения .NET по умолчанию пытается использовать либо системное хранилище OpenSSL, либо собственное внутреннее хранилище корней. Переменная SSL_CERT_FILE переопределяет это поведение, заставляя библиотеку System.Net.Security загружать доверенные центры именно из указанного файла.

Важное замечание по безопасности: никогда не копируйте приватные ключи (*.key, .pfx без пароля) в публичные Docker-образы. В примерах выше используются только открытые корневые сертификаты (файлы .crt или .pem), которые содержат лишь открытый ключ центра сертификации и предназначены для публичного распространения.

Оставаясь на сайте, Вы даете свое согласие на использование файлов cookie и на обработку персональных данных