TLS/SSL детально¶
Історія: SSL → TLS¶
┌─────────────────────────────────────────────────────────────────┐
│ Еволюція протоколів: │
│ │
│ SSL 1.0 (1994) — ніколи не випущений │
│ SSL 2.0 (1995) — небезпечний, deprecated │
│ SSL 3.0 (1996) — небезпечний (POODLE), deprecated │
│ TLS 1.0 (1999) — небезпечний, deprecated │
│ TLS 1.1 (2006) — небезпечний, deprecated │
│ TLS 1.2 (2008) — ОК, широко використовується │
│ TLS 1.3 (2018) — РЕКОМЕНДОВАНО, найбезпечніший │
│ │
│ "SSL" сьогодні = TLS (назва залишилась історично) │
└─────────────────────────────────────────────────────────────────┘
TLS 1.2 Handshake¶
┌─────────────────────────────────────────────────────────────────┐
│ Client Server │
│ │ │ │
│ │ ─────────── ClientHello ─────────────────────▶ │ │
│ │ • Supported TLS versions │ │
│ │ • Cipher suites │ │
│ │ • Random bytes │ │
│ │ │ │
│ │ ◀─────────── ServerHello ───────────────────── │ │
│ │ • Selected TLS version │ │
│ │ • Selected cipher suite │ │
│ │ • Random bytes │ │
│ │ │ │
│ │ ◀─────────── Certificate ───────────────────── │ │
│ │ • Server's X.509 certificate │ │
│ │ • Certificate chain │ │
│ │ │ │
│ │ ◀─────────── ServerKeyExchange ─────────────── │ │
│ │ • DH/ECDH parameters (for PFS) │ │
│ │ │ │
│ │ ◀─────────── ServerHelloDone ──────────────── │ │
│ │ │ │
│ │ [Client verifies certificate] │ │
│ │ │ │
│ │ ─────────── ClientKeyExchange ─────────────▶ │ │
│ │ • Pre-master secret (encrypted with server key)│ │
│ │ │ │
│ │ ─────────── ChangeCipherSpec ──────────────▶ │ │
│ │ ─────────── Finished ──────────────────────▶ │ │
│ │ │ │
│ │ ◀─────────── ChangeCipherSpec ─────────────── │ │
│ │ ◀─────────── Finished ────────────────────── │ │
│ │ │ │
│ │ ═══════════ Encrypted Application Data ══════│ │
│ │ │ │
│ │ 2 RTT (Round Trip Times) для з'єднання │ │
└─────────────────────────────────────────────────────────────────┘
TLS 1.3 Handshake¶
┌─────────────────────────────────────────────────────────────────┐
│ Client Server │
│ │ │ │
│ │ ─────────── ClientHello ─────────────────────▶ │ │
│ │ • Supported versions │ │
│ │ • Cipher suites │ │
│ │ • Key share (ECDHE) │ │
│ │ │ │
│ │ ◀─────────── ServerHello ───────────────────── │ │
│ │ • Selected version │ │
│ │ • Key share │ │
│ │ │ │
│ │ ◀─────────── {EncryptedExtensions} ─────────── │ │
│ │ ◀─────────── {Certificate} ─────────────────── │ │
│ │ ◀─────────── {CertificateVerify} ──────────── │ │
│ │ ◀─────────── {Finished} ────────────────────── │ │
│ │ │ │
│ │ ─────────── {Finished} ──────────────────────▶ │ │
│ │ │ │
│ │ ═══════════ Encrypted Application Data ══════│ │
│ │ │ │
│ │ 1 RTT (Round Trip Time) для з'єднання! │ │
│ │ 0-RTT можливий для повторних з'єднань │ │
└─────────────────────────────────────────────────────────────────┘
TLS 1.3 покращення¶
| Аспект | TLS 1.2 | TLS 1.3 |
|---|---|---|
| Handshake RTT | 2 | 1 (або 0) |
| Cipher suites | Багато (деякі слабкі) | Тільки безпечні |
| Key exchange | RSA, DHE, ECDHE | Тільки ECDHE |
| Encryption | CBC, GCM | Тільки AEAD |
| 0-RTT resumption | Ні | Так |
X.509 Сертифікати¶
Структура сертифіката¶
┌─────────────────────────────────────────────────────────────────┐
│ X.509 Certificate │
├─────────────────────────────────────────────────────────────────┤
│ Version: 3 (0x2) │
│ Serial Number: 03:a4:5b:... │
│ Signature Algorithm: sha256WithRSAEncryption │
│ │
│ Issuer: CN=Let's Encrypt Authority X3 │
│ O=Let's Encrypt │
│ C=US │
│ │
│ Validity: │
│ Not Before: Jan 1 00:00:00 2026 GMT │
│ Not After: Apr 1 00:00:00 2026 GMT │
│ │
│ Subject: CN=example.com │
│ │
│ Subject Public Key: RSA 2048 bits │
│ 30:82:01:0a:02:82:01:01:00:... │
│ │
│ X509v3 Extensions: │
│ Subject Alt Name: DNS:example.com, DNS:www.example.com │
│ Key Usage: Digital Signature, Key Encipherment │
│ Extended Key Usage: TLS Web Server Authentication │
│ │
│ Signature: 3c:7a:b2:... (підписано CA) │
└─────────────────────────────────────────────────────────────────┘
Certificate Chain (Ланцюг довіри)¶
┌─────────────────────────────────────────────────────────────────┐
│ │
│ Root CA Certificate (self-signed) │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Subject: CN=ISRG Root X1 │ │
│ │ Issuer: CN=ISRG Root X1 (self-signed) │ │
│ │ Зберігається в ОС/браузері │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │ │
│ │ signs │
│ ▼ │
│ Intermediate CA Certificate │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Subject: CN=Let's Encrypt Authority X3 │ │
│ │ Issuer: CN=ISRG Root X1 │ │
│ │ Сервер надсилає разом з leaf сертифікатом │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │ │
│ │ signs │
│ ▼ │
│ End-Entity (Leaf) Certificate │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Subject: CN=example.com │ │
│ │ Issuer: CN=Let's Encrypt Authority X3 │ │
│ │ Сертифікат вашого сервера │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Типи сертифікатів¶
| Тип | Перевірка | Час видачі | Вартість |
|---|---|---|---|
| DV (Domain Validated) | Тільки домен | Хвилини | Безкоштовно (Let's Encrypt) |
| OV (Organization Validated) | Домен + організація | Дні | $$ |
| EV (Extended Validation) | Повна перевірка | Тижні | $$$ |
Let's Encrypt¶
Отримання сертифіката¶
# Встановити certbot
apt install certbot
# Для nginx
certbot --nginx -d example.com -d www.example.com
# Для Apache
certbot --apache -d example.com
# Standalone (без веб-сервера)
certbot certonly --standalone -d example.com
# Webroot (з існуючим веб-сервером)
certbot certonly --webroot -w /var/www/html -d example.com
Автоматичне оновлення¶
# Certbot автоматично додає cron/timer
# Перевірити timer
systemctl status certbot.timer
# Тест renewal
certbot renew --dry-run
# Manual renewal
certbot renew
Сертифікати розміщуються в¶
/etc/letsencrypt/live/example.com/
├── cert.pem # Сертифікат
├── chain.pem # Intermediate certificates
├── fullchain.pem # cert.pem + chain.pem
└── privkey.pem # Приватний ключ
Cipher Suites¶
Структура cipher suite¶
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
│ │ │ │ │ │
│ │ │ │ │ └── PRF hash (TLS 1.2)
│ │ │ │ └─────── AEAD mode
│ │ │ └───────────── Key size
│ │ └───────────────────── Encryption algorithm
│ └─────────────────────────── Authentication
└──────────────────────────────── Key exchange
Рекомендовані cipher suites¶
TLS 1.3 (автоматично безпечні):
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
TLS 1.2 (вибіркові):
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Що уникати¶
┌─────────────────────────────────────────────────────────────────┐
│ НЕ ВИКОРИСТОВУВАТИ: │
│ │
│ • *_RSA_* key exchange (без ECDHE/DHE) — немає PFS │
│ • *_CBC_* modes — вразливі до BEAST, Lucky13 │
│ • *_RC4_* — зламаний │
│ • *_DES_*, *_3DES_* — слабкі/повільні │
│ • *_MD5*, *_SHA1* — застарілі хеші │
│ • *_EXPORT_* — навмисно ослаблені │
│ • *_NULL_* — без шифрування │
│ • *_anon_* — без автентифікації │
└─────────────────────────────────────────────────────────────────┘
Perfect Forward Secrecy (PFS)¶
┌─────────────────────────────────────────────────────────────────┐
│ Без PFS (RSA key exchange): │
│ │
│ • Session key зашифрований RSA ключем сервера │
│ • Якщо приватний ключ вкрадено → ВСІ минулі сесії можна │
│ розшифрувати! │
│ │
├─────────────────────────────────────────────────────────────────┤
│ З PFS (ECDHE/DHE): │
│ │
│ • Кожна сесія має унікальний ephemeral key │
│ • Session key генерується через Diffie-Hellman │
│ • Ephemeral keys видаляються після сесії │
│ • Якщо приватний ключ вкрадено → минулі сесії ЗАХИЩЕНІ │
│ │
│ ЗАВЖДИ використовувати ECDHE! │
└─────────────────────────────────────────────────────────────────┘
Конфігурація веб-серверів¶
Nginx¶
server {
listen 443 ssl http2;
server_name example.com;
# Сертифікати
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Протоколи
ssl_protocols TLSv1.2 TLSv1.3;
# Cipher suites
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
# Session
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
}
Caddy (автоматичний HTTPS)¶
example.com {
# Автоматично отримує сертифікат від Let's Encrypt
# Автоматично налаштовує TLS 1.2/1.3
# Автоматично оновлює сертифікат
root * /var/www/html
file_server
}
Apache¶
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder off
Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>
mTLS (Mutual TLS)¶
┌─────────────────────────────────────────────────────────────────┐
│ Звичайний TLS: │
│ Client ─────────── перевіряє ─────────▶ Server Certificate │
│ │
│ mTLS (Mutual TLS): │
│ Client ─────────── перевіряє ─────────▶ Server Certificate │
│ Client Certificate ◀───────── перевіряє ─────────── Server │
│ │
│ Обидві сторони автентифікуються! │
│ │
│ Використання: │
│ • Мікросервіси (service mesh) │
│ • API між серверами │
│ • Корпоративні VPN │
│ • IoT пристрої │
└─────────────────────────────────────────────────────────────────┘
Nginx mTLS¶
server {
listen 443 ssl;
ssl_certificate /etc/ssl/server.crt;
ssl_certificate_key /etc/ssl/server.key;
# Client certificate verification
ssl_client_certificate /etc/ssl/ca.crt;
ssl_verify_client on; # або 'optional'
ssl_verify_depth 2;
}
Діагностика TLS¶
OpenSSL¶
# Перевірити з'єднання
openssl s_client -connect example.com:443
# Показати сертифікат
openssl s_client -connect example.com:443 -showcerts
# Перевірити конкретну версію TLS
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
# Перевірити дату закінчення
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
# Детальна інформація про сертифікат
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text
testssl.sh¶
# Встановити
git clone https://github.com/drwetter/testssl.sh.git
# Запустити
./testssl.sh example.com
./testssl.sh --protocols example.com
./testssl.sh --vulnerable example.com
Nmap¶
# SSL/TLS інформація
nmap --script ssl-enum-ciphers -p 443 example.com
# Перевірка вразливостей
nmap --script ssl-heartbleed -p 443 example.com
Онлайн інструменти¶
- SSL Labs: https://www.ssllabs.com/ssltest/
- ImmuniWeb: https://www.immuniweb.com/ssl/
- CryptCheck: https://cryptcheck.fr/
Certificate Pinning¶
┌─────────────────────────────────────────────────────────────────┐
│ Certificate Pinning — додатковий захист від MITM │
│ │
│ Клієнт "пам'ятає" очікуваний сертифікат/ключ сервера │
│ Якщо сертифікат інший — відхиляє з'єднання │
│ │
│ Типи: │
│ • Pin certificate — весь сертифікат │
│ • Pin public key — тільки публічний ключ (рекомендовано) │
│ │
│ Проблема: якщо ключ змінився — клієнт не зможе з'єднатись! │
│ Потрібен backup pin │
└─────────────────────────────────────────────────────────────────┘
HPKP (застарілий)¶
# HTTP header (deprecated, не рекомендовано)
Public-Key-Pins: pin-sha256="base64=="; max-age=5184000
Certificate Transparency¶
┌─────────────────────────────────────────────────────────────────┐
│ Certificate Transparency — публічний лог всіх сертифікатів │
│ │
│ • CA повинен публікувати сертифікати в CT лог │
│ • Браузери перевіряють наявність SCT (Signed Certificate │
│ Timestamp) │
│ • Можна виявити неавторизовано випущені сертифікати │
│ │
│ Моніторинг: https://crt.sh/?q=example.com │
└─────────────────────────────────────────────────────────────────┘
Типові помилки¶
| Помилка | Причина | Рішення |
|---|---|---|
| Certificate expired | Сертифікат прострочений | Оновити сертифікат |
| Certificate not trusted | Немає intermediate cert | Додати chain |
| Hostname mismatch | CN не співпадає з доменом | Перевірити SAN |
| Self-signed | Немає CA підпису | Отримати від CA |
| Weak cipher | Слабкий cipher suite | Оновити конфігурацію |
| TLS version not supported | Старий TLS | Увімкнути TLS 1.2/1.3 |
Підсумок¶
Рекомендована конфігурація:
- Протоколи: TLS 1.2 + TLS 1.3
- Cipher suites: ECDHE + AES-GCM або ChaCha20
- Сертифікат: Let's Encrypt (автоматичне оновлення)
- Headers: HSTS enabled
- OCSP: Stapling увімкнено
Перевірте свій сайт на https://www.ssllabs.com/ssltest/ — мета A+
Див. також¶
- Основи криптографії — теоретична база
- Firewall Linux — захист мережі
- OSI L6 — рівень представлення
Шлях: security/tls-ssl.md