Здесь я покажу вам, как можно создать свой центр сертификации и выпускать свои сертификаты для ваших тестовых или внутренних веб серверов.

Введение

Само-подписанные ssl-сертификаты бывают нужны в некоторых случаях:

  • При работе с тестовыми веб-серверами. Когда вам всё равно требуется протокол https. Или не требуется, но вам просто хочется использовать https вместо http. То удобно иметь свой центр сертификации и для каждого тестового сайта выпускать ssl-сертификаты.
  • При работе с внутренними web-серверами. Если у компании есть свой внутренний сайт или веб-приложение. И этот сайт доступен только из внутренней сети компании. То, вероятно, вам захочется использовать протокол https вместо http. А так как доступ к сайту есть у ограниченного числа компьютеров, то на них можно добавить свой корневой ssl-сертификат. И тогда, эти компьютеры начнут доверять внутренним сайтам компании.

Если вы не знаете, что означает доверие к сертификату сайта, то покажу вам следующие скриншоты.

На этом скриншоте, браузер не доверяет сайту, но если нажать на кнопку «Дополнительные«, то вы всё равно сможете перейти на сайт:

Браузер не доверяет сертификату сайта
Браузер не доверяет сертификату сайта

А на этом скриншоте браузер доверяет сайту. Об этом говорит то, что сайт открылся без предупреждений и замочек в адресной строке:

Браузер доверяет сертификату сайта
Браузер доверяет сертификату сайта

В этой статье я проделаю следующее:

  • На Debian 11 установлю apache2 и настрою его работу на https (с сертификатами по умолчанию для localhost).
  • Покажу что клиенты пока не доверяют этому сертификату.
  • Создам центр сертификации на этом же сервере. А именно:
    • создам закрытый корневой ключ и открытый корневой ключ (он же корневой сертификат);
    • с помощью этой пары ключей буду выпускать сертификаты для доменов;
    • установлю выпущенный корневой сертификат на компьютер клиента (на windows);
    • с помощью корневого ключа и сертификата, я выпущу ключ и сертификат для домена (для веб-сервера).
  • Затем я настрою apache2 на использование созданных мною закрытого ключа и сертификата для веб-сервера. И продемонстрирую вам что клиентский браузер начал доверять сертификату сайту.
  • Дальше я установлю и настрою другой веб-сервер — nginx. Настрою его на работу по протоколу https. И продемонстрирую доверие браузера к сайту.

Устанавливаю apache2

Устанавливаю web-сервер apache2:

$ sudo apt install apache2

Настраиваю его работу по протоколу https:

$ sudo a2enmod ssl
$ sudo a2ensite default-ssl.conf
$ sudo systemctl restart apache2

Проверяю доверие к ssl-сертификату сайта, открыв его по https:

Браузер Chrome не доверяет сертификату с которым работает сайт
Браузер Chrome не доверяет сертификату с которым работает сайт

Как видите, доверия нет.

Создаю центр сертификации

Теория

Протокол HTTPS это объединение протоколов HTTP + SSL/TLS. А протокол TLS это асинхронное шифрование. То есть создаётся пара ключей. И то, что один ключ может зашифровать, другой может расшифровать и наоборот. В протоколе HTTPS эти ключи не равнозначные:

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

А ещё протокол TLS позволяет создавать цепочки сертификатов. То-есть, если браузер доверяет родительскому сертификату, то он автоматически будет доверять и всем дочерним сертификатам. А чтобы создать дочернюю пару ключей, нужно иметь доступ к родительской паре ключей.

Корневая пара ключей обычно не подтверждает никакой домен. А используется для создания промежуточных сертификатов или сертификатов для доменов (для web-серверов).

Обычно, когда создают ssl-сертификат для домена, то для безопасности отнимают у него право создания дочерних сертификатов.

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

Сервер на котором создают корневые сертификаты, а затем с их помощью выпускают сертификаты для доменов называют — центр сертификации.

Создаю корневой закрытый ключ

Для создания ssl/tls сертификатов можно использовать утилиту openssl, она не требует админских прав.

Создаю корневой закрытый ключ:

$ openssl genpkey -algorithm RSA -out rootCA.key -aes-128-cbc
   ....................................+++++
   ......................+++++
   Enter PEM pass phrase:
   Verifying - Enter PEM pass phrase:

Разберу эту команду:

  • genpkey — команда для создания закрытого ключа;
  • -algorithm RSA — алгоритм асинхронного шифрования, именно он используется для выделения открытого ключа из этого закрытого;
  • -out rootCA.key — получаемый файл закрытого ключа;
  • -aes-128-cbc — алгоритм симметричного шифрования, которым мы зашифруем файл закрытого ключа с помощью пароля. Пароль нужно будет ввести.

Создаю корневой сертификат

Теперь создаю корневой сертификат (открытый ключ):

$ openssl req -x509 -new -key rootCA.key -sha256 -days 3650 -out rootCA.crt
   Enter pass phrase for rootCA.key:
   You are about to be asked to enter information that will be incorporated
   into your certificate request.
   What you are about to enter is what is called a Distinguished Name or a DN.
   There are quite a few fields but you can leave some blank
   For some fields there will be a default value,
   If you enter '.', the field will be left blank.
   -----
   Country Name (2 letter code) [AU]:RU
   State or Province Name (full name) [Some-State]:Moscow
   Locality Name (eg, city) []:Moscow
   Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sysadminium
   Organizational Unit Name (eg, section) []:.
   Common Name (e.g. server FQDN or YOUR name) []:Sysadminium

Разберу команду:

  • req — создаёт сертификаты или запросы на сертификаты;
  • -x509 — будем создавать сертификат а не запрос;
  • -new — создаём новый сертификат (нужно будет ввести значения некоторых полей в сертификате);
  • -key rootCA.key — используемый закрытый ключ, из которого нужно создать открытый;
  • -sha256 — алгоритм хеширования, чтобы создать подпись ключа;
  • -days 3650 — выпускаем сертификат на 10 лет (обратите внимание что закрытые ключи не имеют срока жизни а сертификаты имеют);
  • -out rootCA.crt — получаемый сертификат.

Итак, я создал пару ключей:

$ ls -l root*
-rw-r--r-- 1 alex alex 1306 сен  9 11:26 rootCA.crt
-rw------- 1 alex alex 1874 сен  9 11:19 rootCA.key

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

Создаю файл порядковых номеров для выпуска сертификатов, в нём следует указать два нуля:

$ nano rootCA.srl
00

Дальше нужно передать корневой сертификат на клиентские компьютеры и установить его в доверенные корневые центры сертификации. Я забираю корневой сертификат по протоколу sftp, показывать этот процесс думаю не нужно.

Установка корневого сертификата на Winows

Устанавливаются сертификаты на Windows очень просто. Дважды щелкаем по сертификату и открывается окно с его свойствами. Дальше нажимаем на кнопку «Установить сертификат«:

Установка сертификата на Windows 10
Установка сертификата на Windows 10

Установить можно для текущего пользователя или для всего компьютера. Так как у меня это тестовая установка, я выберу «Текущий пользователь«:

Установка сертификата на Windows 10 для Текущего пользователя
Установка сертификата на Windows 10 для Текущего пользователя

После нажатия на кнопку «Далее» нужно выбрать «Поместить все сертификаты в следующее хранилище» и нажать кнопку «Обзор«:

Установка сертификата на Windows 10. Выбор хранилища
Установка сертификата на Windows 10. Выбор хранилища

В открывшемся окне выбираем «Доверенные корневые центры сертификации«:

Установка сертификата на Windows 10. Выбор хранилища
Установка сертификата на Windows 10. Выбор хранилища

Затем нажимаем кнопку «ОК«, «Далее» и «Готово«.

И наконец, подтверждаем установку сертификата:

Подтверждение установки корневого сертификата
Подтверждение установки корневого сертификата

И затем нужно будет ещё раз нажать кнопку «ОК«.

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

Просмотр свойств сертификата
Просмотр свойств сертификата

Создаю ключ и сертификат для домена

Теперь, с помощью корневых ключей мы можем создать ключи для домена. У меня будет домен — site.sysadminium.ru.

Утилита openssl не может без конфигурационного файла добавлять некоторые поля. А нам нужно будет в сертификат добавить поле subjectAltName. Без этого поля браузер Chrome не доверяет сертификату.

Поэтому вначале я создаю следующий конфиг:

$ nano sysadminium.cnf
[ req ]
default_bits = 2048
distinguished_name  = req_distinguished_name
req_extensions     = req_ext

[ req_distinguished_name ]
countryName                  = Country Name (2 letter code)
countryName_default          = RU
stateOrProvinceName          = State or Province Name (full name)
stateOrProvinceName_default  = Moscow
localityName                 = Locality Name (eg, city)
localityName_default         = Moscow
organizationName             = Organization Name (eg, company)
organizationName_default     = Sysadminium
commonName                   = Common Name (eg, YOUR name or FQDN)
commonName_max               = 64
commonName_default           = site.sysadminium.ru

[ req_ext ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName          = DNS:site.sysadminium.ru

В блоке [ req ] — настраивается команда req:

  • default_bits = 2048 — длина ключа по умолчанию.
  • distinguished_name = req_distinguished_namedistinguished_name — это поля в сертификате, например Common Name, organizationName и другие. Для этих полей мы создадим блок req_distinguished_name ниже.
  • req_extensions = req_ext — расширение для req, здесь мы можем добавить дополнительные поля в сертификат. А в этом параметре мы просто указываем что ниже будет блок req_ext с дополнительными полями.

Блок [ req_distinguished_name ] — служит для конфигурации полей сертификата.

А блок в блок [ req_ext ] — можно добавить некоторые расширяющие свойства сертификата:

  • basicConstraints = CA:FALSE — полученные сертификаты нельзя будет использовать как центр сертификации. Другими словами, забираем у сертификатов для доменов право создавать дочерние сертификаты.
  • keyUsage = nonRepudiation, digitalSignature, keyEncipherment — созданный ключ будет иметь следующие свойства: неотказуемость (если ключом что-то подписали то аннулировать подпись невозможно), цифровая подпись (сертификат можно использовать в качестве цифровой подписи), шифрование ключей (сертификат можно использовать для симметричного шифрования). Об этих свойствах на английском хорошо написано здесь.
  • subjectAltName = DNS:site.sysadminium.ru — а здесь указываем поле subjectAltName и его значение. Как я уже говорил, без этого поля браузер Chrome не доверяет сертификату.

Создаю закрытый ключ для домена

Теперь я создам закрытый ключ для домена:

alex@deb-11:~$ openssl genpkey -algorithm RSA -out site.key
   .......................................+++++
   .............+++++

Создаю файл запроса для домена

С помощью закрытого ключа для домена создаю файл запроса на сертификат:

$ openssl req -new -key site.key -config sysadminium.cnf -reqexts req_ext -out site.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [Moscow]:
Locality Name (eg, city) [Moscow]:
Organization Name (eg, company) [Sysadminium]:
Common Name (eg, YOUR name or FQDN) [site.sysadminium.ru]:

Обратите внимание, все параметры были использованы из конфига, вручную мне не пришлось ничего вписывать.

Создаю сертификат для домена

Теперь, с помощью корневых ключей, подписываю файл запроса и создаю сертификат для домена:

$ openssl x509 -req -days 730 -CA rootCA.crt -CAkey rootCA.key -extfile sysadminium.cnf -extensions req_ext -in site.csr -out site.crt

Разберу команду:

  • x509 — создание сертификата путём подписывания;
  • -req — если подписывать будем файл запроса, то нужно использовать эту опцию;
  • -days 730 — сертификат я делаю на 2 года;
  • -CA rootCA.crt -CAkey rootCA.key — указываю корневую пару ключей;
  • -extfile sysadminium.cnf — файл, содержащий расширения сертификатов. Без этой опции расширения из файла запроса не попадут в сертификат;
  • -in site.csr -out site.crt — файл запроса и файл сертификата.

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

$ ls -l site.*
-rw-r--r-- 1 alex alex 1257 сен  9 14:27 site.crt # сертификат
-rw-r--r-- 1 alex alex 1098 сен  9 14:17 site.csr # запрос
-rw------- 1 alex alex 1704 сен  9 14:15 site.key # ключ

Перенастраиваю apache2

Кинем сертификат и ключ в следующие каталоги:

$ sudo cp site.crt /etc/ssl/certs/
$ sudo cp site.key /etc/ssl/private/

И настроим apache2 на использование этих ключей:

$ sudo nano /etc/apache2/sites-enabled/default-ssl.conf
   SSLCertificateFile      /etc/ssl/certs/site.crt
   SSLCertificateKeyFile /etc/ssl/private/site.key

Применим изменение конфига apache2:

$ sudo systemctl reload apache2

И проверим как открывается наш сайт с клиента на котором установлен наш корневой сертификат:

Браузер доверяет сертификату сайта
Браузер доверяет сертификату сайта

Как видим, браузер начал доверять нашему тестовому сайту.

Смотрим на сертификат из Chrome

Нажмите на замочек возле адреса сайта (он виден на скриншоте выше). Дальше нажмите на «Безопасное подключение» и на «Действительный сертификат«. Откроются свойства сертификата:

Свойства сертификата из Chrome
Свойства сертификата из Chrome

На вкладке «Подробнее» вы можете изучить и остальные свойства.

Например, помните мы указывали алгоритм ассиметричного шифрования — RSA:

Алгоритм подписи сертификатов
Алгоритм подписи сертификатов

А помните, мы создали файл для серийных номеров выпускаемых сертификатов и записали в нём «00». Давайте посмотрим на серийный номер нашего сертификата:

Серийный номер сертификата
Серийный номер сертификата

Можем посмотреть на сам открытый ключ:

Открытый ключ
Открытый ключ

А в расширениях видно альтернативное имя, которое так нужно браузеру Chrome для доверия к сертификату:

Альтернативное имя
Альтернативное имя

Раньше браузеры проверяли только CN:

Common Name
Common Name

А сейчас, если есть альтернативное имя, то они даже не смотрят в параметр Common Name. А Chrome требует это поле и вообще перестал смотреть на Common Name.

Настраиваю веб-сервер Nginx

Ну и наконец я покажу как настроить Nginx на использование наших сертификатов.

Для начала выключу apache2 и установлю nginx:

$ sudo systemctl stop apache2.service
$ sudo apt install nginx

И настрою его. Нужно рас-комментировать и поменять значения некоторых полей:

$ sudo nano /etc/nginx/sites-enabled/default
   listen 443 ssl default_server;
   listen [::]:443 ssl default_server;
   ssl_certificate     /etc/ssl/certs/site.crt;
   ssl_certificate_key /etc/ssl/private/site.key;

Применю изменения:

$ sudo systemctl reload nginx

И наконец, проверю доверие к ssl-сертификату сайта, обновив страничку в браузере.

Браузер доверяет сертификату сайта
Браузер доверяет сертификату сайта

Здесь apache2 создал свою индексную страничку, поэтому оба веб сервера (nginx и apache2) используют одну и туже страницу. Но как вы помните, я отключил apache2, так что у меня точно отвечает nginx.

Итог

Надеюсь я смог объяснить, как сделать свой центр сертификации и начать выпускать свои собственные сертификаты для доменов. Мы создали следующие файлы:

  • rootCA.key — корневой закрытый ключ. Используется для создания дочерних сертификатов. Обычно лежит на сервере центра сертификации и зашифрован с помощью пароля.
  • rootCA.srl — корневой сертификат. Используется для создания дочерних сертификатов. Его нужно распространить на все ваши компьютеры и установить в хранилище корневых сертификатов. Его тоже можно защитить паролем, но я этого не делал.
  • site.key — ключ для домена (для веб сервера). Его можно было сгенерировать на веб-сервере и не передавать на сервер центра сертификации. Но в моём примере был один сервер и для веб-сервера и для центра сертификации.
  • site.csr — файл запроса на сертификат для домена. Его также можно было сделать на веб-сервере и передать в центр сертификации, чтобы там выпустить сертификат.
  • site.crt — сертификат для домена (для веб сервера). Этот файл создаётся из файла запроса на сертификат с помощью пары корневых ключей.

Также я показал, как использовать созданные сертификаты для настройки веб серверов: apache2 и nginx.

Если вы интересуетесь настройками веб-серверов на Linux, то возможно вам также понравится эта статья:

Сводка
Создаём свой центр сертификации на Linux
Имя статьи
Создаём свой центр сертификации на Linux
Описание
Здесь я покажу вам, как можно создать свой центр сертификации и выпускать свои сертификаты для ваших тестовых или внутренних веб серверов

5 Replies to “Создаём свой центр сертификации на Linux”

  1. Здравствуйте!
    Большое спасибо Вам за материал, многое стало понятно, хоть ничего и не работает в итоге (не доверяет).
    По всей инструкции все действия выполнились успешно.
    Мои отличия от Вашей конфигурации:
    IP-адрес в локальной сети вместо доменного имени, также указал IP в subjectAltName = DNS:IP.
    Срок действия сертификата установил 10 лет, также как и у корневого.
    Сервер Lighttpd, но он так же ест по отдельности ключ и сертификат или все вместе в виде *.pem-файла.
    Браузеры Хром, Опера, FF, в последнем свое хранилище, а не системное, но все равно сертификату не доверяет, может подскажите куда копать?

  2. Простите за беспокойство, проблема решилась subjectAltName = IP:xxx.xxx.x.xx вместо DNS:имя-сайта

    1. Спасибо что ответили как решили проблему, то есть вы заходите на сервер по IP адресу и сертификат принимается?

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *