You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/bin/bash
# Этот скрипт автоматизирует процесс создания инфраструктуры центра сертификации (ЦС),
# включая создание директорий, генерацию ключей и сертификатов,
# а также настройку конфигурационных файлов для корневого и промежуточного ЦА.
#
# Скрипт выполняет следующие основные действия:
# 1. Создает необходимые директории для хранения сертификатов, ключей и других файлов ЦС.
# 2. Генерирует RSA ключи для корневого и промежуточного ЦА с шифрованием AES-256.
# 3. Создает самоподписанный корневой сертификат и CSR (Certificate Signing Request)
# для промежуточного ЦА.
# 4. Подписывает сертификат промежуточного ЦА корневым ЦА.
# 5. Создает цепочку сертификатов, включающую корневой и промежуточный сертификаты.
# 6. Проверяет целостность созданного сертификата промежуточного ЦА с помощью корневого ЦА.
#
# Для использования скрипта рекомендуется запускать его с правами суперпользователя (root),
# так как он создает файлы и директории в защищенных системных папках.
#set -e
#trap 'echo "Error: Script execution failed"; exit 1' ERR
source ./config.sh
# Detect language and define error function
LANGUAGE="en"
if [[ "$LANG" == ru* || "$LANG" == *ru_* || "$LC_ALL" == ru* || "$LC_ALL" == *ru_* ]]; then
LANGUAGE="ru"
fi
msg() {
local en_msg="$1"
local ru_msg="$2"
if [[ "$LANGUAGE" == "ru" ]]; then
echo "$ru_msg"
else
echo "$en_msg"
fi
exit 1
}
# Проверка переменной VAL_DAYS
if [[ -z "$VAL_DAYS" || ! "$VAL_DAYS" =~ ^[0-9]+$ || "$VAL_DAYS" -le 0 ]]; then
msg "Error: VAL_DAYS must be a positive integer" "Ошибка: Переменная VAL_DAYS должна быть положительным целым числом"
fi
if ! mkdir -m 700 "$PATH_TO_CA"; then
msg "Error: Failed to create directory $PATH_TO_CA" "Ошибка: Не удалось создать директорию $PATH_TO_CA"
fi
# Перейти в директорию CA или выйти с ошибкой, если это не удалось
cd "$PATH_TO_CA" || { msg "Error: Failed to change directory to $PATH_TO_CA" "Ошибка: Не удалось перейти в каталог $PATH_TO_CA"; }
# Список каталогов, для которых создается структура
DIRECTORIES=("root" "intermediate")
# Создание необходимых директорий и настройка их прав доступа
for dir in "${DIRECTORIES[@]}"; do
# Создание поддиректорий в каждой директории из списка
mkdir -p "$dir/certs" "$dir/crl" "$dir/newcerts" "$dir/private" "$dir/csr"
chmod 700 "$dir/private"
# Создание файлов базы CA
touch "$dir/index.txt"
echo -n 100000 >"$dir/serial"
# Настройка файла для CRL (список отозванных сертификатов)
echo -n 100000 >"$dir/crlnumber"
done
# Создание конфигурационного файла для корневого ЦА
cat >root/sertissuer.conf <<EOL
[ca]
default_ca=CA_default
[CA_default]
dir = $ROOT_CA
certs = \$dir/certs
crl_dir = \$dir/crl
database = \$dir/index.txt
new_certs_dir = \$dir/newcerts
serial = \$dir/serial
certificate = \$dir/certs/ca.cert.pem
private_key = \$dir/private/ca.key.pem
crlnumber = \$dir/crlnumber
crl = \$dir/crl/ca.crl.pem
crl_extensions = crl_ext
default_crl_days = 30
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = $VAL_DAYS
preserve = no
policy = policy_strict
[policy_strict]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[req]
default_bits = 4096
default_md = sha256
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
string_mask = utf8only
x509_extensions = v3_ca
prompt = no
[req_distinguished_name]
countryName = $COUNTRY_NAME
organizationName = $ORG_NAME
commonName = $ORG_NAME
[v3_ca]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, keyCertSign, cRLSign
[v3_inter]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, keyCertSign, cRLSign
[crl_ext]
authorityKeyIdentifier = keyid:always
EOL
# Перейти в директорию корневого ЦА или выйти с ошибкой, если это не удалось
pushd "$ROOT_CA" || { msg "Error: Failed to change directory to $ROOT_CA" "Ошибка: Не удалось перейти в каталог $ROOT_CA"; }
# Генерация RSA ключа для корневого ЦА с шифрованием AES-256
openssl genrsa -aes256 -out private/ca.key.pem -passout "pass:$SERT_PASS" 4096 || { msg "Error: Failed to generate RSA key for root CA" "Ошибка: Не удалось создать RSAключ для корневого ЦА"; }
# Установка прав доступа для ключа корневого ЦА
chmod 400 private/ca.key.pem
# Создание самоподписанного сертификата корневого ЦА
openssl req -config sertissuer.conf -key private/ca.key.pem -new -x509 -days "$VAL_DAYS" -sha256 -extensions v3_ca -out certs/ca.cert.pem -passin "pass:$SERT_PASS" || { msg "Error: Failed to create root CA certificate" "Ошибка: Не удалось создать сертификат корневого ЦА"; }
# Установка прав доступа для сертификата корневого ЦА
chmod 444 certs/ca.cert.pem
# Отображение деталей сертификата корневого ЦА
openssl x509 -noout -text -in certs/ca.cert.pem || { msg "Error: Failed to display root CA certificate details" "Ошибка: Не удалось вывести детали сертификата корневого ЦА"; }
# Вернуться в исходную директорию или выйти с ошибкой, если это не удалось
popd || { msg "Can't return to old directory" "Невозможно вернуться к старому каталогу"; }
# Создание конфигурационного файла для промежуточного ЦА
cat >intermediate/immissuer.conf <<EOL
[ca]
default_ca=CA_default
[CA_default]
dir = $IMM_CA
certs = \$dir/certs
crl_dir = \$dir/crl
database = \$dir/index.txt
new_certs_dir = \$dir/newcerts
serial = \$dir/serial
certificate = \$dir/certs/intermediate.cert.pem
private_key = \$dir/private/intermediate.key.pem
crlnumber = \$dir/crlnumber
crl = \$dir/crl/intermediate.crl.pem
crl_extensions = crl_ext
default_crl_days = 7
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 825
preserve = no
policy = policy_loose
[policy_loose]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[req]
default_bits = 4096
default_md = sha256
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
string_mask = utf8only
x509_extensions = v3_intermediate_ca
prompt = no
[req_distinguished_name]
countryName = $COUNTRY_NAME
organizationName = $ORG_NAME
commonName = $ORG_NAME
[v3_intermediate_ca]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, keyCertSign, cRLSign
[server_cert]
basicConstraints = CA:false
nsCertType = server
nsComment = "$COMM_NAME TLS server cert"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[client_cert]
basicConstraints = CA:false
nsCertType = client
nsComment = "Brepo client cert"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
[crl_ext]
authorityKeyIdentifier = keyid:always
EOL
# Перейти в директорию промежуточного ЦА или выйти с ошибкой, если это не удалось
pushd "$IMM_CA" || { msg "Error: Failed to change directory to $IMM_CA" "Ошибка: Не удалось перейти в каталог $IMM_CA"; }
# Генерация RSA ключа для промежуточного ЦА с шифрованием AES-256
openssl genrsa -aes256 -out private/intermediate.key.pem -passout "pass:$SERT_PASS" 4096 || { msg "Error: Failed to generate RSA key for intermediate CA" "Ошибка: Не удалось создать RSAключ для промежуточного ЦА"; }
# Установка прав доступа для ключа промежуточного ЦА
chmod 400 private/intermediate.key.pem
# Создание CSR для промежуточного ЦА
openssl req -config immissuer.conf -new -sha256 -key private/intermediate.key.pem -out csr/intermediate.csr.pem -passin "pass:$SERT_PASS" || { msg "Error: Failed to create CSR for intermediate CA" "Ошибка: Не удалось создать запрос на сертификат для промежуточного ЦА"; }
# Вернуться в исходную директорию или выйти с ошибкой, если это не удалось
popd || { msg "Can't return to old directory" "Невозможно вернуться к старому каталогу"; }
# Перейти в директорию корневого ЦА или выйти с ошибкой, если это не удалось
pushd "$ROOT_CA" || { msg "Error: Failed to change directory to $ROOT_CA" "Ошибка: Не удалось перейти в каталог $ROOT_CA"; }
# Подпись сертификата промежуточного ЦА корневым ЦА
openssl ca -batch -config sertissuer.conf -extensions v3_inter -days 3550 -notext -md sha256 -in $IMM_CA/csr/intermediate.csr.pem -out $IMM_CA/certs/intermediate.cert.pem -passin "pass:$SERT_PASS" || { msg "Error: Failed to sign intermediate CA certificate" "Ошибка: Не удалось подписать сертификат промежуточного ЦА корневым ЦА"; }
# Установка прав доступа для сертификата промежуточного ЦА
chmod 444 $IMM_CA/certs/intermediate.cert.pem
openssl ca -config "sertissuer.conf" -gencrl -out crl/ca.crl.pem -passin "pass:$SERT_PASS"
# Вернуться в исходную директорию или выйти с ошибкой, если это не удалось
popd || { msg "Can't return to old directory" "Невозможно вернуться к старому каталогу"; }
# Перейти в директорию промежуточного ЦА или выйти с ошибкой, если это не удалось
pushd "$IMM_CA" || { msg "Error: Failed to change directory to $IMM_CA" "Ошибка: Не удалось перейти в каталог $IMM_CA"; }
openssl ca -config "immissuer.conf" -gencrl -out crl/intermediate.crl.pem -passin "pass:$SERT_PASS"
cat $ROOT_CA/crl/ca.crl.pem $IMM_CA/crl/intermediate.crl.pem >$IMM_CA/crl/ca-full.crl.pem
# Вернуться в исходную директорию или выйти с ошибкой, если это не удалось
popd || { msg "Can't return to old directory" "Невозможно вернуться к старому каталогу"; }
# Создание цепочки сертификатов
cat "$IMM_CA/certs/intermediate.cert.pem" "$ROOT_CA/certs/ca.cert.pem" >"$IMM_CA/certs/ca-chain.cert.pem" || { msg "Error: Failed to create CA chain certificate" "Ошибка: Не удалось создать цепочку сертификатов ЦА"; }
# Проверка сертификата промежуточного ЦА с использованием корневого центра сертификации
openssl verify -CAfile $ROOT_CA/certs/ca.cert.pem $IMM_CA/certs/intermediate.cert.pem || { msg "Error: Failed to verify intermediate CA certificate" "Ошибка: Не удалось проверить сертификат промежуточного ЦА"; }
exit 0