📝 Adequate

OpenSSL — шпаргалка

Довідник типових OpenSSL операцій: генерація ключів, CSR, self-signed сертифікати, дебаг TLS. Теоретичний базис — TLS/SSL та Основи криптографії.

💡 Коли OpenSSL потрібен у UMTC
Caddy автоматично отримує Let's Encrypt сертифікати — звичайним сайтам OpenSSL не потрібен. Але він необхідний для: внутрішніх CA (mTLS між сервісами), Mailcow SSL під власні піддомени, перевірка чужих сертифікатів, mtls для Matrix federation, підпис пакетів та конфігів.

Генерація ключів

# RSA 4096 (стандарт для CA та серверних ключів)
openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:4096

# Ed25519 (швидший, сучасний — використовується у WireGuard, SSH)
openssl genpkey -algorithm ED25519 -out key.pem

# ECDSA P-256 (legacy-сумісність з браузерами)
openssl ecparam -name prime256v1 -genkey -noout -out key.pem

# Захистити приватний ключ паролем
openssl pkcs8 -topk8 -in key.pem -out key-encrypted.pem
# зняти пароль
openssl pkcs8 -in key-encrypted.pem -out key.pem

CSR — запит на сертифікат

# Інтерактивно
openssl req -new -key key.pem -out request.csr

# Одним викликом, без запитань
openssl req -new -key key.pem -out request.csr -subj \
  "/C=UA/ST=Kyiv/O=UMTC/OU=Infra/CN=wiki.umtc.local"

# CSR з Subject Alternative Names (обов'язково для сучасних сертифікатів)
cat > san.cnf <<'EOF'
[req]
distinguished_name = dn
req_extensions     = v3_req
prompt             = no

[dn]
CN = wiki.umtc.local
O  = UMTC

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = wiki.umtc.local
DNS.2 = www.wiki.umtc.local
IP.1  = 10.10.10.10
EOF

openssl req -new -key key.pem -out request.csr -config san.cnf

# Перевірити CSR
openssl req -in request.csr -noout -text
⚠️ CN без SAN не працює
Сучасні браузери та `curl` ігнорують `Common Name` і вимагають `Subject Alternative Name`. Завжди додавай SAN, навіть якщо він дублює CN.

Self-signed сертифікат

# Швидкий self-signed на 365 днів (для тестів/внутрішніх сервісів)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
  -days 365 -nodes \
  -subj "/C=UA/O=UMTC/CN=internal.umtc.local" \
  -addext "subjectAltName=DNS:internal.umtc.local,IP:10.10.10.20"

# Ed25519 версія
openssl req -x509 -newkey ED25519 -keyout key.pem -out cert.pem \
  -days 365 -nodes -subj "/CN=internal.umtc.local" \
  -addext "subjectAltName=DNS:internal.umtc.local"

Власний CA + підписаний сертифікат

# 1. Створити CA
openssl req -x509 -newkey rsa:4096 -keyout ca.key -out ca.crt \
  -days 3650 -nodes -subj "/CN=UMTC Root CA" \
  -addext "basicConstraints=critical,CA:TRUE" \
  -addext "keyUsage=critical,keyCertSign,cRLSign"

# 2. CSR для сервера
openssl req -new -newkey rsa:2048 -keyout server.key -out server.csr \
  -nodes -subj "/CN=mail.umtc.local" \
  -addext "subjectAltName=DNS:mail.umtc.local"

# 3. Підписати CSR своїм CA
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt -days 365 \
  -copy_extensions copy

# 4. Додати CA.crt в trust store клієнта (Ubuntu)
cp ca.crt /usr/local/share/ca-certificates/umtc-ca.crt
update-ca-certificates

Перевірка сертифікатів

# Прочитати сертифікат у людській формі
openssl x509 -in cert.pem -noout -text

# Тільки ключові поля
openssl x509 -in cert.pem -noout -subject -issuer -dates -ext subjectAltName

# Fingerprint
openssl x509 -in cert.pem -noout -fingerprint -sha256

# Ланцюг довіри
openssl verify -CAfile ca.crt server.crt

# Сертифікат з файлу + проміжні
openssl verify -CAfile root.crt -untrusted intermediate.crt server.crt

Debug TLS з'єднання

# Підключитись і показати сертифікат
openssl s_client -connect wiki.umtc.local:443 -servername wiki.umtc.local

# Тільки сертифікат без інтерактиву
echo | openssl s_client -connect wiki.umtc.local:443 -servername wiki.umtc.local 2>/dev/null \
  | openssl x509 -noout -dates -subject

# Показати весь ланцюг
openssl s_client -connect wiki.umtc.local:443 -showcerts </dev/null 2>/dev/null

# Перевірка підтримки TLS версії
openssl s_client -connect host:443 -tls1_2
openssl s_client -connect host:443 -tls1_3

# STARTTLS (SMTP submission 587)
openssl s_client -connect mail.umtc.local:587 -starttls smtp
openssl s_client -connect mail.umtc.local:993 -crlf                # IMAPS

# Перевірити OCSP
openssl s_client -connect host:443 -status </dev/null 2>/dev/null | grep -A 17 'OCSP response'

Перевірка відповідності ключ / сертифікат / CSR

