Построение небольшого центра сертификации на основе OpenSSL

Разбираемся с PKI и создаём простой центр сертификации для веб-сервера на Apache 2
9 минут3650

Разговор о центре сертификации логично начать с PKI — инфраструктуры открытых ключей. Находим определение в Википедии: «PKI — набор средств (технических, материальных, людских и т. д.), распределённых служб и компонентов, в совокупности используемых для поддержки криптозадач на основе закрытого и открытого ключей». Так что к PKI стоит относиться именно как к инфраструктуре, в состав которой входят те или иные компоненты.

По сути, PKI представляет собой систему, которая используется для создания, хранения и распределения цифровых сертификатов. Они, в свою очередь, должны максимально защищённым образом удостоверять, что определённый публичный ключ принадлежит той или иной сущности.

В качестве сущности может выступать пользователь, устройство или что угодно ещё, что можно ассоциировать с тем или иным ключом (процесс, программа, производитель и т. д.). Вот примеры задач, для которых обычно используется PKI:

  • создание сертификатов для привязки публичного ключа к сущности;
  • безопасное хранение сертификатов в репозитории (англ. repository — хранилище);
  • отзыв сертификата (отметка, что сертификату нельзя доверять).

В систему PKI обычно входят:

  • Центр сертификации (англ. Certificate Authority (CA)), которому будет посвящена основная часть этой статьи. Он непосредственно работает с сертификатом — выписывает, хранит, проверяет подлинность. Центр сертификации не следует путать с удостоверяющим центром. Также отдельно рассматривается «корневой центр сертификации» — сторона, чья честность неоспорима, а открытый ключ широко известен. 
  • Регистрационный центр (англ. Registration Authority (RA)). Согласно Википедии, «удостоверяющий центр доверяет регистрационному проверку информации о субъекте». Поэтому часто регистрационный центр полностью или частично объединяют с CA.
  • Сертификат (англ. Certificate) — публичный ключ и идентификаторы сущности, имеющие подпись центра сертификации. В качестве идентификатора может выступать электронная почта пользователя. Если ЦС подписывает набор данных, который состоит из имени пользователя, его публичного ключа и электронной почты, то он как бы гарантирует, что эти данные подлинные. Далее под термином «сертификат» мы будем понимать сертификат стандарта X.509.
  • Certificate Signing Request (CSR). По сути это запрос на подпись сертификата. В запросе обычно указывается сущность, её параметры и публичный ключ. 
  • Certificate Revocation List (CRL), он же список отзывов, или отозванных сертификатов. По этому списку ЦС ведёт учёт «плохих» сертификатов. И если такой сертификат используется, то ЦС не подтвердит к нему доверие. Чаще всего причина — утрата ключей сертификата.

Для базового понимания структуры PKI этого списка достаточно. Теперь рассмотрим, как всё это применяется.

Центры сертификации: как они используются

Задача центра сертификации — подтверждать подлинность ключей шифрования с помощью сертификатов электронной подписи. Логику работы ЦС, как правило, можно описать тезисом «никто не доверяет друг другу, но все доверяют ЦС».

Допустим, условная сущность Аlice имеет сертификат, подписанный ЦС Comp, а сущность Bob пытается проверить подлинность этого сертификата. Проверка будет успешной, если Bob и Alice доверяют одному и тому же ЦС. Для решения такой проблемы в ОС Alice и ОС Bob установлено множество сертификатов различных ЦС.

Установив сертификат ЦС в систему, можно доверять тем сертификатам, которые он подписал. Если сертификат (в частности для HTTPS) выдан, но не подписан каким-нибудь доверенным ЦС, то его называют самоподписанным и он считается недоверенным — если, конечно, не заставить систему доверять такому сертификату.

Здесь могут возникать разные ошибки. Протестировать реакцию браузера на нарушения в работе SSL можно на сайте badssl.com.

