Двухуровневая PKI-инфраструктура на базе OpenSSL
Поддерживает:
- Создание корневого и промежуточного центров сертификации
- Выпуск клиентских сертификатов: веб, почта, Active Directory, VPN, долгосрочные сервисы
- Отзыв сертификатов
- Генерацию CRL (списков отзыва)
- Импорт существующих PKI-файлов
- Выгрузку CRL по FTP
⚠️ Все секретные данные (
private/
, ключи, пароли) исключены из системы контроля версий через.gitignore
.
📁 Структура проекта
├── /scripts │ ├── init_pki.sh # Инициализация инфраструктуры │ ├── create_root_ca.sh # Создание корневого ЦС │ ├── create_intermediate_ca.sh # Создание промежуточного ЦС │ ├── issue_web_cert.sh # Выпуск веб-сертификатов │ ├── issue_mail_cert.sh # Выпуск почтовых сертификатов │ ├── issue_ad_cert.sh # Для Active Directory │ ├── issue_longterm_service.sh # Для NAS, Proxmox, TrueNAS и т.д. │ ├── issue_vpn_cert.sh # Для OpenVPN/WireGuard │ ├── revoke_cert.sh # Отзыв любого сертификата │ ├── generate_root_ca_crl.sh # Обновление CRL корневого ЦС │ ├── generate_intermediate_ca_crl.sh # Обновление CRL промежуточного ЦС │ ├── upload_crl.sh # Выгрузка CRL по FTP │ └── check_cert_uniqueness.sh # Проверка уникальности перед выпуском │ ├── /root-ca-ssl # Корневой ЦС (генерируется автоматически) ├── /intermediate-ca-ssl # Промежуточный ЦС (генерируется автоматически) ├── /live # Временные файлы при работе ├── pki_config.cfg # Конфигурация инфраструктуры ├── pki_status.cfg # Флаг инициализации └── .gitignore # Защита конфиденциальных данных
⚠️ Важно поместить исходные файлы вашей будущей инфраструктуры сразу в ту директорию на диске, где она и будет расположена в итоге
🛠 Требования
- Linux (Debian/Ubuntu/CentOS и др.)
- Bash
- OpenSSL
- Утилиты:
curl
илиftp
, если используется выгрузка по FTP
🧪 Быстрое начало
1. Инициализация PKI-инфраструктуры
./scripts/init_pki.sh
При инициализации будет предложено ввести:
- Путь к рабочему каталогу инициализируемой PKI-инфраструктуры
- Доменное имя вашей организации, которое станет базовым для именования сертификатов корневного и промежуточного ЦС
- Наименование компании, которое может быть использовано в полях Common Name серфтикатов корневого и промежуточного ЦС
- Данные о стране, регионе, населенном пункте, подразделении, адресе электропочты
- Срок действия сертификата корневого ЦС (указывается количество лет)
- Срок действия сертификата промежуточного ЦС (указывается количество лет), не может превышать половину от срока действия сертификата корневого ЦС
После этого потребуется указать, какие типы клиентских сертификатов потребуется выпускать. На настоящий момент поддерживается шесть типов выпускаемых клиентских сертификатов:
- сертификаты подчиненных промежуточному (сторонних) центров сертификации;
- сертификаты центров сертификации Active Directory;
- сертификаты долгосрочных сервисов и служб (системы видеонаблюдения, гипервизоры, NAS, SQL и другие);
- сертификаты веб-сайтов;
- сертификаты почтовых серверов и служб;
- сертификаты VPN-серверов и сертификаты для авторизации VPN-клиентов.
Узлы распространения сертификатов ЦС и узлы публицакии списков отзыва
Если вы планируете публиковать сертификаты корневого и промежуточного центров сертификации в интернете, а также будете публиковать списки отзывов, необходимо указать URL таких узлов. Например, если ваш сайт будет расположен по адресу http://pki.domain.ru, а списки отзыва для скачивания будут размещены на сервере в каталоге crl, то на вопрос об узлах распространения следует ответить так: http://pki.domain.ru/crl/
Если таких сайтов у вас более одного, можете указать каждый из последующих при следующем вводе.
Аналогично следует указывать и адреса для распространения сертификатов корневого и промежуточного ЦС.
Автоматическая выгрузка по FTP
Если хотите, списки отозванных сертификатов после генерации будут автоматически выгружаться по FTP на ваш сервер. Для этого потребуется указать адрес сервера, порт, логин и пароль для подключения. Потребуется указать и путь выгрузки. Если ftp-пользователь после подключения уже попадает в корневой каталог, в котором находятся ваши каталоги certs и crl, тогда путь укажите просто: /
Можно автоматически выгружать списки отозванных сертификатов после их генерации.
📥 Импорт вашей существующей двухуровневой PKI-инфраструктуры
Если у вас уже имеется двухуровневая PKI-инфраструктура, вы можете импортировать её основные файлы в инициируемую. Для этого потребуется создать где-то на диске каталог import, и поместить в него файлы закрытых ключей центров сертификации, самих сертификтов ЦС, файлов index.txt, crlnumber, serial.
В файлах *.passphrase.txt вам потребуется указать пароль закрытого ключа для соответствующего ЦС.
import/ ├── root-ca/ │ ├── private/ │ │ ├── root-ca.example.ru.key │ │ └── root-ca.example.ru.passphrase.txt │ ├── certs/ │ │ └── root-ca.example.ru.crt │ ├── index.txt │ ├── serial │ └── crlnumber └── intermediate-ca/ ├── private/ │ ├── intermediate-ca.example.ru.key │ └── intermediate-ca.example.ru.passphrase.txt ├── certs/ │ └── intermediate-ca.example.ru.crt ├── csr/ ├── index.txt ├── serial └── crlnumber
Вам будет предложено сразу же выпустить сертификаты корневого промежуточного центров сертификации, если вы не указали необходимость импорта существуюей инфраструктуры.
После этого в каталоге вашей инфраструктуры появятся файлы и папки для её использования.
- 📁 root-ca-ssl — каталог корневого центра сертификации.
- 📁 intermediate-ca-ssl — каталог промежуточного центра сертификации.
- ⚙️ pki_config.cfg — файл с основными параметрами вашей PKI-инфраструктуры.
- 📄 pki_status.cfg — файл-маркер статуса инициализации вашей PKI-инфраструктуры
📁 scripts — каталог служебных скриптов останется там же, где и был.
Службные скрипты PKI-инфраструктуры
В каталоге 📁 scripts расположены важные служебные скрипты для вашей инфраструктуры.
Скрипт | Назначение |
---|---|
create_root_ca_config.sh | Создание файла конфигурации корневого центра сертификации |
create_root_ca.sh | Выпуск сертификата корневого центра сертификации |
create_intermediate_ca_config.sh | Создание файла конфигурации промежуточного центра сертификации |
create_intermediate_ca.sh | Выпуск сертификата промежуточного центра сертификации |
init_client_configs.sh | Инициализация конфигурационных файлов openssl для выпуска клиентских сертификатов |
import_pki.sh | Импорт существующей двухуровневой PKI-инфраструктуры |
upload_crl.sh | Выгрузка сертификатов корневного и промежуточного ЦС, их списков отзыва на удаленный сервер для публикации |
Для выпуска клиентских сертификатов используйте скрипты
Скрипт | Назначение |
---|---|
issue_ad_cert.sh | Для серфтикатов Центров сертификации Active Directory |
issue_longterm_service.sh | Для сертификатов различных долговременных сервисов и служб |
issue_mail_cert.sh | Для сертификатов почтовых серверов им служб |
issue_sub_ca.sh | Для сертификатов сторонних центров сертификации, подчиненных вашему промежуточному ЦС |
issue_vpn_cert.sh | Для сертификатов VPN-серверов и авторизации VPN-клиентов |
issue_web_cert.sh | Для сертификатов веб-сайтов |
⚠️ Скрипты выпуска клиентских сертификатов в итоге создают:
- файл закрытого ключа;
- csr-файл запроса на выпуск сертификата;
- файл открытого ключа;
- файл цепочки сертификации;
- сертификат-контерйнер в формате PKCS#12;
- архив tar.gz со всеми перечисленными файлами.
Предположим, что ваша PKI-инфраструктура размещена на диске в каталоге /opt/openssl
# Переходим в каталог инфраструктуры
cd /opt/openssl
# Выпускаем сертификат для веб-сайта
./scripts/issue_web_cert.sh
=== Выпуск сертификата для веб-сайта ===
1) Введите основное доменное имя сайта (например: example.com): www.example.com
2) Введите Common Name для сертификата [www.example.com]: Main WEB-Site Company ltd
3) Укажите срок действия в днях (по умолчанию 365): 730
4) Страна [RU]:
5) Регион/Область [Moscow]:
6) Город [Moscow]:
7) Название компании [Company ltd]:
8) Подразделение [IT dep]:
9) Email [admin@example.com]:
10) Пароль закрытого ключа (оставьте пустым, если не нужен):
Укажите дополнительные доменные имена для SAN (через пробел, Enter для пропуска):
example.com test.example.com copy.example.com 192.168.0.1
Генерация закрытого ключа...
Generating RSA private key, 2048 bit long modulus (2 primes)
....................+++++
............+++++
e is 65537 (0x010001)
Создание запроса на подпись (CSR)...
Подготовка SAN конфигурации...
Подписание сертификата...
Создание цепочки сертификатов...
Создание PKCS12 архива...
Введите пароль для PKCS12-контейнера:
Сохранение сертификата...
Архив успешно создан:
/opt/openssl/intermediate-ca-ssl/certs/web_certs/www.example.com-20250605/www.example.com.tar.gz
-rw-rw-r-- 1 user user 15K Jun 5 13:59 /opt/openssl/intermediate-ca-ssl/certs/web_certs/www.example.com-20250605/www.example.com.tar.gz
=== Сертификат успешно создан ===
Файлы в каталоге: /opt/openssl/intermediate-ca-ssl/certs/web_certs/www.example.com-20250605
total 48K
-rw-r--r-- 1 user user 6.9K Jun 5 13:59 www.example.com-chain.crt
-rw-r--r-- 1 user user 2.4K Jun 5 13:59 www.example.com.crt
-rw-r--r-- 1 user user 1.1K Jun 5 13:59 www.example.com.csr
-rw-r--r-- 1 user user 1.7K Jun 5 13:59 www.example.com.key
-rw-r--r-- 1 user user 8.4K Jun 5 13:59 www.example.com.p12
-rw-rw-r-- 1 user user 15K Jun 5 13:59 www.example.com.tar.gz
Архив:
/opt/openssl/intermediate-ca-ssl/certs/web_certs/www.example.com-20250605/www.example.com.tar.gz
Размер: 16K
Детали сертификата:
Issuer: C = RU, ST = Moscow, L = Moscow, O = Company ltd, OU = IT dep, CN = Company Intermediate CA, emailAddress = admin@example.com
Not Before: Jun 5 10:59:16 2025 GMT
Not After : Jun 5 10:59:16 2027 GMT
Subject: C = RU, ST = Moscow, L = Moscow, O = Company, OU = IT dep, CN = Main WEB-Site Company ltd
DNS:www.example.com, DNS:example.com, DNS:test.example.com, DNS:copy.example.com, DNS:192.168.0.1
Отзыв сертификатов
Для отзыва сертификатов необходимо использовать скрипт revoke_cert.sh, которому нужно передать часть Common Name сертификата, но надёжнее будет указать серийный номер отзываемого сертификата
# Переходим в каталог инфраструктуры
cd /opt/openssl
# Получаем информацию о сертификатах, выпущенных промежуточным ЦС
cat ./intermediate-ca-ssl/index.txt | grep WEB-Site
V 270605105916Z 169679B8A05193B34FE63AC065CF302703B7A70C unknown /C=RU/ST=RO/L=Tag/O=LEZH/OU=HOME/CN=Main WEB-Site Company ltd
# Отзываем сертификат по серийному номеру
./scripts/revoke_cert.sh 169679B8A05193B34FE63AC065CF302703B7A70C
Далее остается выбрать найденный сертификат, указать причину отзыва, и подтвердить отзыв.
Если это предусмотрено конфигурацией инфраструктуры, скрипт отзыва после генерации нового списка отозванных сертификатов по FTP отправит их на сервер для публикации.
Через cron можно задать периодическую генерацию новых списков отозванных сертификатов
# Открываем редактор заданий cron
crontab -e
Оба скрипта генерации списков отозванных сертификатов умеют выгружать их по FTP на удаленный сервер, если такая необоходимость задана в конфигурации PKI-инфраструктуры
00 2 * * * /opt/openssl/scripts/generate_intermediate_ca_crl.sh > /dev/null
05 2 * * * /opt/openssl/scripts/generate_root_ca_crl.sh > /dev/null