Установка корневого сертификата НУЦ Минцифры для сайтов на виртуальном хостинге

Российский национальный сертификат безопасности (сертификат Минцифры, он же “сертификат НУЦ Минцифры” или “Russian Trusted Root CA”) используется для установки защищенного соединения с российскими сервисами, которые перешли на отечественные SSL-сертификаты – например, платежными шлюзами банков ( Сбербанка, Т-Банка, Альфа-Банка) и государственными системами.

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

В статье рассмотрим, как скачать и установить сертификаты Минцифры на виртуальном хостинге, как подключить его в PHP и проверить, что он используется, а также отдельно разберем особенность подключения для сайтов на WordPress.

Общий план установки

Установка сертификатов Минцифры состоит из пяти шагов:

  1. Создать в корне сайта директорию для сертификата.
  2. Скачать в нее корневой сертификат Минцифры.
  3. Определить полный путь до скачанного файла сертификата.
  4. Подключить сертификат в PHP – самостоятельно (если включен режим CGI) или через техническую поддержку (если сайт работает на mod_php).
  5. Проверить, что сертификат действительно используется.

Разберем каждый шаг подробнее.

Шаг 1. Создайте директорию для сертификата

Создайте в директории public_html директорию для сертификата – например, назовите ее cert.

Через SSH

Выполните команду, находясь в корневой директории сайта (внутри директории public_html):

mkdir cert

Без SSH

Создать директорию можно и без консоли:

  • в файловом менеджере панели управления – откройте директорию сайта (например, ~/ваш_сайт/public_html) и создайте в ней новую директорию cert;
  • через FTP/SFTP-клиент, например, FileZilla или WinSCP – подключитесь к аккаунту и создайте директорию cert в директории ~/ваш_сайт/public_html.

Шаг 2. Скачайте корневой сертификат

Файл с сертификатом Минцифры и другими стандартными корневыми сертификатами доступен по ссылке ниже:

http://cp.beget.com/shared/0NGaYKR7Z7f77SlGwjFL0NYc2D7nue4O/russian_trusted_root_ca_pem.crt

Файл с сертификатом Минцифры объединен с другими корневыми сертификатами специально. Если использовать файл только с сертификатом Минцифры, сайт перестанет доверять сертификатам остальных сервисов – тех, что не связаны с Минцифры. В этом же файле собраны и стандартные сертификаты, поэтому доверие сохраняется сразу ко всем: и к обычным сайтам, и к тем, что используют сертификат Минцифры.

Через SSH

Скачайте файл прямо в созданную директорию cert, например, командой wget:

wget -O cert/russian_trusted_root_ca_pem.crt http://cp.beget.com/shared/0NGaYKR7Z7f77SlGwjFL0NYc2D7nue4O/russian_trusted_root_ca_pem.crt

Без SSH

Скачайте файл по ссылке на локальный компьютер (через браузер), а затем загрузите его в директорию cert через файловый менеджер или FTP/SFTP-клиент.

Шаг 3. Определите полный путь к файлу сертификата

В файле php.ini путь к сертификату необходимо указать абсолютным. Определите абсолютный путь до файла сертификата на сервере – он понадобится на шаге 4.

Через SSH

Узнать полный путь можно двумя способами.

Первый – команда realpath, которая сработает, если выполнить ее из директории public_html (там же, где создана директория cert):

realpath cert/russian_trusted_root_ca_pem.crt

Пример результата:

/home/b/betutorial/mincifry.betutorial.ru/public_html/cert/russian_trusted_root_ca_pem.crt

Второй способ – узнать путь до директории public_html командой pwd, выполнив ее из этой же директории:

pwd

Пример результата:

/home/b/betutorial/mincifry.betutorial.ru/public_html

К результату останется вручную добавить /cert/russian_trusted_root_ca_pem.crt – получится тот же путь, что и в примере выше.

Без SSH

Путь можно составить вручную по схеме:

/home/[первая буква логина]/[логин]/[ваш сайт]/public_html/cert/russian_trusted_root_ca_pem.crt

Логин аккаунта указан в правом верхнем углу панели управления. Директорию, к которой привязан нужный домен, можно посмотреть в разделе «Сайты».

Мы разобрали, как скачать сертификат Минцифры для сайта, и теперь перейдем к нюансам, связанным с CMS WordPress, и подключению сертификата в PHP.

Особенность для сайтов на WordPress

Ядро WordPress не использует системный или указанный в php.ini набор сертификатов, а берет его из собственного файла:

wp-includes/certificates/ca-bundle.crt

Поэтому для корректной работы HTTPS-запросов из WordPress (например, при работе с платежными системами Российской Федерации) сертификаты Минцифры нужно дополнительно добавить в конец этого файла. Это отдельный шаг, который не зависит от режима PHP (CGI или mod_php) – выполните его независимо от того, какой режим работает на вашем сайте.

Скачанный в шаге 2 файлrussian_trusted_root_ca_pem.crt содержит несколько сертификатов подряд, каждый из которых оформлен как отдельный блок между строками -----BEGIN CERTIFICATE----- и -----END CERTIFICATE-----. Для WordPress нужны только первые два из них: сначала в файле идет промежуточный сертификат (Sub CA), затем – корневой (Root CA). Но добавлять их в ca-bundle.crt нужно в обратном порядке – сначала корневой сертификат, затем промежуточный. Остальные сертификаты из файла для этой задачи не нужны.

Через SSH

Для добавления сертификатов Минцифры в файл wp-includes/certificates/ca-bundle.crt выполните следующие действия:

  1. Извлеките из скачанного файла первые два сертификата – команда остановится сразу после второго:
awk '/-----BEGIN CERTIFICATE-----/{c++} c<=2{print > ("cert/root" c ".pem")} c>2{exit}' cert/russian_trusted_root_ca_pem.crt

Появятся два файла: cert/root1.pem – промежуточный сертификат (идет в скачанном файле первым) и cert/root2.pem – корневой (идет в скачанном файле вторым).

  1. Выведите их на экран в порядке, нужном для вставки – сначала корневой, потом промежуточный:
cat cert/root2.pem cert/root1.pem
  1. Откройте в редакторе vim файл wp-includes/certificates/ca-bundle.crt:
vim wp-includes/certificates/ca-bundle.crt
  1. Перейдите в конец файла – клавиша G (Shift+G).
  2. Откройте новую строку под последней и перейдите в режим вставки – клавиша o.
  3. Вставьте оба сертификата, выведенных на шаге 2, в том же порядке – сначала корневой, потом промежуточный.
  4. Выйдите из режима вставки – клавиша Esc.
  5. Сохраните файл и выйдите из редактора – команда :wq.

Через файловый менеджер

Откройте файлы cert/russian_trusted_root_ca_pem.crt и wp-includes/certificates/ca-bundle.crt на редактирование. Скачанный файл содержит несколько сертификатов подряд, но нужны только первые два – границы каждого блока видны по строкам -----BEGIN CERTIFICATE----- и -----END CERTIFICATE-----. Первый по счету блок – промежуточный сертификат (Sub CA), второй – корневой (Root CA). Скопируйте эти два блока (каждый – от -----BEGIN CERTIFICATE----- до соответствующего -----END CERTIFICATE-----) и вставьте их в конец wp-includes/certificates/ca-bundle.crt в обратном порядке: сначала второй блок из скачанного файла (корневой), затем первый (промежуточный). Сохраните файл.

Через FTP/SFTP-клиент

Скачайте файлы wp-includes/certificates/ca-bundle.crt и cert/russian_trusted_root_ca_pem.crt на компьютер. Скачанный файл cert/russian_trusted_root_ca_pem.crt содержит несколько сертификатов подряд, но нужны только первые два – границы каждого блока видны по строкам -----BEGIN CERTIFICATE----- и -----END CERTIFICATE-----. Они расположены в порядке: сначала промежуточный, затем корневой. Скопируйте эти два блока в текстовом редакторе и вставьте их в конец ca-bundle.crt в обратном порядке: сначала корневой (второй блок в скачанном файле), затем промежуточный (первый блок). Загрузите измененный ca-bundle.crt обратно на сервер, заменив исходный.

Шаг 4. Подключите сертификат в PHP

Способ подключения сертификата зависит от режима работы PHP на сайте – CGI или mod_php (используется по умолчанию). В режиме mod_php PHP работает как модуль веб-сервера и не запускается заново на каждый запрос. В режиме CGI PHP-скрипты обрабатывает отдельный процесс интерпретатора, из-за чего CGI расходует больше ресурсов процессора и памяти, чем mod_php, – на сайтах с высокой посещаемостью это может заметно увеличить нагрузку на аккаунт.

Посмотреть текущий режим можно в разделе “Сайты” вашей панели управления:

  1. Найдите нужный домен и нажмите на иконку в строке с именем сайта:
сайт из раздела Сайты
  1. В открывшемся окне посмотрите, активирован ли Режим cgi:
настройки сайта из раздела Сайты

Если режим CGI включен, путь к сертификату можно прописать самостоятельно. Если же он отключен, значит, для сайта используется mod_php – в этом случае сертификат подключает техническая поддержка.

Если режим CGI выключен

В режиме mod_php директивы из файла cgi-bin/php.ini не применяются – даже если создать этот файл вручную. Прописать путь к сертификату в этом случае можно только через конфигурацию виртуального хоста, которая доступна технической поддержке. Поэтому обратитесь в техническую поддержку Beget – специалисты подключат сертификат Минцифры на сайт без включения режима CGI.

В тикете укажите:

  • домен сайта;
  • полный путь к сертификату, который вы определили на шаге 3, например:
/home/b/betutorial/mincifry.betutorial.ru/public_html/cert/russian_trusted_root_ca_pem.crt

Если режим CGI включен

Путь к сертификату указывается в файле php.ini:

~/ваш_сайт/public_html/cgi-bin/php.ini

В файл нужно добавить директиву openssl.cafile с полным путем к сертификату, который вы определили на шаге 3. Например:

openssl.cafile = /home/b/betutorial/mincifry.betutorial.ru/public_html/cert/russian_trusted_root_ca_pem.crt

Через SSH

  1. Находясь в корневой директории сайта (внутри public_html), откройте файл в редакторе vim:
vim cgi-bin/php.ini
  1. Перейдите в начало файла – клавиша gg.
  2. Откройте новую строку над первой и перейдите в режим вставки – клавиша O (заглавная).
  3. Введите строку openssl.cafile с путем к сертификату.
  4. Выйдите из режима вставки – клавиша Esc.
  5. Сохраните файл и выйдите из редактора – команда :wq.

Через файловый менеджер

Откройте файл cgi-bin/php.ini на редактирование прямо в файловом менеджере панели управления, добавьте директиву openssl.cafile и сохраните файл.

Через FTP/SFTP-клиент

Скачайте файл cgi-bin/php.ini на компьютер, добавьте директиву openssl.cafile в текстовом редакторе и загрузите файл обратно на сервер, заменив исходный.

Шаг 5. Проверьте, что сертификат используется

Чтобы убедиться, что сертификат подключен и используется корректно, можно выполнить тестовый запрос к внешним ресурсам, которые используют сертификат Минцифры (например, к платежным шлюзам банков), через cURL с включенной проверкой сертификата (CURLOPT_SSL_VERIFYPEER).

Обратите внимание!
Проверять нужно именно PHP-скриптом, а не командой curl в терминале по SSH. Директива openssl.cafile из php.ini или в конфигурационном файле виртуального хоста относится только к PHP – консольная утилита curl ее не читает и использует свой собственный набор сертификатов. Поэтому команда curl https://3dsec.sberbank.ru в терминале завершится ошибкой SSL certificate problem: self signed certificate in certificate chain, даже если сертификат в PHP подключен правильно. Это не означает, что установка не удалась, – ориентируйтесь на результат PHP-скрипта.

Загрузите на сайт PHP-скрипт из блока ниже (например, под именем check-cert.php) и откройте его в браузере.

<?php
$banks = [
    'Сбербанк (3-D Secure)' => 'https://3dsec.sberbank.ru',
    'Т-Банк (3-D Secure)'   => 'https://mddc.tbank.ru',
    'Альфа-Банк (rbsuat)'   => 'https://alfa.rbsuat.com/payment/rest',
];
foreach ($banks as $name => $url) {
    echo '<h2>' . htmlspecialchars($name) . '</h2>';
    echo '<p><strong>URL:</strong> ' . htmlspecialchars($url) . '</p>';
    $verbose = fopen('php://temp', 'w+');
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER         => false,
        CURLOPT_VERBOSE        => true,
        CURLOPT_STDERR         => $verbose,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT        => 20
    ]);
    $response = curl_exec($ch);
    rewind($verbose);
    $debug = stream_get_contents($verbose);
    $error = curl_error($ch);
    $errno = curl_errno($ch);
    $info  = curl_getinfo($ch);
    curl_close($ch);
    fclose($verbose);
    echo '<pre>';
    echo htmlspecialchars($debug);
    if ($response === false) {
        echo "\n";
        echo "cURL error (" . $errno . "): ";
        echo htmlspecialchars($error);
    } else {
        echo "\n";
        echo "HTTP code: " . ($info['http_code'] ?? 0);
        echo "\n";
        echo "SSL verification: OK";
    }
    echo '</pre>';
}

Через SSH

  1. Находясь в корневой директории сайта (внутри public_html), создайте и откройте файл в редакторе vim:
vim check-cert.php
  1. Перейдите в режим вставки – клавиша i.
  2. Вставьте код скрипта (скопируйте его из блока выше).
  3. Выйдите из режима вставки – клавиша Esc.
  4. Сохраните файл и выйдите из редактора – команда :wq.

Через файловый менеджер

Создайте в директории public_html новый файл check-cert.php, откройте его на редактирование, вставьте код скрипта и сохраните.

Через FTP/SFTP-клиент

Сохраните код скрипта в файл check-cert.php на компьютере и загрузите его в директорию public_html.

После загрузки любым из способов откройте файл в браузере по адресу вида https://ваш-домен.ru/check-cert.php.

Скрипт по очереди обращается к трем платежным шлюзам, которые используют сертификат Минцифры (3-D Secure Сбербанка, Т-Банка и Альфа-Банка), и с включенной проверкой сертификата (CURLOPT_SSL_VERIFYPEER) выводит подробную диагностику TLS-соединения по каждому из них.

Главный признак успешной проверки – строки в выводе:

CAfile: /home/b/betutorial/mincifry.betutorial.ru/public_html/cert/russian_trusted_root_ca_pem.crt
issuer: C=RU; O=The Ministry of Digital Development and Communications; CN=Russian Trusted Sub CA
SSL certificate verify ok.

Строка CAfile показывает, какой именно файл сертификатов использовал cURL для проверки, – путь должен совпадать с тем, что вы указали в openssl.cafile на шаге 4. Строки issuer и SSL certificate verify ok подтверждают, что соединение прошло проверку именно по сертификату Минцифры.

Проверьте вывод по каждому из трех ресурсов – эти строки должны присутствовать в блоке диагностики для каждого банка. Код HTTP-ответа сервера (200, 302, 404 и т. д.), который выводится ниже, в данном случае не важен – значение имеет именно успешное установление SSL-соединения с указанным сертификатом.

Пример полного вывода для одного из банков:

Пример вывода скрипта проверки сертификата Минцифры

Дополнительная проверка для WordPress

Скрипт выше проверяет сертификат на уровне PHP – через директиву openssl.cafile в php.ini. Но сам WordPress (в том числе платежные плагины) могут обращаться к внешним сервисам через собственный HTTP API ядра – функцию wp_remote_get(), которая использует файл wp-includes/certificates/ca-bundle.crt.

Чтобы проверить именно эту часть, используйте отдельный скрипт, который подключает ядро WordPress:

<?php
require_once __DIR__ . '/wp-load.php';
$banks = [
    'Сбербанк (3-D Secure)' => 'https://3dsec.sberbank.ru',
    'Т-Банк (3-D Secure)'   => 'https://mddc.tbank.ru',
    'Альфа-Банк (rbsuat)'   => 'https://alfa.rbsuat.com/payment/rest',
];
foreach ($banks as $name => $url) {
    echo '<h2>' . esc_html($name) . '</h2>';
    echo '<p><strong>URL:</strong> ' . esc_html($url) . '</p>';
    $response = wp_remote_get($url, [
        'timeout'   => 20,
        'sslverify' => true,
    ]);
    echo '<pre>';
    if (is_wp_error($response)) {
        echo 'Ошибка: ' . esc_html($response->get_error_message());
    } else {
        echo 'HTTP code: ' . esc_html(wp_remote_retrieve_response_code($response)) . "\n";
        echo 'SSL verification: OK';
    }
    echo '</pre>';
}

Загрузите файл (например, check-cert-wp.php) в корень WordPress-сайта – в ту же директорию, где лежит файл wp-load.php, – любым из способов, описанных выше, и откройте его в браузере.

Если сертификат в ca-bundle.crt подключен корректно, ошибок в выводе не будет – вы увидите только HTTP-код ответа и строку SSL verification: OK. Если сертификат не подключен или добавлен с ошибкой, wp_remote_get() вернет ошибку cURL error 60: SSL certificate problem: self signed certificate in certificate chain.

Пример вывода:

Пример вывода скрипта проверки сертификата Минцифры для cms wordpess

После проверки удалите оба скрипта с сайта – оставлять на сайте служебные PHP-файлы с диагностической информацией небезопасно.

После того, как сертификат подтвержден скриптом можно проверить работу платежных плагинов на сайте – например, оформить тестовый заказ через нужный способ оплаты.

На каких CMS проверен способ

Способ проверен на сайтах под управлением WordPress, 1С-Битрикс, MODX, Joomla и OpenCart – на них установка проходит по описанному алгоритму (для WordPress – с дополнительным шагом выше).

Даже на этих CMS результат зависит от конкретного сайта. Некоторые плагины и модули устанавливают соединение с внешними сервисами в обход общих настроек, не используя ни php.ini, ни ca-bundle.crt, ни настройки виртуального хоста. В этом случае для отдельного плагина может понадобиться дополнительная настройка – по таким вопросам обращайтесь к разработчикам плагина или разработчикам сайта.

На других CMS могут быть свои особенности работы с сертификатами, как в случае с WordPress.

Заключение

Установка сертификата Минцифры состоит из трех частей: скачать сертификат и определить путь к нему, подключить этот путь в PHP через параметр openssl.cafile, а на WordPress-сайтах – еще и добавить сертификаты в ca-bundle.crt ядра CMS. Подключить openssl.cafile можно самостоятельно, если на сайте включен режим CGI; на mod_php это делает техническая поддержка Beget. Все шаги, которые выполняются самостоятельно, доступны и через SSH, и без консоли – через файловый менеджер или FTP/SFTP-клиент.

Если возникнут вопросы, напишите нам, пожалуйста, тикет из панели управления аккаунта (раздел “Помощь и поддержка”), а если вы захотите обсудить, зачем нужен сертификат Минцифры, с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.