Initial commit
This commit is contained in:
230
utils/api_call.sh
Executable file
230
utils/api_call.sh
Executable file
@@ -0,0 +1,230 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") -s SERVER -u USER -p PASS <command> [args]
|
||||
|
||||
Commands:
|
||||
install <login> <password> <email> # Create initial admin user (no auth needed)
|
||||
listserv # List server certificates
|
||||
listclient # List client certificates
|
||||
addserv <domains> <validity_days> # Add server certificate
|
||||
addclient <server_domain> <client> <validity_days> # Add client certificate
|
||||
listuser # List users
|
||||
adduser <login> <password> <email> <role> # Add user (role numeric)
|
||||
revokecert <id> # Revoke certificate
|
||||
deleteuser <id> # Delete user
|
||||
edituser <id> <login> <password> <role> # Edit user
|
||||
certdetail <id> # Cert detail
|
||||
rootdetail # Root cert detail
|
||||
help # Show this help
|
||||
|
||||
Options:
|
||||
-s SERVER Base URL of the API (default: http://127.0.0.1:4567)
|
||||
-u USER Username for authentication
|
||||
-p PASS Password for authentication
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse global options
|
||||
SERVER="http://127.0.0.1:4567"
|
||||
USERNAME=""
|
||||
PASSWORD=""
|
||||
|
||||
while getopts ":s:u:p:h" opt; do
|
||||
case $opt in
|
||||
s) SERVER="$OPTARG" ;;
|
||||
u) USERNAME="$OPTARG" ;;
|
||||
p) PASSWORD="$OPTARG" ;;
|
||||
h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option -$OPTARG"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
COMMAND="$1"
|
||||
shift
|
||||
|
||||
# Helper: get token
|
||||
get_token() {
|
||||
local login="$1"
|
||||
local pass="$2"
|
||||
local resp
|
||||
resp=$(curl -s -X POST "$SERVER/api/v1/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"login\":\"$login\",\"password\":\"$pass\"}")
|
||||
local err
|
||||
err=$(echo "$resp" | jq -r '.error')
|
||||
if [[ "$err" != "null" && -n "$err" ]]; then
|
||||
echo "Login error: $err" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "$resp" | jq -r '.content.token'
|
||||
}
|
||||
|
||||
# Helper: perform request
|
||||
do_req() {
|
||||
local method="$1"
|
||||
local url="$2"
|
||||
local data="$3"
|
||||
local token="$4"
|
||||
local json_data
|
||||
if [[ -n "$token" ]]; then
|
||||
json_data=$(echo "$data" | jq --arg token "$token" '. + {token: $token}')
|
||||
else
|
||||
json_data="$data"
|
||||
fi
|
||||
local resp
|
||||
resp=$(curl -s -X "$method" "$url" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$json_data")
|
||||
local err
|
||||
err=$(echo "$resp" | jq -r '.error')
|
||||
if [[ "$err" != "null" && -n "$err" ]]; then
|
||||
echo "Error: $err" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "$resp" | jq -r '.content'
|
||||
}
|
||||
|
||||
# Commands requiring authentication
|
||||
auth_required_commands=("listserv" "listclient" "addserv" "addclient" "listuser" "adduser" "revokecert" "deleteuser" "edituser" "certdetail" "rootdetail")
|
||||
needs_auth=false
|
||||
for cmd in "${auth_required_commands[@]}"; do
|
||||
if [[ "$COMMAND" == "$cmd" ]]; then
|
||||
needs_auth=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if $needs_auth; then
|
||||
if [[ -z "$USERNAME" || -z "$PASSWORD" ]]; then
|
||||
echo "Username and password required for command '$COMMAND'" >&2
|
||||
exit 1
|
||||
fi
|
||||
TOKEN=$(get_token "$USERNAME" "$PASSWORD")
|
||||
if [[ -z "$TOKEN" ]]; then
|
||||
echo "Failed to obtain token" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$COMMAND" in
|
||||
install)
|
||||
if [[ $# -ne 3 ]]; then
|
||||
echo "install requires <login> <password> <email>" >&2
|
||||
exit 1
|
||||
fi
|
||||
login="$1"
|
||||
pw="$2"
|
||||
email="$3"
|
||||
do_req POST "$SERVER/api/v1/adduser" "{\"login\":\"$login\",\"password\":\"$pw\",\"email\":\"$email\",\"role\":1}" ""
|
||||
;;
|
||||
listserv)
|
||||
do_req POST "$SERVER/api/v1/servers" "{}" "$TOKEN"
|
||||
;;
|
||||
listclient)
|
||||
do_req POST "$SERVER/api/v1/clients" "{}" "$TOKEN"
|
||||
;;
|
||||
addserv)
|
||||
if [[ $# -ne 2 ]]; then
|
||||
echo "addserv requires <domains> <validity_days>" >&2
|
||||
exit 1
|
||||
fi
|
||||
domains="$1"
|
||||
days="$2"
|
||||
do_req POST "$SERVER/api/v1/addserver" "{\"domains\":\"$domains\",\"validity_days\":$days}" "$TOKEN"
|
||||
;;
|
||||
addclient)
|
||||
if [[ $# -ne 3 ]]; then
|
||||
echo "addclient requires <server_domain> <client> <validity_days>" >&2
|
||||
exit 1
|
||||
fi
|
||||
server_domain="$1"
|
||||
client="$2"
|
||||
validity_days="$3"
|
||||
do_req POST "$SERVER/api/v1/addclient" "{\"server_domain\":\"$server_domain\",\"client\":\"$client\",\"validity_days\":\"$validity_days\"}" "$TOKEN"
|
||||
;;
|
||||
listuser)
|
||||
do_req POST "$SERVER/api/v1/ulist" "{}" "$TOKEN"
|
||||
;;
|
||||
adduser)
|
||||
if [[ $# -ne 4 ]]; then
|
||||
echo "adduser requires <login> <password> <email> <role:user|creator|admin>" >&2
|
||||
exit 1
|
||||
fi
|
||||
login="$1"
|
||||
pw="$2"
|
||||
email="$3"
|
||||
role="$4"
|
||||
case "$role" in
|
||||
user) role=0 ;;
|
||||
creator) role=1 ;;
|
||||
admin) role=2 ;;
|
||||
*) role=0 ;;
|
||||
esac
|
||||
do_req POST "$SERVER/api/v1/adduser" "{\"login\":\"$login\",\"password\":\"$pw\",\"email\":\"$email\",\"role\":$role}" "$TOKEN"
|
||||
;;
|
||||
revokecert)
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "revokecert requires <id>" >&2
|
||||
exit 1
|
||||
fi
|
||||
id="$1"
|
||||
do_req POST "$SERVER/api/v1/revoke/$id" "{}" "$TOKEN"
|
||||
;;
|
||||
deleteuser)
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "deleteuser requires <id>" >&2
|
||||
exit 1
|
||||
fi
|
||||
id="$1"
|
||||
do_req POST "$SERVER/api/v1/deleteuser/$id" "{}" "$TOKEN"
|
||||
;;
|
||||
edituser)
|
||||
if [[ $# -ne 5 ]]; then
|
||||
echo "edituser requires <id> <login> <password> <email> <role: user|creator|admin>" >&2
|
||||
exit 1
|
||||
fi
|
||||
id="$1"
|
||||
login="$2"
|
||||
pw="$3"
|
||||
role="$5"
|
||||
email="$4"
|
||||
case "$role" in
|
||||
user) role=0 ;;
|
||||
creator) role=1 ;;
|
||||
admin) role=2 ;;
|
||||
*) role=0 ;;
|
||||
esac
|
||||
do_req POST "$SERVER/api/v1/edituser/$id" "{\"login\":\"$login\",\"password\":\"$pw\",\"role\":$role,\"email\":\"$email\"}" "$TOKEN"
|
||||
;;
|
||||
certdetail)
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "certdetail requires <id>" >&2
|
||||
exit 1
|
||||
fi
|
||||
id="$1"
|
||||
do_req POST "$SERVER/api/v1/certinfo/$id" "{}" "$TOKEN"
|
||||
;;
|
||||
rootdetail)
|
||||
do_req POST "$SERVER/api/v1/root" "{}" "$TOKEN"
|
||||
;;
|
||||
help | --help | -h)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command: $COMMAND" >&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
28
utils/config.sh
Normal file
28
utils/config.sh
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -e custom_config.sh ]; then
|
||||
source custom_config.sh
|
||||
else
|
||||
|
||||
ROOT_DIR="."
|
||||
|
||||
COUNTRY_NAME="RU"
|
||||
ORG_NAME="Regenal Organization"
|
||||
COMM_NAME="General Name"
|
||||
SERT_PASS=""
|
||||
|
||||
fi
|
||||
|
||||
if [ -z "$SERT_PASS" ]; then
|
||||
if [[ "$LANG" =~ ^ru ]]; then
|
||||
echo "Установите пароль для корневого сертификата и промежуточного"
|
||||
else
|
||||
echo "Please set a password for the root certificate and intermediate"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PATH_TO_CA="$ROOT_DIR/ca"
|
||||
ROOT_CA="$PATH_TO_CA/root"
|
||||
IMM_CA="$PATH_TO_CA/intermediate"
|
||||
CLI_CA="$PATH_TO_CA/client_certs"
|
||||
41
utils/make_app_keys.sh
Normal file
41
utils/make_app_keys.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Описание: Этот скрипт генерирует беспарольный публичный и приватный ключ с помощью openssl.
|
||||
# Путь к файлу указывается в первом обязательном параметре, если он не указан,
|
||||
# то показывается help или usage. Если путь не существует, то сообщает об ошибке и завершает работу.
|
||||
|
||||
# Определяем язык вывода
|
||||
if [[ "$LANG" =~ ^ru|RU ]]; then
|
||||
USE_RU=1
|
||||
else
|
||||
USE_RU=0
|
||||
fi
|
||||
|
||||
if [ -z "$1" ] || [ ! -e "$1" ]; then
|
||||
if [ "$USE_RU" -eq 1 ]; then
|
||||
echo "Использование: $0 <путь>"
|
||||
else
|
||||
echo "Usage: $0 <path>"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PATH_TO_KEYS=$1
|
||||
|
||||
if [ ! -e "$PATH_TO_KEYS" ]; then
|
||||
if [ "$USE_RU" -eq 1 ]; then
|
||||
echo "Такого пути $PATH_TO_KEYS не существует"
|
||||
else
|
||||
echo "Path $PATH_TO_KEYS does not exist"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
openssl genpkey -algorithm RSA -out "$PATH_TO_KEYS/caapp.private.key.pem" -pkeyopt rsa_keygen_bits:2048
|
||||
openssl rsa -in "$PATH_TO_KEYS/caapp.private.key.pem" -pubout -out "$PATH_TO_KEYS/caapp.public.key.pem"
|
||||
|
||||
if [ "$USE_RU" -eq 1 ]; then
|
||||
echo "Беспарольный публичный $PATH_TO_KEYS/caapp.public.key.pem и приватный $PATH_TO_KEYS/caapp.private.key.pem ключи созданы по пути"
|
||||
else
|
||||
echo "Passwordless public key $PATH_TO_KEYS/caapp.public.key.pem and private key $PATH_TO_KEYS/caapp.private.key.pem created at path"
|
||||
fi
|
||||
182
utils/make_client_cert.sh
Normal file
182
utils/make_client_cert.sh
Normal file
@@ -0,0 +1,182 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Скрипт для создания клиентских сертификатов для указанного сервера и клиента.
|
||||
# Генерирует приватный ключ, запрос на сертификат (CSR), подписывает его и выводит информацию о сгенерированном сертификате.
|
||||
#
|
||||
|
||||
source config.sh
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
|
||||
# Determine language based on locale
|
||||
if [[ "$LANG" =~ ^ru ]]; then
|
||||
USE_RU=true
|
||||
else
|
||||
USE_RU=false
|
||||
fi
|
||||
|
||||
msg() {
|
||||
if $USE_RU; then
|
||||
printf '%s\n' "$1"
|
||||
else
|
||||
printf '%s\n' "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
# Проверка наличия и валидации параметров командной строки
|
||||
while getopts "s:c:d:h" opt; do
|
||||
case $opt in
|
||||
s) server=$OPTARG ;;
|
||||
c) client=$OPTARG ;;
|
||||
d) days=$OPTARG ;;
|
||||
h)
|
||||
msg "Использование: $0 -s <доменное имя сервера> -c <строка имени клиента> -d <число дней>" "Usage: $0 -s <server domain> -c <client name string> -d <number of days>"
|
||||
exit 0
|
||||
;;
|
||||
\?)
|
||||
msg "Неверный аргумент или пустой параметр" "Invalid argument or empty parameter" >&2
|
||||
msg "Использование: $0 -s <доменное имя сервера> -c <строка имени клиента> -d <число дней>" "Usage: $0 -s <server domain> -c <client name string> -d <number of days>" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Если параметры -d и -c не заданы или пусты, вывести сообщение об ошибке и справку
|
||||
if [[ -z "$server" || -z "$client" ]]; then
|
||||
msg "Неверные аргументы или пустые параметры" "Invalid arguments or empty parameters" >&2
|
||||
msg "Использование: $0 -s <доменное имя сервера> -c <строка имени клиента> -d <число дней>" "Usage: $0 -s <server domain> -c <client name string> -d <number of days>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Если параметр -d не задан, принять число дней равным 30
|
||||
if [ -z "$days" ]; then
|
||||
days=30
|
||||
fi
|
||||
|
||||
if [ ! -e "$PATH_TO_CA/server_certs/$server" ]; then
|
||||
msg "Данного ресурса не существует $server" "Resource $server does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd $PATH_TO_CA || {
|
||||
msg "Ошибка: Не удалось перейти в каталог $PATH_TO_CA" "Error: Could not change directory to $PATH_TO_CA" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
|
||||
mkdir -p client_certs
|
||||
|
||||
pushd client_certs || {
|
||||
msg "Ошибка: Не удалось перейти в каталог client_certs" "Error: Could not change directory to client_certs" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
|
||||
SEQ="1"
|
||||
|
||||
if [ ! -e "$server/${client}_csr_req.cnf" ]; then
|
||||
|
||||
mkdir -p "$server" "$server/private"
|
||||
|
||||
chmod 0700 "$server/private"
|
||||
|
||||
echo -n "2" >"$server/${client}_seq.seq"
|
||||
|
||||
cat <<EOF >"$server/${client}_csr_req.cnf"
|
||||
[req]
|
||||
default_bits = 2048
|
||||
default_md = sha256
|
||||
prompt = no
|
||||
distinguished_name = dn
|
||||
req_extensions = req_ext
|
||||
|
||||
[dn]
|
||||
CN = $server
|
||||
O = $client:1
|
||||
|
||||
[req_ext]
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
email.1 = $client
|
||||
EOF
|
||||
|
||||
# Создание запроса на сертификат (CSR) для указанного сервера и клиента
|
||||
openssl req -new -sha256 -nodes -keyout "$CLI_CA/$server/private/${client}_private.key.pem" -out "$CLI_CA/$server/${client}.csr.pem.$SEQ" -config "$CLI_CA/$server/${client}_csr_req.cnf" || {
|
||||
msg "Error: Failed to create CSR for server certificate" "Error: Failed to create CSR for server certificate" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
|
||||
chmod 0400 "$CLI_CA/$server/private/${client}_private.key.pem"
|
||||
else
|
||||
# Чтение файла "$server/${client}_seq.seq" и его значение сохраняется в переменной SEQ, а в файл без переноса строки записывается новое значение SEQ+1
|
||||
SEQ=$(cat "$server/${client}_seq.seq")
|
||||
echo $((SEQ + 1)) >"$server/${client}_seq.seq"
|
||||
|
||||
# Парсинг файла "$server/${client}_csr_req.cnf" и замена значения ключа O на $client:$SEQ
|
||||
sed -i "s/^O = .*/O = $client:$SEQ/" "$server/${client}_csr_req.cnf"
|
||||
|
||||
openssl req -new -sha256 -key "$CLI_CA/$server/private/${client}_private.key.pem" -out "$CLI_CA/$server/${client}.csr.pem.$SEQ" -config "$CLI_CA/$server/${client}_csr_req.cnf" || {
|
||||
msg "Error: Failed to create CSR for server certificate" "Error: Failed to create CSR for server certificate" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
popd || {
|
||||
msg "Ошибка: Не удалось вернуться из каталога client_certs" "Error: Could not popd from client_certs" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
|
||||
pushd "$IMM_CA" || {
|
||||
msg "Ошибка: Не удалось перейти в каталог $IMM_CA" "Error: Could not change directory to $IMM_CA" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Подпись CSR сертификатом CA
|
||||
openssl ca -batch -config "immissuer.conf" -extensions client_cert -days "$days" -notext -md sha256 -in "$CLI_CA/$server/${client}.csr.pem.$SEQ" -out "$CLI_CA/$server/${client}.cert.pem.$SEQ" -passin "pass:$SERT_PASS" || {
|
||||
msg "Ошибка: Не удалось подписать сертификат сервера" "Error: Failed to sign the server certificate" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
chmod 644 "$CLI_CA/$server/${client}.cert.pem.$SEQ"
|
||||
|
||||
# Вывод информации о сгенерированном сертификате
|
||||
openssl x509 -noout -text -in "$CLI_CA/$server/${client}.cert.pem.$SEQ" || {
|
||||
msg "Ошибка: Не удалось отобразить информацию о сертификате сервера" "Error: Failed to display the server certificate information" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
|
||||
if $USE_RU; then
|
||||
cat <<EOF
|
||||
Сгенерированный набор ключей для установки на машину клиента для доступа:
|
||||
|
||||
- [OUTPUTDATA] приватный ключ: \`$CLI_CA/$server/private/${client}_private.key.pem\`;
|
||||
- [OUTPUTDATA_CERT] сертификат сервера: \`$CLI_CA/$server/${client}.cert.pem.$SEQ\`;
|
||||
- [OUTPUTDATA] цепочка CA: \`$IMM_CA/certs/ca-chain.cert.pem\`.
|
||||
EOF
|
||||
else
|
||||
cat <<EOF
|
||||
Generated key set for client machine:
|
||||
|
||||
- [OUTPUTDATA] private key: \`$CLI_CA/$server/private/${client}_private.key.pem\`;
|
||||
- [OUTPUTDATA_CERT] server certificate: \`$CLI_CA/$server/${client}.cert.pem.$SEQ\`;
|
||||
- [OUTPUTDATA] CA chain: \`$IMM_CA/certs/ca-chain.cert.pem\`.
|
||||
EOF
|
||||
fi
|
||||
|
||||
popd || {
|
||||
msg "Ошибка: Не удалось вернуться из каталога $IMM_CA" "Error: Could not popd from $IMM_CA" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
|
||||
popd || {
|
||||
msg "Ошибка: Не удалось вернуться из каталога $PATH_TO_CA" "Error: Could not popd from $PATH_TO_CA" >&2
|
||||
cd "$CURRENT_DIR" || exit
|
||||
exit 1
|
||||
}
|
||||
96
utils/make_client_revoke.sh
Normal file
96
utils/make_client_revoke.sh
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
source config.sh
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
|
||||
CERT_REV=""
|
||||
|
||||
# Language detection
|
||||
if [[ "$LANG" == ru_* || "$LANG" == *ru* ]]; then
|
||||
IS_RU=1
|
||||
else
|
||||
IS_RU=0
|
||||
fi
|
||||
|
||||
msg() {
|
||||
local ru=$1
|
||||
local en=$2
|
||||
if [[ $IS_RU -eq 1 ]]; then
|
||||
echo "$ru"
|
||||
else
|
||||
echo "$en"
|
||||
fi
|
||||
}
|
||||
|
||||
# Проверка наличия и валидации параметров командной строки
|
||||
while getopts "s:c:n:h" opt; do
|
||||
case $opt in
|
||||
s) server=$OPTARG ;;
|
||||
c) client=$OPTARG ;;
|
||||
n) CERT_REV=$OPTARG ;;
|
||||
h)
|
||||
msg "Использование: $0 -s <доменное имя сервера> -c <строка имени клиента> -n <номер версии>" "Usage: $0 -s <server domain> -c <client name> -n <version number>"
|
||||
exit 0
|
||||
;;
|
||||
\?)
|
||||
msg "Неверный аргумент или пустой параметр" "Invalid argument or empty parameter" >&2
|
||||
msg "Использование: $0 -s <доменное имя сервера> -c <строка имени клиента> -n <номер версии>" "Usage: $0 -s <server domain> -c <client name> -n <version number>" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Если параметры -d и -c не заданы или пусты, вывести сообщение об ошибке и справку
|
||||
if [[ -z "$server" || -z "$client" ]]; then
|
||||
msg "Неверные аргументы или пустые параметры" "Invalid arguments or empty parameters" >&2
|
||||
msg "Использование: $0 -s <доменное имя сервера> -c <строка имени клиента> -n <номер версии>" "Usage: $0 -s <server domain> -c <client name> -n <version number>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e "$PATH_TO_CA/server_certs/$server" ]; then
|
||||
msg "Данного ресурса не существует $server" "Resource does not exist: $server" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e "$CLI_CA/$server/${client}_csr_req.cnf" ]; then
|
||||
msg "Данного клиента не существует $client" "Client does not exist: $client" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd "$IMM_CA" || {
|
||||
msg "Ошибка: не удалось перейти в каталог $IMM_CA" "Error: Could not change directory to $IMM_CA" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
}
|
||||
|
||||
if [ -z "$CERT_REV" ]; then
|
||||
files=("$CLI_CA/$server/${client}.cert.pem".*)
|
||||
else
|
||||
files=("$CLI_CA/$server/${client}.cert.pem.$CERT_REV")
|
||||
fi
|
||||
|
||||
for file in "${files[@]}"; do
|
||||
if [ -e "$file" ]; then
|
||||
if ! openssl ca -config "immissuer.conf" -revoke "$file" -passin "pass:$SERT_PASS"; then
|
||||
msg "Ошибка при выполнении команды openssl ca -revoke" "Error executing openssl ca -revoke" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if ! openssl ca -config "immissuer.conf" -gencrl -out crl/intermediate.crl.pem -passin "pass:$SERT_PASS"; then
|
||||
msg "Ошибка при выполнении команды openssl ca -gencrl" "Error executing openssl ca -gencrl" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
fi
|
||||
|
||||
if ! openssl crl -in crl/intermediate.crl.pem -noout -text; then
|
||||
msg "Ошибка при выполнении команды openssl crl" "Error executing openssl crl" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
fi
|
||||
|
||||
cat $ROOT_CA/crl/ca.crl.pem $IMM_CA/crl/intermediate.crl.pem >$IMM_CA/crl/ca-full.crl.pem
|
||||
|
||||
popd || {
|
||||
msg "Ошибка: не удалось выйти из каталога $IMM_CA" "Error: Could not popd from $IMM_CA" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
}
|
||||
209
utils/make_server_cert.sh
Normal file
209
utils/make_server_cert.sh
Normal file
@@ -0,0 +1,209 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Этот скрипт предназначен для генерации серверных сертификатов для указанных доменов или IP-адресов.
|
||||
# Он создает приватный ключ, запрос на подпись сертификата (CSR) и сам сертификат,
|
||||
# используя конфигурационные файлы и инфраструктуру центра сертификации (CA).
|
||||
# Скрипт также выводит информацию о сгенерированных ключах и сертификатах.
|
||||
|
||||
source ./config.sh
|
||||
|
||||
# Определяем, установлена ли русская локаль
|
||||
if [[ "${LANG,,}" == ru* ]] || [[ "${LC_MESSAGES,,}" == ru* ]]; then
|
||||
LANG_RU=1
|
||||
else
|
||||
LANG_RU=0
|
||||
fi
|
||||
|
||||
# Handle -h option for help message
|
||||
if [ "$1" == "-h" ]; then
|
||||
if [ "$LANG_RU" -eq 1 ]; then
|
||||
echo "Использование: $0 [-h] [-t|--days DAYS] [domain1, domain2, ...]"
|
||||
echo "Создает сертификаты сервера для указанных доменов или IP."
|
||||
echo
|
||||
echo "Опции:"
|
||||
echo " -h Показать это сообщение"
|
||||
echo " -t|--days DAYS Установить срок действия сертификата (по умолчанию: 3650 дней)"
|
||||
else
|
||||
echo "Usage: $0 [-h] [-t|--days DAYS] [domain1, domain2, ...]"
|
||||
echo "Generate server certificates for the given domains or IPs."
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -h Display this help message"
|
||||
echo " -t|--days DAYS Set the number of days the certificate is valid for (default: 3650)"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Чтение параметра -t через getopt для установки числа дней действия сертификата
|
||||
while true; do
|
||||
case "$1" in
|
||||
-t | --days)
|
||||
CERT_DAYS="$2"
|
||||
shift 2
|
||||
break
|
||||
;;
|
||||
-h | --help)
|
||||
if [ "$LANG_RU" -eq 1 ]; then
|
||||
echo "Использование: $0 [-h] [-t|--days DAYS] [domain1, domain2, ...]"
|
||||
echo "Создает сертификаты сервера для указанных доменов или IP."
|
||||
echo
|
||||
echo "Опции:"
|
||||
echo " -h Показать это сообщение"
|
||||
echo " -t|--days DAYS Установить срок действия сертификата (по умолчанию: 3650 дней)"
|
||||
else
|
||||
echo "Usage: $0 [-h] [-t|--days DAYS] [domain1, domain2, ...]"
|
||||
echo "Generate server certificates for the given domains or IPs."
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -h Display this help message"
|
||||
echo " -t|--days DAYS Set the number of days the certificate is valid for (default: 3650)"
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Если параметр не указан, используем значение по умолчанию
|
||||
CERT_DAYS=${CERT_DAYS:-3650}
|
||||
|
||||
pushd $PATH_TO_CA || exit
|
||||
|
||||
mkdir -p server_certs
|
||||
|
||||
pushd server_certs || exit
|
||||
|
||||
# Проверка, предоставлен ли первый параметр и не пуст ли он
|
||||
if [ -z "$1" ]; then
|
||||
if [ "$LANG_RU" -eq 1 ]; then
|
||||
echo "Нет входных данных"
|
||||
else
|
||||
echo "No input provided"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Разделение входной строки в массив с использованием запятых или пробелов как разделителей
|
||||
IFS=', ' read -r -a items <<<"$1"
|
||||
|
||||
# Проверка, есть ли хотя бы один элемент в списке
|
||||
if [ "${#items[@]}" -eq 0 ]; then
|
||||
if [ "$LANG_RU" -eq 1 ]; then
|
||||
echo "Входные данные пусты"
|
||||
else
|
||||
echo "No elements found in the input"
|
||||
fi
|
||||
popd || exit
|
||||
popd || exit
|
||||
exit 0
|
||||
fi
|
||||
|
||||
SEQ="1"
|
||||
|
||||
# Извлечение первого элемента списка
|
||||
fst_elem="${items[0]}"
|
||||
|
||||
# Создание директории с именем первого элемента, если она не существует
|
||||
mkdir -p "$fst_elem" || true
|
||||
|
||||
if [ ! -e "$fst_elem/csr_req.cnf" ]; then
|
||||
|
||||
echo -n "2" >"$fst_elem/${fst_elem}_seq.seq"
|
||||
|
||||
# Создание файла csr_api.cnf с необходимым содержимым
|
||||
cat <<EOF >"$fst_elem/csr_req.cnf"
|
||||
[req]
|
||||
default_bits = 2048
|
||||
default_md = sha256
|
||||
prompt = no
|
||||
distinguished_name = dn
|
||||
req_extensions = req_ext
|
||||
|
||||
[dn]
|
||||
CN = $fst_elem
|
||||
O = ${ORG_NAME}:$SEQ
|
||||
|
||||
[req_ext]
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
EOF
|
||||
|
||||
# Добавление записей DNS для доменных имен и записей IP для IP-адресов
|
||||
dns_count=1
|
||||
ip_count=1
|
||||
|
||||
for item in "${items[@]}"; do
|
||||
if [[ "$item" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "IP.$ip_count = $item" >>"$fst_elem/csr_req.cnf"
|
||||
((ip_count++))
|
||||
else
|
||||
echo "DNS.$dns_count = $item" >>"$fst_elem/csr_req.cnf"
|
||||
((dns_count++))
|
||||
fi
|
||||
done
|
||||
|
||||
popd || exit
|
||||
|
||||
pushd "$IMM_CA" || {
|
||||
if [ "$LANG_RU" -eq 1 ]; then
|
||||
echo "Ошибка: не удалось перейти в каталог $IMM_CA"
|
||||
else
|
||||
echo "Error: Could not change directory to $IMM_CA"
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
openssl genrsa -out "private/$fst_elem.key.pem" -passout "pass:$SERT_PASS" 2048
|
||||
chmod 400 "private/$fst_elem.key.pem"
|
||||
else
|
||||
SEQ=$(cat "$fst_elem/${fst_elem}_seq.seq")
|
||||
echo $((SEQ + 1)) >"$fst_elem/${fst_elem}_seq.seq"
|
||||
|
||||
sed -i "s/^O = .*/O = ${ORG_NAME}:${SEQ}/" "${fst_elem}/csr_req.cnf"
|
||||
|
||||
pushd "$IMM_CA" || {
|
||||
if [ "$LANG_RU" -eq 1 ]; then
|
||||
echo "Ошибка: не удалось перейти в каталог $IMM_CA"
|
||||
else
|
||||
echo "Error: Could not change directory to $IMM_CA"
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
fi
|
||||
|
||||
# Генерация запроса на подпись сертификата (CSR)
|
||||
openssl req -new -sha256 -key "private/$fst_elem.key.pem" -out "csr/$fst_elem.csr.pem" -config "../server_certs/$fst_elem/csr_req.cnf"
|
||||
|
||||
# Подписание CSR и создание сертификата
|
||||
openssl ca -batch -config "immissuer.conf" -extensions server_cert -days "$CERT_DAYS" -notext -md sha256 -in "csr/$fst_elem.csr.pem" -out "certs/$fst_elem.cert.pem.$SEQ" -passin "pass:$SERT_PASS"
|
||||
chmod 444 "certs/$fst_elem.cert.pem.$SEQ"
|
||||
|
||||
# Вывод информации о сертификате
|
||||
openssl x509 -noout -text -in "certs/$fst_elem.cert.pem.$SEQ"
|
||||
|
||||
# Информирование пользователя о сгенерированных ключах и сертификатах
|
||||
if [ "$LANG_RU" -eq 1 ]; then
|
||||
cat <<EOF
|
||||
Сгенерированный набор ключей для установки на сервер:
|
||||
|
||||
- [OUTPUTDATA] приватный ключ: \`$IMM_CA/private/$fst_elem.key.pem\`;
|
||||
- [OUTPUTDATA_CERT] сертификат сервера: \`$IMM_CA/certs/$fst_elem.cert.pem.$SEQ\`;
|
||||
- [OUTPUTDATA] цепочка CA: \`$IMM_CA/certs/ca-chain.cert.pem\`;
|
||||
- [OUTPUTDATA] список отмененных сертификатов: \`$IMM_CA/crl/ca-full.crl.pem\`
|
||||
EOF
|
||||
else
|
||||
cat <<EOF
|
||||
Generated key set for server installation:
|
||||
|
||||
- [OUTPUTDATA] private key: \`$IMM_CA/private/$fst_elem.key.pem\`;
|
||||
- [OUTPUTDATA_CERT] server certificate: \`$IMM_CA/certs/$fst_elem.cert.pem.$SEQ\`;
|
||||
- [OUTPUTDATA] CA chain: \`$IMM_CA/certs/ca-chain.cert.pem\`;
|
||||
- [OUTPUTDATA] revoked certificates list: \`$IMM_CA/crl/ca-full.crl.pem\`
|
||||
EOF
|
||||
fi
|
||||
|
||||
popd || exit
|
||||
|
||||
popd || exit
|
||||
90
utils/make_server_revoke.sh
Normal file
90
utils/make_server_revoke.sh
Normal file
@@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
|
||||
source config.sh
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
|
||||
CERT_REV=""
|
||||
|
||||
# Detect language: Russian if LANG or LC_ALL starts with 'ru'
|
||||
if [[ "${LANG:-$LC_ALL}" =~ ^ru|^ru_RU ]]; then
|
||||
IS_RUSSIAN=1
|
||||
else
|
||||
IS_RUSSIAN=0
|
||||
fi
|
||||
|
||||
# Helper to print messages in the appropriate language
|
||||
msg() {
|
||||
local en="$1"
|
||||
local ru="$2"
|
||||
if [ "$IS_RUSSIAN" -eq 1 ]; then
|
||||
echo "$ru"
|
||||
else
|
||||
echo "$en"
|
||||
fi
|
||||
}
|
||||
|
||||
# Проверка наличия и валидации параметров командной строки
|
||||
while getopts "s:n:h" opt; do
|
||||
case $opt in
|
||||
s) server=$OPTARG ;;
|
||||
n) CERT_REV=$OPTARG ;;
|
||||
h)
|
||||
msg "Usage: $0 -s <server domain name> -n <certificate reverse number>" "Использование: $0 -s <доменное имя сервера> -n <реверс-номер сертификата>"
|
||||
exit 0
|
||||
;;
|
||||
\?)
|
||||
msg "Invalid argument or missing parameter" "Неверный аргумент или пустой параметр" >&2
|
||||
msg "Usage: $0 -s <server domain name> -n <certificate reverse number>" "Использование: $0 -s <доменное имя сервера> -n <реверс-номер сертификата>" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$server" ]; then
|
||||
msg "Invalid arguments or missing parameters" "Неверные аргументы или пустые параметры" >&2
|
||||
msg "Usage: $0 -s <server domain name> -n <certificate reverse number>" "Использование: $0 -s <доменное имя сервера> -n <реверс-номер сертификата>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e "$PATH_TO_CA/server_certs/$server" ]; then
|
||||
msg "Resource does not exist $server" "Данного ресурса не существует $server" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd "$IMM_CA" || {
|
||||
msg "Error: Could not change directory to $IMM_CA" "Ошибка: Не удалось перейти в каталог $IMM_CA" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
}
|
||||
|
||||
if [ -z "$CERT_REV" ]; then
|
||||
files=("certs/$server.cert.pem".*)
|
||||
else
|
||||
files=("certs/$server.cert.pem.$CERT_REV")
|
||||
fi
|
||||
|
||||
for file in "${files[@]}"; do
|
||||
if [ -e "$file" ]; then
|
||||
if ! openssl ca -config "immissuer.conf" -revoke "$file" -passin "pass:$SERT_PASS"; then
|
||||
msg "Error executing openssl ca -revoke ($file)" "Ошибка при выполнении команды openssl ca -revoke ($file)" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if ! openssl ca -config "immissuer.conf" -gencrl -out crl/intermediate.crl.pem -passin "pass:$SERT_PASS"; then
|
||||
msg "Error executing openssl ca -gencrl" "Ошибка при выполнении команды openssl ca -gencrl" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
fi
|
||||
|
||||
if ! openssl crl -in crl/intermediate.crl.pem -noout -text; then
|
||||
msg "Error executing openssl crl" "Ошибка при выполнении команды openssl crl" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
fi
|
||||
|
||||
cat $ROOT_CA/crl/ca.crl.pem $IMM_CA/crl/intermediate.crl.pem >$IMM_CA/crl/ca-full.crl.pem
|
||||
|
||||
popd || {
|
||||
msg "Error: Could not popd from $IMM_CA" "Ошибка: Не удалось выполнить popd из $IMM_CA" >&2
|
||||
cd "$CURRENT_DIR" || exit 1
|
||||
}
|
||||
279
utils/prepare.sh
Normal file
279
utils/prepare.sh
Normal file
@@ -0,0 +1,279 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user