Make own intermdiate ca for every server
This commit is contained in:
22
app.rb
22
app.rb
@@ -35,17 +35,17 @@ require_relative 'models/userdata'
|
|||||||
require_relative 'classes/cert'
|
require_relative 'classes/cert'
|
||||||
require_relative 'classes/pagination'
|
require_relative 'classes/pagination'
|
||||||
|
|
||||||
configure do
|
# configure do
|
||||||
Dir.mkdir('logs') unless Dir.exist?('logs')
|
# Dir.mkdir('logs') unless Dir.exist?('logs')
|
||||||
unless File.exist?('logs/actions.log')
|
# unless File.exist?('logs/actions.log')
|
||||||
File.new('logs/actions.log', 'w').close
|
# File.new('logs/actions.log', 'w').close
|
||||||
end
|
# end
|
||||||
log_file = File.open('logs/actions.log', 'a+')
|
# log_file = File.open('logs/actions.log', 'a+')
|
||||||
STDOUT.reopen(log_file)
|
# STDOUT.reopen(log_file)
|
||||||
STDERR.reopen(log_file)
|
# STDERR.reopen(log_file)
|
||||||
STDOUT.sync = true
|
# STDOUT.sync = true
|
||||||
STDERR.sync = true
|
# STDERR.sync = true
|
||||||
end
|
# end
|
||||||
|
|
||||||
set :bind, IPBIND
|
set :bind, IPBIND
|
||||||
set :port, PORT
|
set :port, PORT
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
require 'date'
|
require 'date'
|
||||||
require 'zip'
|
require 'zip'
|
||||||
require 'i18n'
|
require 'i18n'
|
||||||
|
require 'digest/sha1'
|
||||||
require_relative 'runner'
|
require_relative 'runner'
|
||||||
|
|
||||||
class CertManager
|
class CertManager
|
||||||
@@ -183,13 +184,13 @@ class CertManager
|
|||||||
if cert_item[:is_client]
|
if cert_item[:is_client]
|
||||||
files_list << cert_item[:client]
|
files_list << cert_item[:client]
|
||||||
files_list << "#{@root_ca}/ca/client_certs/#{cert_item[:server_name]}/private/#{cert_item[:client_id]}_private.key.pem"
|
files_list << "#{@root_ca}/ca/client_certs/#{cert_item[:server_name]}/private/#{cert_item[:client_id]}_private.key.pem"
|
||||||
files_list << "#{@root_ca}/ca/intermediate/certs/ca-chain.cert.pem"
|
files_list << "#{@root_ca}/ca/#{cert_item[:server_name]}/certs/ca-chain.cert.pem"
|
||||||
readme_txt = I18n.t('messages.client_readme', private_key: files_list[1], server_cert: files_list[0], ca_chain: files_list[2])
|
readme_txt = I18n.t('messages.client_readme', private_key: files_list[1], server_cert: files_list[0], ca_chain: files_list[2])
|
||||||
else
|
else
|
||||||
files_list << cert_item[:server]
|
files_list << cert_item[:server]
|
||||||
files_list << "#{@root_ca}/ca/intermediate/private/#{cert_item[:server_name]}.key.pem"
|
files_list << "#{@root_ca}/ca/#{cert_item[:server_name]}/private/#{cert_item[:server_name]}.key.pem"
|
||||||
files_list << "#{@root_ca}/ca/intermediate/certs/ca-chain.cert.pem"
|
files_list << "#{@root_ca}/ca/#{cert_item[:server_name]}/certs/ca-chain.cert.pem"
|
||||||
files_list << "#{@root_ca}/ca/intermediate/crl/ca-full.crl.pem"
|
files_list << "#{@root_ca}/ca/#{cert_item[:server_name]}/crl/ca-full.crl.pem"
|
||||||
readme_txt = I18n.t('messages.server_readme', private_key: files_list[1], server_cert: files_list[0], ca_chain: files_list[2], crl: files_list[3])
|
readme_txt = I18n.t('messages.server_readme', private_key: files_list[1], server_cert: files_list[0], ca_chain: files_list[2], crl: files_list[3])
|
||||||
end
|
end
|
||||||
cert_info[:full] = readme_txt
|
cert_info[:full] = readme_txt
|
||||||
@@ -210,7 +211,7 @@ class CertManager
|
|||||||
|
|
||||||
cert_info[:common] = cmd.stdout
|
cert_info[:common] = cmd.stdout
|
||||||
|
|
||||||
cmd_args = %Q(openssl verify -crl_check_all -CAfile "#{@root_ca}/ca/intermediate/certs/ca-chain.cert.pem" -CRLfile "#{@root_ca}/ca/intermediate/crl/ca-full.crl.pem" "#{cert_path}" 2>&1)
|
cmd_args = %Q(openssl verify -crl_check_all -CAfile "#{@root_ca}/ca/#{cert_item[:server_name]}/certs/ca-chain.cert.pem" -CRLfile "#{@root_ca}/ca/#{cert_item[:server_name]}/crl/ca-full.crl.pem" "#{cert_path}" 2>&1)
|
||||||
cmd = Runner.new(cmd_args)
|
cmd = Runner.new(cmd_args)
|
||||||
cmd.run_clean
|
cmd.run_clean
|
||||||
cert_info[:revoke] = cmd.stdout
|
cert_info[:revoke] = cmd.stdout
|
||||||
@@ -259,13 +260,13 @@ class CertManager
|
|||||||
if cert_path[:is_client]
|
if cert_path[:is_client]
|
||||||
files_list << cert_path[:client]
|
files_list << cert_path[:client]
|
||||||
files_list << "#{@root_ca}/ca/client_certs/#{cert_path[:server_name]}/private/#{cert_path[:client_id]}_private.key.pem"
|
files_list << "#{@root_ca}/ca/client_certs/#{cert_path[:server_name]}/private/#{cert_path[:client_id]}_private.key.pem"
|
||||||
files_list << "#{@root_ca}/ca/intermediate/certs/ca-chain.cert.pem"
|
files_list << "#{@root_ca}/ca/#{cert_path[:server_name]}/certs/ca-chain.cert.pem"
|
||||||
readme_txt = I18n.t('messages.client_readme', private_key: File.basename(files_list[1]), server_cert: File.basename(files_list[0]), ca_chain: File.basename(files_list[2]))
|
readme_txt = I18n.t('messages.client_readme', private_key: File.basename(files_list[1]), server_cert: File.basename(files_list[0]), ca_chain: File.basename(files_list[2]))
|
||||||
else
|
else
|
||||||
files_list << cert_path[:server]
|
files_list << cert_path[:server]
|
||||||
files_list << "#{@root_ca}/ca/intermediate/private/#{cert_path[:server_name]}.key.pem"
|
files_list << "#{@root_ca}/ca/#{cert_path[:server_name]}/private/#{cert_path[:server_name]}.key.pem"
|
||||||
files_list << "#{@root_ca}/ca/intermediate/certs/ca-chain.cert.pem"
|
files_list << "#{@root_ca}/ca/#{cert_path[:server_name]}/certs/ca-chain.cert.pem"
|
||||||
files_list << "#{@root_ca}/ca/intermediate/crl/ca-full.crl.pem"
|
files_list << "#{@root_ca}/ca/#{cert_path[:server_name]}/crl/ca-full.crl.pem"
|
||||||
readme_txt = I18n.t('messages.server_readme', private_key: File.basename(files_list[1]), server_cert: File.basename(files_list[0]), ca_chain: File.basename(files_list[2]), crl: File.basename(files_list[3]))
|
readme_txt = I18n.t('messages.server_readme', private_key: File.basename(files_list[1]), server_cert: File.basename(files_list[0]), ca_chain: File.basename(files_list[2]), crl: File.basename(files_list[3]))
|
||||||
end
|
end
|
||||||
if files_list.all? { |file| File.exist?(file) }
|
if files_list.all? { |file| File.exist?(file) }
|
||||||
@@ -408,9 +409,9 @@ class CertManager
|
|||||||
end
|
end
|
||||||
sr_name = item[:ui][:CN]
|
sr_name = item[:ui][:CN]
|
||||||
serv_file = if cl_name.length > 1
|
serv_file = if cl_name.length > 1
|
||||||
"#{@root_ca}/ca/intermediate/certs/#{sr_name}.cert.pem.#{cl_name[1]}"
|
"#{@root_ca}/ca/#{sr_name}/certs/#{sr_name}.cert.pem.#{cl_name[1]}"
|
||||||
else
|
else
|
||||||
"#{@root_ca}/ca/intermediate/certs/#{sr_name}.cert.pem"
|
"#{@root_ca}/ca/#{sr_name}/certs/#{sr_name}.cert.pem"
|
||||||
end
|
end
|
||||||
is_client = File.exist?(cert_file)
|
is_client = File.exist?(cert_file)
|
||||||
seq = if cl_name.length > 1
|
seq = if cl_name.length > 1
|
||||||
@@ -428,13 +429,29 @@ class CertManager
|
|||||||
return []
|
return []
|
||||||
end
|
end
|
||||||
|
|
||||||
index_txt_path = "#{@root_ca}/ca/intermediate/index.txt"
|
index_txt_path = "#{@root_ca}/ca/server_certs"
|
||||||
unless File.exist?(index_txt_path)
|
unless File.exist?(index_txt_path)
|
||||||
@error = I18n.t('errors.root_ca_not_detected')
|
|
||||||
return []
|
return []
|
||||||
end
|
end
|
||||||
|
|
||||||
ca_index_txt = File.read(index_txt_path, encoding: 'utf-8').split("\n").each_with_object([]) do |line, entries|
|
# Retrieve names of subdirectories under index_txt_path (without nested dirs)
|
||||||
|
dir_names = Dir.children(index_txt_path).select do |entry|
|
||||||
|
File.directory?(File.join(index_txt_path, entry))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Array to accumulate unique lines from all index.txt files
|
||||||
|
index_txt_entries = []
|
||||||
|
|
||||||
|
dir_names.each do |dir|
|
||||||
|
idx_file = File.join(@root_ca, 'ca', dir, 'index.txt')
|
||||||
|
next unless File.exist?(idx_file)
|
||||||
|
File.read(idx_file, encoding: 'utf-8').each_line do |line|
|
||||||
|
line.chomp!
|
||||||
|
index_txt_entries << line unless index_txt_entries.include?(line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ca_index_txt = index_txt_entries.each_with_object([]) do |line, entries|
|
||||||
match = line.split("\t")
|
match = line.split("\t")
|
||||||
next if match.length != 6
|
next if match.length != 6
|
||||||
|
|
||||||
@@ -473,6 +490,8 @@ class CertManager
|
|||||||
"#{@root_ca}/ca/client_certs/#{prep[:ui][:CN]}/#{cl_name[0]}.cert.pem"
|
"#{@root_ca}/ca/client_certs/#{prep[:ui][:CN]}/#{cl_name[0]}.cert.pem"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
prep[:id] = Digest::SHA1.hexdigest("#{prep[:ui][:CN]}/#{prep[:id]}")
|
||||||
|
|
||||||
if type == '*'
|
if type == '*'
|
||||||
entries << prep
|
entries << prep
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
### Примеры использования:
|
### Примеры использования:
|
||||||
1. Генерация серверного сертификата для домена `example1.com` и IP-адреса `192.168.3.145`:
|
1. Генерация серверного сертификата для домена `example1.com` и IP-адреса `192.168.3.145`:
|
||||||
```sh
|
```sh
|
||||||
bash make_server_cert.sh example1.com 192.168.3.145
|
bash make_server_cert.sh -t 395 example1.com 192.168.3.145
|
||||||
```
|
```
|
||||||
|
|
||||||
## Утилита `make_client_cert.sh`
|
## Утилита `make_client_cert.sh`
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
### Примеры использования:
|
### Примеры использования:
|
||||||
1. Отозвать серверный сертификат для домена `brepo.ru`:
|
1. Отозвать серверный сертификат для домена `brepo.ru`:
|
||||||
```sh
|
```sh
|
||||||
bash make_server_revoke.sh -n 1 brepo.ru
|
bash make_server_revoke.sh -n 1 -s brepo.ru
|
||||||
```
|
```
|
||||||
|
|
||||||
## Утилита `make_client_revoke.sh`
|
## Утилита `make_client_revoke.sh`
|
||||||
|
|||||||
@@ -24,5 +24,4 @@ fi
|
|||||||
|
|
||||||
PATH_TO_CA="$ROOT_DIR/ca"
|
PATH_TO_CA="$ROOT_DIR/ca"
|
||||||
ROOT_CA="$PATH_TO_CA/root"
|
ROOT_CA="$PATH_TO_CA/root"
|
||||||
IMM_CA="$PATH_TO_CA/intermediate"
|
|
||||||
CLI_CA="$PATH_TO_CA/client_certs"
|
CLI_CA="$PATH_TO_CA/client_certs"
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ pushd $PATH_TO_CA || {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMM_CA="$PATH_TO_CA/$server"
|
||||||
|
|
||||||
mkdir -p client_certs
|
mkdir -p client_certs
|
||||||
|
|
||||||
pushd client_certs || {
|
pushd client_certs || {
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ if [ ! -e "$CLI_CA/$server/${client}_csr_req.cnf" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
IMM_CA="$PATH_TO_CA/$server"
|
||||||
|
|
||||||
pushd "$IMM_CA" || {
|
pushd "$IMM_CA" || {
|
||||||
msg "Ошибка: не удалось перейти в каталог $IMM_CA" "Error: Could not change directory to $IMM_CA" >&2
|
msg "Ошибка: не удалось перейти в каталог $IMM_CA" "Error: Could not change directory to $IMM_CA" >&2
|
||||||
cd "$CURRENT_DIR" || exit 1
|
cd "$CURRENT_DIR" || exit 1
|
||||||
|
|||||||
@@ -14,6 +14,23 @@ else
|
|||||||
LANG_RU=0
|
LANG_RU=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 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
|
||||||
|
}
|
||||||
|
|
||||||
# Handle -h option for help message
|
# Handle -h option for help message
|
||||||
if [ "$1" == "-h" ]; then
|
if [ "$1" == "-h" ]; then
|
||||||
if [ "$LANG_RU" -eq 1 ]; then
|
if [ "$LANG_RU" -eq 1 ]; then
|
||||||
@@ -69,10 +86,6 @@ CERT_DAYS=${CERT_DAYS:-3650}
|
|||||||
|
|
||||||
pushd $PATH_TO_CA || exit
|
pushd $PATH_TO_CA || exit
|
||||||
|
|
||||||
mkdir -p server_certs
|
|
||||||
|
|
||||||
pushd server_certs || exit
|
|
||||||
|
|
||||||
# Проверка, предоставлен ли первый параметр и не пуст ли он
|
# Проверка, предоставлен ли первый параметр и не пуст ли он
|
||||||
if [ -z "$1" ]; then
|
if [ -z "$1" ]; then
|
||||||
if [ "$LANG_RU" -eq 1 ]; then
|
if [ "$LANG_RU" -eq 1 ]; then
|
||||||
@@ -94,7 +107,6 @@ if [ "${#items[@]}" -eq 0 ]; then
|
|||||||
echo "No elements found in the input"
|
echo "No elements found in the input"
|
||||||
fi
|
fi
|
||||||
popd || exit
|
popd || exit
|
||||||
popd || exit
|
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -103,6 +115,157 @@ SEQ="1"
|
|||||||
# Извлечение первого элемента списка
|
# Извлечение первого элемента списка
|
||||||
fst_elem="${items[0]}"
|
fst_elem="${items[0]}"
|
||||||
|
|
||||||
|
IMM_CA="$PATH_TO_CA/$fst_elem"
|
||||||
|
|
||||||
|
# Создаем промежуточный CA
|
||||||
|
if [ ! -d "$IMM_CA" ]; then
|
||||||
|
|
||||||
|
# Список каталогов, для которых создается структура
|
||||||
|
DIRECTORIES=("$fst_elem")
|
||||||
|
|
||||||
|
# Создание необходимых директорий и настройка их прав доступа
|
||||||
|
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 >$IMM_CA/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 = $fst_elem
|
||||||
|
|
||||||
|
[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" "Ошибка: Не удалось проверить сертификат промежуточного ЦА"; }
|
||||||
|
|
||||||
|
fi
|
||||||
|
# Конец создания промежуточного CA
|
||||||
|
|
||||||
|
mkdir -p server_certs
|
||||||
|
|
||||||
|
pushd server_certs || exit
|
||||||
|
|
||||||
# Создание директории с именем первого элемента, если она не существует
|
# Создание директории с именем первого элемента, если она не существует
|
||||||
mkdir -p "$fst_elem" || true
|
mkdir -p "$fst_elem" || true
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ if [ ! -e "$PATH_TO_CA/server_certs/$server" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
IMM_CA="$PATH_TO_CA/$server"
|
||||||
|
|
||||||
pushd "$IMM_CA" || {
|
pushd "$IMM_CA" || {
|
||||||
msg "Error: Could not change directory to $IMM_CA" "Ошибка: Не удалось перейти в каталог $IMM_CA" >&2
|
msg "Error: Could not change directory to $IMM_CA" "Ошибка: Не удалось перейти в каталог $IMM_CA" >&2
|
||||||
cd "$CURRENT_DIR" || exit 1
|
cd "$CURRENT_DIR" || exit 1
|
||||||
|
|||||||
127
utils/prepare.sh
127
utils/prepare.sh
@@ -51,7 +51,7 @@ fi
|
|||||||
cd "$PATH_TO_CA" || { msg "Error: Failed to change directory to $PATH_TO_CA" "Ошибка: Не удалось перейти в каталог $PATH_TO_CA"; }
|
cd "$PATH_TO_CA" || { msg "Error: Failed to change directory to $PATH_TO_CA" "Ошибка: Не удалось перейти в каталог $PATH_TO_CA"; }
|
||||||
|
|
||||||
# Список каталогов, для которых создается структура
|
# Список каталогов, для которых создается структура
|
||||||
DIRECTORIES=("root" "intermediate")
|
DIRECTORIES=("root")
|
||||||
|
|
||||||
# Создание необходимых директорий и настройка их прав доступа
|
# Создание необходимых директорий и настройка их прав доступа
|
||||||
for dir in "${DIRECTORIES[@]}"; do
|
for dir in "${DIRECTORIES[@]}"; do
|
||||||
@@ -114,7 +114,7 @@ prompt = no
|
|||||||
[req_distinguished_name]
|
[req_distinguished_name]
|
||||||
countryName = $COUNTRY_NAME
|
countryName = $COUNTRY_NAME
|
||||||
organizationName = $ORG_NAME
|
organizationName = $ORG_NAME
|
||||||
commonName = $ORG_NAME
|
commonName = $COMM_NAME
|
||||||
|
|
||||||
[v3_ca]
|
[v3_ca]
|
||||||
subjectKeyIdentifier = hash
|
subjectKeyIdentifier = hash
|
||||||
@@ -153,127 +153,4 @@ openssl x509 -noout -text -in certs/ca.cert.pem || { msg "Error: Failed to displ
|
|||||||
# Вернуться в исходную директорию или выйти с ошибкой, если это не удалось
|
# Вернуться в исходную директорию или выйти с ошибкой, если это не удалось
|
||||||
popd || { msg "Can't return to old directory" "Невозможно вернуться к старому каталогу"; }
|
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
|
exit 0
|
||||||
|
|||||||
Reference in New Issue
Block a user