Рассмотрим, как браузер реагирует на разные сертификаты. У Firefox, например, для идентификации есть такой набор сертификатов ЦС:

Вот пример с HTTPS. Есть ресурс www.geekbrains.ru, соединение с которым браузер считает доверенным:

Если открыть подробности, то можно увидеть почему:

Браузер считает подключение доверенным потому, что сертификат HTTPS подписан ЦС Comodo CA. Эта организация своим сертификатом подтверждает, что сертификату, выданному для сайта GeekBrains, можно доверять. Получается примерно такая схема:

  • браузер доверяет организации Comodo CA;
  • браузер открывает сайт GeekBrains и видит там сертификат HTTPS, подписанный Comodo CA;
  • браузер считает, что если организация, которой он доверяет, уверена в сайте GeekBrains (они же подтвердили их сертификат), то такое соединение для конечного пользователя можно считать доверенным.

Если коротко, то для успешной проверки доверия (в рамках HTTPS) с использованием центра сертификации необходимо, чтобы:

  • в системе были соответствующие корневые сертификаты ЦС, которые будут использоваться для подтверждения сертификата конкретного сайта;
  • у выданных для сайтов сертификатов не было ошибок.

Не вдаваясь в подробности, отметим, что ошибки могут быть разными. К примеру, если в браузере будет отсутствовать сертификат, который подтверждает подлинность сертификата HTTPS, то соединение автоматически пометится как недоверенное:

Если открыть дополнительные сведения (что я всегда советую делать), то можно подробнее узнать о проблеме. Здесь видно, что на сайте установлен самоподписанный сертификат, то есть не подписанный каким-либо другим сертификатам. Его подлинность нельзя проверить, и соединение считается недоверенным.

Другой пример — сайт wrong.host.badssl.com. Сертификат выдан для другого хоста, о чём и уведомляет браузер:

А вот пример для сайта, у которого истёк срок действия сертификата:

Как проверяется доверие на практике?

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

В Windows сертификаты можно просмотреть через оснастку certmgr.msc:

Если поместить сертификат в хранилище «Доверенные корневые центры сертификации», то такому центру система будет доверять. А поскольку это хранилище корневых центров сертификации, система потом будет доверять и всем объектам, которые подписаны этим сертификатом. 

В ОС Ubuntu Linux сертификаты хранятся в каталоге /etc/ssl/cetrs. Причём часть из них — ссылки на другой объект:

Разворачиваем собственный ЦС

Чтобы лучше понять все процессы, лежащие в основе PKI, рассмотрим на практике развёртывание небольшого ЦС на виртуальной машине под управлением Ubuntu 18 (без выхода в глобальную сеть). Мы не будем жёстко придерживаться правил и стандартов выдачи сертификатов — просто разберём работу с ними.

С учетом того, что. все эксперименты мы проводим в виртуальной среде (без выхода в глобальную сеть), мы можем использовать любое доменное имя — например www.simple.org. Однако надо помнить, что в глобальной сети такое имя вполне может быть зарегистрировано за каким-нибудь сайтом.

Допустим, нам надо настроить веб-сервер так, чтобы соединение к нему шло по протоколу HTTPS и сервер заодно проверял клиента по сертификату. Пользователь у нас один, веб-сервер на Apache 2. Схема нашего центра сертификации будет такой:

Начальные настройки

Сперва заполним файл /root/.rnd, который используется как источник начальных случайных значений в генераторе псевдослучайных чисел OpenSSL. Суть использования этого файла описана на сайте OpenSSL. Нам надо заполнить свой файл случайными данными, как вариант — скопировав из /dev/urandom 32768 байт в файл .rnd таким образом: 

Далее создадим сертификат для CA:

root@shpc:/opt/simple_CA# openssl req -newkey rsa:4096 -keyform PEM -keyout ca.key -x509 -days 3650 -outform PEM -out ca.cer

Опции для сертификата берутся из файла /etc/ssl/openssl.cnf. Сам файл довольно большой, мы не будем приводить здесь его содержимое. В реальности стоит создать свой конфигурационный файл с необходимыми опциями и блоками — и использовать его для генерации сертификатов.

На выходе получим два файла: ключ и сертификат. 

Оба файла надо беречь. Если они попадут к злоумышленнику, он сможет использовать их для генерации сертификатов. Посмотреть сертификат можно при помощи этой команды (вывод обрезан для краткости):

root@shpc:/opt/simple_CA# openssl x509 -text -noout -in ca.cer

Далее на основе полученного сертификата (напомним, что это сертификат корневого CA) можно сгенерировать сертификат для сервера. Вначале генерируем закрытый ключ для сервера:

root@shpc:/opt/simple_CA# openssl genrsa -out server.key 4096

Теперь используем этот ключ для генерации запроса на выдачу сертификата (CSR):

root@shpc:/opt/simple_CA# openssl req -new -key server.key -out server.req -sha256

Отметим, что данные, которые вы вводите в поля, должны совпадать со значениями в тех полях, что указывались при создании сертификата корневого сервера. Теперь возьмём корневой сертификат CA и запрос — и сгенерируем на их основе сертификат для сервера:

root@shpc:/opt/simple_CA# openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key -set_serial 100 -extensions server -days 1460 -outform PEM -out server.cer -sha256 

Должно получиться 5 файлов.

Файл server.req можно удалить — а при необходимости создать заново. Теперь надо перенастроить веб-сервер для работы с сертификатами.

Настройка Apache 2 для использования сертификатов

Переходим в каталог /etc/apache2:

root@shpc:/mnt# cd /etc/apache2/

Создаём каталог для хранения сертификатов:

root@shpc:/etc/apache2# mkdir ssl

Включаем модуль SSL для веб-сервера. Тестирование проводилось на ОС Ubuntu Linux, поэтому модуль достаточно просто включить:

a2enmod headers

Перезапускаем веб-сервер:

root@shpc:/etc/apache2# systemctl restart apache2

Аналогично нужно включить поддержку заголовков: 

Теперь создадим конфигурационный файл для модуля SSL. Пример содержимого для него можно взять на Syslink.pl. Команды такие:

root@shpc:/mnt# cd /etc/apache2/conf-available
root@shpc:/etc/apache2/conf-available# nano ssl-params.conf

Сам файл будет содержать следующие параметры (чтобы было проще работать, мы отключили заголовки Strict-Transport-Securrity, X-Frame-Options и X-Content-Type-Options):

Далее созданный конфиг надо активировать:

root@shpc:/etc/apache2/conf-available# a2enconf ssl-params

Теперь переходим в каталог /etc/apache2/sites-available:

root@shpc:/etc/apache2/conf-available# cd /etc/apache2/sites-available

И делаем на всякий случай резервные копии всех хранящихся там файлов:

root@shpc:/etc/apache2/sites-available# cp 000-default.conf 000-default.conf.bak
root@shpc:/etc/apache2/sites-available# cp default-ssl.conf default-ssl.conf.bak

Теперь ещё раз проверяем подключённые модули headers и SSL:

Далее нам надо перенести созданные сертификаты (сертификат CA и сертификат сервера) в каталог /etc/ssl/certs, а ключ сертификата сервера — в каталог /etc/ssl/private:

root@shpc:/opt/simple_CA# cp ca.cer /etc/ssl/certs/
root@shpc:/opt/simple_CA# cp server.cer /etc/ssl/certs/server.crt
root@shpc:/opt/simple_CA# cp server.key /etc/ssl/private/server.key

Далее откроем конфиг сайта (/etc/apache2/sites-available/000-default-ssl.conf) и добавим туда следующие опции:

SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
SSLCACertificateFile /etc/ssl/certs/ca.cer

Теперь перезагружаем веб-сервер:

root@shpc:/etc/apache2# a2ensite default-ssl
root@shpc:/etc/apache2/sites-available# service apache2 restart

Проверяем доступность сайта:

Видим, что Firefox не может проверить сертификат сайта. Чтобы смог, надо импортировать цепочку сертификатов, подтверждающих сертификат сервера, в список доверенных. Создадим цепочку:

root@shpc:/opt/simple_CA# openssl crl2pkcs7 -nocrl -certfile ca.cer -certfile server.cer -out serve-and-ca-chain.p7c -outform der

У полученного файла не забываем сменить атрибуты на 555:

root@shpc:/opt/simple_CA# chmod 555 serve-and-ca-chain.p7c 

Теперь откроем в браузере менеджер сертификатов и импортируем полученную цепочку (кнопка Import):

Далее можно просмотреть сертификаты и настроить доверие — вдруг что-то упущено:

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

Сейчас время настроить аутентификацию для клиентов. 

Настройка аутентификации клиентов

Веб-сервер Apache поддерживает аутентификацию клиента. Это значит, что мы можем выписать клиенту сертификат SSL, а сервер сможет его проверить. Если у пользователя не будет сертификата — аутентификация не пройдёт. Для активации такой возможности надо добавить в конфиг default-ssl.conf такие опции:

SSLCACertificateFile /opt/simple_CA/ca.cer 
SSLVerifyClient require 
SSLVerifyDepth 2

После этого к сайту сможет подключиться только тот пользователь, сертификат которого:

  • установлен в браузере, если клиентом является браузер, — тогда сертификат будет предъявлен при подключении к серверу;
  • подписан сертификатом доверенного УЦ.

Сначала сгенерируем сертификат для клиента. Первым делом создаём ключ:

root@shpc:/opt/simple_CA# openssl genrsa -out client.key 4096 

Затем на основе ключа сгенерируем CSR:

root@shpc:/opt/simple_CA# openssl req -new -key client.key -out client.req

Теперь на базе запроса сгенерируем сам сертификат:

root@shpc:/opt/simple_CA# openssl req -new -key client.key -out client.req

И импортируем сертификат в формате p12:

root@shpc:/opt/simple_CA# openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12 

В итоге у нас должен получиться файл client.p12. Нужно поменять права на файл, иначе сертификат не импортируется:

root@shpc:/opt/simple_CA# chmod 555 client.p12

Теперь можно импортировать его в браузер по аналогии с корневыми сертификатами:

После импорта должно получиться примерно так:

После этого перезапускаем веб-сервер и возвращаемся на сайт. Видим окно выбора сертификата того пользователя, которого мы импортировали в браузер:

После выбора сертификата пользователя можно успешно зайти на сайт:

В этой статье мы рассмотрели сборку простейшего ЦС. Его сертификат мы использовали для подтверждения других сертификатов, обеспечив таким образом доверие между всеми участниками. Но в собранной нами системе есть пара существенных недостатков:

  • если пользователей будет больше одного, то мы столкнёмся с проблемами при учёте выдаваемых сертификатов;
  • при настройке ЦС стоит грамотно выбирать параметры для используемых сертификатов, а для этого нужен свой конфигурационный файл.

Но если необходимо обеспечить защиту информации в пределах локальной сети, то подобный ЦС будет интересным и грамотным решением.

Напоследок предлагаю ряд полезных материалов для изучения:

Источники, которые использовались при подготовке статьи: 

Хотите в подробностях изучить работу центров сертификации и другие вопросы информационной безопасности? Тогда приглашаем вас на факультет GeekUniversity!

Сентябрь — отличное время, чтобы построить далеко идущие планы и начать идти к новым целям! Если вы хотите освоить профессию мечты, то с 22 по 31 сентября 2020 г. мы дарим вам скидку 40% почти на все программы обучения GeekBrains. Успехов! :)

 

программированиеsecurity
Нашли ошибку в тексте? Напишите нам.
Спасибо,
что читаете наш блог!
Posts popup