Развертывание центра сертификации (pki-manager)


Развертывание центра сертификации (pki-manager)

Установка

Клонирование репозитория

git clone https://github.com/thecybergardener/pki-manager.git
cd pki-manager

Правка конфигурации

Создаем конфиги из шаблонов

cp openssl.conf.example openssl.conf
cp config.env.example config.env

Вносим правки/ В config.env увеличиваем сроки жизни сертификатов корневого и промежуточного центров сертификации, вносим инфу о локации и компании

diff config.env.example config.env
8,10c8,10
< ROOT_VALIDITY=1460         # 4 years
< INTERMEDIATE_VALIDITY=730  # 2 years
< LEAF_VALIDITY=180          # 6 months
---
> ROOT_VALIDITY=14600         # 40 years
> INTERMEDIATE_VALIDITY=7300  # 20 years
> LEAF_VALIDITY=1800          # 60 months
17,22c17,22
< COUNTRY="US"    # Use 2 letter country code
< STATE="State"
< LOCALITY="City"
< ORGANIZATION="Home"
< ROOT_CN="Root CA"
< INTERMEDIATE_CN="Intermediate CA"
---
> COUNTRY="RU"    # Use 2 letter country code
> STATE="MSK"
> LOCALITY="Moscow"
> ORGANIZATION="Taburetka Inc."
> ROOT_CN="Qiwi Root CA"
> INTERMEDIATE_CN="Qiwi Intermediate CA"

В openssl.conf увеличиваем срок жизни клиентских сертификатов (например 2 или 3 года), разрешаем выпуск нескольких сертификатов для одного домена, и дефолтные значения локации и компании

diff openssl.conf.example openssl.conf
31c31
< default_days      = 1825                   # Default cert validity duration
---
> default_days      = 18250                   # Default cert validity duration
51c51
< default_days      = 365                # 1 years
---
> default_days      = 36500                # 100 years
57c57
< unique_subject    = yes
---
> unique_subject    = no
109,112c109,112
< countryName_default             = US
< stateOrProvinceName_default     = State
< localityName_default            = City
< organizationName_default        = Home
---
> countryName_default             = RU
> stateOrProvinceName_default     = MSK
> localityName_default            = Moscow
> organizationName_default        = Taburetka Inc.

Развертывание центра сертификации

./pki-manager.sh init

На все вопросы отвечаем Y.