# Modulus трьох артефактів має співпадати
openssl rsa  -in key.pem  -noout -modulus | sha256sum
openssl x509 -in cert.pem -noout -modulus | sha256sum
openssl req  -in csr.pem  -noout -modulus | sha256sum

# Для EC ключів modulus немає — порівнюй публічний ключ
openssl pkey -in key.pem  -pubout | sha256sum
openssl x509 -in cert.pem -pubkey -noout | sha256sum
ℹ️ Навіщо
Найчастіша помилка: на сервер поклали cert від одного CSR, а key — від іншого генерування. Браузер каже `ERR_SSL_PROTOCOL_ERROR`, сервіс не стартує. Порівняння modulus/публічного ключа одразу показує розбіжність.

Конвертація форматів

Формат Розширення Для чого
PEM .pem, .crt, .key Linux за замовчуванням, base64
DER .der, .cer Binary, Windows, Java
PKCS#12 .p12, .pfx Windows, Exchange, ключ+сертифікат разом
PKCS#7 .p7b Windows, тільки сертифікати без ключа
# PEM → DER
openssl x509 -in cert.pem -outform DER -out cert.der
openssl rsa  -in key.pem  -outform DER -out key.der

# DER → PEM
openssl x509 -in cert.der -inform DER -out cert.pem
openssl rsa  -in key.der  -inform DER -out key.pem

# PEM → PKCS#12 (для імпорту в Windows/email клієнт)
openssl pkcs12 -export -in cert.pem -inkey key.pem \
  -certfile ca.crt -out bundle.p12 -name "UMTC Mail"

# PKCS#12 → PEM
openssl pkcs12 -in bundle.p12 -nocerts -out key.pem -nodes
openssl pkcs12 -in bundle.p12 -nokeys  -clcerts -out cert.pem
openssl pkcs12 -in bundle.p12 -nokeys  -cacerts -out ca.pem

Швидка криптографія

# Хеші
openssl dgst -sha256 file.bin
openssl dgst -sha512 file.bin

# HMAC
openssl dgst -sha256 -hmac "secret-key" file.bin

# Випадкові байти (для ключів, паролів, токенів)
openssl rand -hex 32             # 64 hex символи
openssl rand -base64 32          # base64 паролі
openssl rand -out keyfile 32     # raw bytes у файл

# Base64 кодування
echo -n "text" | openssl base64
echo "dGV4dA==" | openssl base64 -d

# Шифрування файлу (симетричне, AES-256)
openssl enc -aes-256-gcm -pbkdf2 -in file.txt -out file.enc
openssl enc -d -aes-256-gcm -pbkdf2 -in file.enc -out file.txt

Troubleshooting

x509: certificate signed by unknown authority
- Симптом: curl чи браузер кидає помилку валідації, хоча сертифікат нібито валідний.
- Причина: сервер віддає тільки leaf-сертифікат без проміжного (intermediate). Клієнт не знає повного ланцюга.
- Рішення: у конфіг веб-сервера покласти fullchain.pem (leaf + intermediates), не просто cert.pem. Перевірка: openssl s_client -connect host:443 -showcerts | grep -c "BEGIN CERTIFICATE" має повертати ≥2. Для Caddy — він це робить автоматично.

SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
- Симптом: з'єднання обривається одразу після ClientHello.
- Причина: неспівпадіння версій TLS (сервер вимагає 1.3, клієнт дає 1.0), або немає спільного шифру, або SNI не передано.
- Рішення: openssl s_client -connect host:443 -servername host -tls1_3 — явно вказати версію. Подивитись cipher suites сервера: nmap --script ssl-enum-ciphers -p 443 host. Увімкнути debug у сервері (Caddy: log DEBUG, nginx: debug_connection).

Сертифікат видимий, але Caddy/nginx не стартує
- Симптом: cert.pem читається openssl x509 -in cert.pem -noout -text, але сервіс пише failed to load key або tls: private key does not match public key.
- Причина: key.pem і cert.pem — від різних генерувань (типово коли CSR згенерували двічі).
- Рішення: перевірити відповідність: openssl pkey -in key.pem -pubout | sha256sum і openssl x509 -in cert.pem -pubkey -noout | sha256sum мають давати однаковий хеш. Якщо різний — перегенерувати CSR з ПРАВИЛЬНОГО ключа і переотримати cert.

openssl s_client підключається, але перериває без помилки
- Симптом: s_client показує сертифікат, далі тиша, потім disconnect.
- Причина: STARTTLS-протокол (SMTP/IMAP/FTP) потребує явної команди, або сервер закриває idle connection.
- Рішення: для SMTP 587: openssl s_client -connect host:587 -starttls smtp -crlf; для IMAP STARTTLS: -starttls imap; для LDAP: -starttls ldap. Додати -crlf для нормальних line endings, -quiet щоб приховати handshake шум.


Пов'язані статті

  • TLS/SSL — теорія TLS, сертифікати, handshake
  • Основи криптографії — RSA, EC, симетрика
  • Hardening — TLS як частина захисту
  • Caddy — автоматичний TLS, коли OpenSSL не потрібен
  • mTLS — взаємна автентифікація клієнт/сервер
  • PKI, X.509 — формат сертифікатів

Шлях: reference/openssl-cheatsheet.md

UMTC Wiki © 2026 | Ukrainian Military Tactical Communications