Свой центр сертификации - openssl
Введение
Причины использовать само-подписанные ssl-сертификаты:
- При работе с тестовыми веб-серверами. Когда вам требуется протокол https. Удобно иметь свой центр сертификации и для каждого тестового сайта выпускать сертификаты.
- При работе с внутренними web-серверами. Например у компании есть внутренний сайт, доступный только из внутренней сети. Здесь также необходимо использовать https. Так как доступ к сайту есть у ограниченного числа сотрудников, то на их устройства можно добавить свой корневой ssl-сертификат. И эти устройства начнут доверять внутреннему сайту компании.
На этом скриншоте, браузер не доверяет сайту, но если нажать на кнопку Дополнительные, то вы всё равно сможете перейти на сайт:

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

В этой статье я проделаю следующее:
- На Debian 11 установлю apache2 и настрою его работу на https (с сертификатами по умолчанию для localhost).
- Покажу что клиенты пока не доверяют этому сертификату.
- Создам центр сертификации на этом же сервере. А именно:
- создам закрытый корневой ключ и открытый корневой ключ (он же корневой сертификат);
- установлю выпущенный корневой сертификат на компьютер клиента (windows);
- с помощью корневого ключа и сертификата, выпущу ключ и сертификат для домена (для веб-сервера).
- Затем я настрою apache2 на использование созданных мною закрытого ключа и сертификата для веб-сервера. И продемонстрирую вам что клиентский браузер начал доверять сертификату сайта.
- Дальше я установлю и настрою другой веб-сервер — nginx. Настрою его на работу по протоколу https. И продемонстрирую доверие браузера к сайту.
Теория
Протокол HTTPS - это объединение протоколов HTTP + SSL/TLS, протокол TLS - это асинхронное шифрование. То есть создаётся пара ключей. И то, что один ключ может зашифровать, другой может расшифровать и наоборот. В протоколе HTTPS эти ключи не равнозначные:
- закрытый ключ — это обычный ключ шифрования применяемый в асинхронном шифровании.
- открытый ключ — это тоже ключ шифрования. Но он дополнительно содержит некоторую информацию, например имя домена, имя организации и другое. Такой ключ называют сертификатом.
А ещё протокол TLS позволяет создавать цепочки сертификатов. То-есть, если браузер доверяет родительскому сертификату, то он автоматически будет доверять и всем дочерним сертификатам. А чтобы создать дочернюю пару ключей, нужно иметь доступ к родительской паре ключей.
Корневая пара ключей обычно не подтверждает никакой домен. А используется для создания промежуточных сертификатов или сертификатов для доменов (для web-серверов).
Обычно, когда создают ssl-сертификат для домена, то для безопасности отнимают у него право создания дочерних сертификатов.
Корневой ключ обычно защищают паролем. Это уже симметричное шифрование, когда зная один ключ (пароль) можно зашифровать и расшифровать файл закрытого ключа.
Сервер на котором создают корневые сертификаты, а затем с их помощью выпускают сертификаты для доменов называют — центр сертификации.
Устанавливаю apache2
Устанавливаю:
$ sudo apt install apache2
Настраиваю его работу по протоколу https:
$ sudo a2enmod ssl
$ sudo a2ensite default-ssl.conf
$ sudo systemctl restart apache2
Проверяю доверие к ssl-сертификату сайта, открыв его по https:

- Как видите, доверия нет.
Создание центра сертификации
Создание корневого закрытого ключа
Для создания 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
Дальше нужно передать корневой сертификат на клиентские компьютеры и установить его в доверенные корневые центры сертификации.
Установка корневого сертификата на Winows
Установить сертификаты на Windows очень просто. Дважды щелкаем по сертификату, открывается окно с его свойствами. Дальше нажимаем на кнопку Установить сертификат:

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

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

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

Затем нажимаем кнопку ОК, Далее и Готово. И наконец, подтверждаем установку сертификата:

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

Подготовка конфига для создания ключей для домена
Теперь, с помощью корневых ключей мы можем создать ключи для домена. У меня будет домен — 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_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 и его значение. Как я уже говорил, без этого поля браузер не доверяет сертификату.
Создание закрытого ключа и сертификата для домена
Теперь создадим закрытый ключ для домена:
$ 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
Применим изменения:
$ sudo systemctl reload apache2
Проверим как открывается наш сайт с устройства на котором установлен корневой сертификат:

- Браузер начал доверять тестовому сайту.
Смотрим на сертификат из Chrome
Нажмите на замочек возле адреса сайта. Дальше нажмите на Безопасное подключение / Действительный сертификат. Откроются свойства сертификата:

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

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

А в расширениях видно альтернативное имя:

Настраиваем веб-сервер 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.
Если понравилась статья, подпишись на мой канал в VK или Telegram .