[2025-12-06 06:44:49] Creating PKI directory structure
[2025-12-06 06:44:49] Generating root CA key using prime256v1 curve
[2025-12-06 06:44:49] Generating root CA certificate (valid for 14600 days)
[2025-12-06 06:44:49] Generating intermediate CA key using prime256v1 curve
[2025-12-06 06:44:49] Generating intermediate CA CSR
[2025-12-06 06:44:49] Signing intermediate CA certificate (valid for 7300 days)
Using configuration from openssl.conf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'RU'
stateOrProvinceName   :ASN.1 12:'MSK'
localityName          :ASN.1 12:'Moscow'
organizationName      :ASN.1 12:'Taburetka Inc.'
commonName            :ASN.1 12:'Qiwi Intermediate CA'
Certificate is to be certified until Dec  1 03:44:49 2045 GMT (7300 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Database updated
[2025-12-06 06:45:18] Creating certificate chain file
[2025-12-06 06:45:18] Certificate chains created at:
[2025-12-06 06:45:18]   Full chain (root + intermediate): pki/chains/taburetka-inc.-ca-chain.crt
[2025-12-06 06:45:18]   Intermediate chain: pki/chains/taburetka-inc.-intermediate-chain.crt
[2025-12-06 06:45:18] Creating backup at backups/pki_backup_20251206_064518.tar.gz
[2025-12-06 06:45:18] Backup completed successfully
[2025-12-06 06:45:18] PKI initialization complete. Important files:
[2025-12-06 06:45:18]   Root CA: pki/root/certs/ca.crt
[2025-12-06 06:45:18]   Intermediate CA: pki/intermediate/certs/intermediate.crt
[2025-12-06 06:45:18]   Full Chain: pki/chains/ca-chain.crt
[2025-12-06 06:45:18]   Intermediate Chain: pki/chains/intermediate-chain.crt

Готовим корневой и промежуточный сертификаты к распространению

Для удобства делаем симлинки

ln -sv pki/intermediate/certs/intermediate.crt ./intermediate-.home_$(date +%Y.%m.%d-%H%M%S).crt
ln -sv pki/root/certs/ca.crt ./ca-.home_$(date +%Y.%m.%d-%H%M%S).crt

Далее забираем эти 2 сертификата и добавляем в доверенные

sudo cp *.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

На браузеры это не распространяется, нужно или добавлять руками, или погуглить скрипты для автоматизации.

Выпуск сертификата из файла запроса (*.csr)

dom=zbx.home
dt=$(date +%Y-%m-%d_%H-%M-%S)
./pki-manager.sh new-cert $dom-$dt $dom /tmp/request.csr
[2025-12-06 07:38:55] Signing CSR from /tmp/request.csr for service zbx.home-2025-12-06_07-38-55
Using configuration from openssl.conf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 4096 (0x1000)
        Validity
            Not Before: Dec  6 04:38:55 2025 GMT
            Not After : Nov 10 04:38:55 2030 GMT
        Subject:
            countryName               = RU
            stateOrProvinceName       = MSK
            organizationName          = Taburetka Inc.
            organizationalUnitName    = IT
            commonName                = zbx.home
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Server
            Netscape Comment: 
                OpenSSL Generated Server Certificate
            X509v3 Subject Key Identifier: 
                C9:16:DE:5E:1C:69:3D:73:18:50:27:6A:E4:53:FD:F2:50:31:41:1D
            X509v3 Authority Key Identifier: 
                keyid:BD:6F:D5:8C:52:20:B3:DA:28:60:0F:A4:D5:D5:32:C0:1B:41:A8:E3
                DirName:/C=RU/ST=MSK/L=Moscow/O=Taburetka Inc./CN=Qiwi Root CA
                serial:10:00
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
            X509v3 Subject Alternative Name: 
                IP Address:192.168.1.70
Certificate is to be certified until Nov 10 04:38:55 2030 GMT (1800 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Database updated
[2025-12-06 07:39:15] Certificate generated successfully for zbx.home-2025-12-06_07-38-55 from provided CSR
[2025-12-06 07:39:15] Creating backup at backups/pki_backup_20251206_073915.tar.gz
[2025-12-06 07:39:15] Backup completed successfully

Сертификат выпущен и лежит в pki/services/`

ll pki/services/
total 12
drwxr-xr-x 3 root root 4096 Dec  6 07:38 ./
drwxr-xr-x 6 root root 4096 Dec  6 07:38 ../
drwxr-xr-x 3 root root 4096 Dec  6 07:38 zbx.home-2025-12-06_07-38-55/

Наш сертификат:

cat pki/services/$dom-$dt/certs/$dom-$dt.crt 

Скрипт генерации файла запроса сертификата (csr) (первичного ключа)

Выполняется, как правило, на сервере, для которого нужно выпустить сертификат (скрипт стоит положить в отдельную папку)

#!/bin/bash
# v.2025.12.06
# Файлы для хранения ключа и шаблона
KEY_FILE="server.key"
CSR_FILE="server.csr"
CONFIG_FILE="openssl.cnf"

# Функция для отображения справки
function show_help {
    echo "Использование: $0 [опции]"
    echo
    echo "Этот скрипт генерирует SSL-сертификаты."
    echo "При первом запуске он создает ключ и конфигурационный файл."
    echo "При повторном запуске он генерирует запрос на сертификат."
    echo
    echo "Опции:"
    echo "  -h, --help      Показать эту справку и выйти"
    echo
    echo "Пример использования:"
    echo "  ./generate_ssl.sh"
    echo
    echo "После первого запуска следуйте инструкциям на экране для ввода необходимых данных."
}

# Проверка на наличие опции помощи
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
    show_help
    exit 0
fi

# Проверка наличия ключа
if [ ! -f "$KEY_FILE" ]; then
    # Генерация ключа
    openssl genrsa -out "$KEY_FILE" 2048
    echo "Ключ сгенерирован и сохранен в $KEY_FILE."

    # Запрос данных у пользователя
    read -p "Введите страну (C) [RU]: " COUNTRY
    read -p "Введите область (ST) [MSK]: " STATE
    read -p "Введите город (L) [Moscow]: " LOCALITY
    read -p "Введите организацию (O) [Taburetka Inc.]: " ORGANIZATION
    read -p "Введите подразделение (OU) [IT]: " ORG_UNIT
    read -p "Введите адрес электронной почты [mail@example.com]: " EMAIL
    read -p "Введите общее имя (CN) [my.domain.com]: " COMMON_NAME
    read -p "Введите IP-адрес (IP.1) [127.0.0.1]: " IP_ADDRESS

    # Установка значений по умолчанию, если пользователь ничего не ввел
    COUNTRY=${COUNTRY:-RU}
    STATE=${STATE:-MSK}
    LOCALITY=${LOCALITY:-Moscow}
    ORGANIZATION=${ORGANIZATION:-Taburetka Inc.}
    ORG_UNIT=${ORG_UNIT:-IT}
    EMAIL=${EMAIL:-mail@example.com}
    COMMON_NAME=${COMMON_NAME:-my.domain.com}
    IP_ADDRESS=${IP_ADDRESS:-127.0.0.1}

    # Создание конфигурационного файла
    cat <<EOL > "$CONFIG_FILE"
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[dn]
C=$COUNTRY
ST=$STATE
L=$LOCALITY
O=$ORGANIZATION
OU=$ORG_UNIT
emailAddress=$EMAIL
CN=$COMMON_NAME

[req_ext]
subjectAltName = @alt_names

[alt_names]
IP.1 = $IP_ADDRESS
DNS.1 = $COMMON_NAME
EOL

    echo "Конфигурационный файл сгенерирован и сохранен в $CONFIG_FILE."
else
    # Генерация запроса на сертификат
    if [ -f "$CONFIG_FILE" ]; then
        openssl req -new -key "$KEY_FILE" -out "$CSR_FILE" -config "$CONFIG_FILE"
        echo "Запрос на сертификат сгенерирован и сохранен в $CSR_FILE."
    else
        echo "Конфигурационный файл не найден. Пожалуйста, запустите скрипт в первый раз для его создания."
    fi
fi
Поделиться: