✅ Good
TLS/SSL детально¶
Історія: SSL → TLS¶
flowchart LR
subgraph Deprecated ["❌ Deprecated"]
SSL1[SSL 1.0<br/>1994]
SSL2[SSL 2.0<br/>1995]
SSL3[SSL 3.0<br/>1996]
TLS10[TLS 1.0<br/>1999]
TLS11[TLS 1.1<br/>2006]
end
subgraph OK ["✅ Supported"]
TLS12[TLS 1.2<br/>2008]
end
subgraph Best ["⭐ Recommended"]
TLS13[TLS 1.3<br/>2018]
end
SSL1 --> SSL2 --> SSL3 --> TLS10 --> TLS11 --> TLS12 --> TLS13
style SSL1 fill:#ef4444,color:#fff
style SSL2 fill:#ef4444,color:#fff
style SSL3 fill:#ef4444,color:#fff
style TLS10 fill:#f97316,color:#fff
style TLS11 fill:#f97316,color:#fff
style TLS12 fill:#22c55e,color:#fff
style TLS13 fill:#3b82f6,color:#fff
Примітка
"SSL" сьогодні = TLS (назва залишилась історично)
TLS 1.2 Handshake¶
sequenceDiagram
participant C as 💻 Client
participant S as 🖥️ Server
rect rgb(200, 220, 255)
Note over C,S: Round Trip 1
C->>S: ClientHello
Note right of C: TLS versions, cipher suites, random
S->>C: ServerHello
Note left of S: Selected version, cipher, random
S->>C: Certificate
Note left of S: X.509 cert + chain
S->>C: ServerKeyExchange
Note left of S: ECDHE params (for PFS)
S->>C: ServerHelloDone
end
Note over C: Verify certificate
rect rgb(200, 255, 220)
Note over C,S: Round Trip 2
C->>S: ClientKeyExchange
Note right of C: Pre-master secret
C->>S: ChangeCipherSpec
C->>S: Finished
S->>C: ChangeCipherSpec
S->>C: Finished
end
rect rgb(180, 180, 255)
Note over C,S: 🔒 Encrypted Application Data
C-->>S: HTTPS Request
S-->>C: HTTPS Response
end
Примітка
TLS 1.2 потребує 2 RTT (Round Trip Times) для встановлення з'єднання.
TLS 1.3 Handshake¶
sequenceDiagram
participant C as 💻 Client
participant S as 🖥️ Server
rect rgb(200, 255, 200)
Note over C,S: 1 RTT Only!
C->>S: ClientHello + KeyShare
Note right of C: Versions, ciphers, ECDHE key
S->>C: ServerHello + KeyShare
Note left of S: Selected cipher, ECDHE key
Note over C,S: 🔒 Encryption starts here
S-->>C: {EncryptedExtensions}
S-->>C: {Certificate}
S-->>C: {CertificateVerify}
S-->>C: {Finished}
C-->>S: {Finished}
end
rect rgb(180, 180, 255)
Note over C,S: 🔒 Encrypted Application Data
C-->>S: HTTPS Request
S-->>C: HTTPS Response
end
Порада
TLS 1.3 потребує лише 1 RTT! Для повторних з'єднань можливий 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 (Ланцюг довіри)¶
flowchart TB
subgraph Browser ["🌐 Browser/OS Trust Store"]
Root[🔒 Root CA<br/>ISRG Root X1<br/>Self-signed]
end
subgraph Chain ["Certificate Chain"]
Int[📜 Intermediate CA<br/>Let's Encrypt Authority X3<br/>Signed by Root]
Leaf[📄 Leaf Certificate<br/>example.com<br/>Signed by Intermediate]
end
Root -->|signs| Int
Int -->|signs| Leaf
Server[🖥️ Server] -.->|sends| Leaf
Server -.->|sends| Int
style Root fill:#22c55e,color:#fff
style Int fill:#3b82f6,color:#fff
style Leaf fill:#8b5cf6,color:#fff
Примітка
Браузер перевіряє ланцюг від Leaf до Root. Root CA вже є в довірених сертифікатах ОС/браузера.
Типи сертифікатів¶
| Тип | Перевірка | Час видачі | Вартість |
|---|---|---|---|
| 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)¶
flowchart TB
subgraph NoPFS ["❌ Без PFS (RSA key exchange)"]
direction LR
K1[🔑 Server Key]
S1[Session 1]
S2[Session 2]
S3[Session 3]
K1 -->|encrypts| S1
K1 -->|encrypts| S2
K1 -->|encrypts| S3
Stolen[🔓 Key stolen!]
Stolen -.->|decrypts ALL| S1
Stolen -.->|decrypts ALL| S2
Stolen -.->|decrypts ALL| S3
end
subgraph PFS ["✅ З PFS (ECDHE)"]
direction LR
E1[🔑 Ephemeral 1]
E2[🔑 Ephemeral 2]
E3[🔑 Ephemeral 3]
P1[Session 1]
P2[Session 2]
P3[Session 3]
E1 -->|encrypts| P1
E2 -->|encrypts| P2
E3 -->|encrypts| P3
Stolen2[🔓 Server key stolen]
Stolen2 -.->|Cannot decrypt!| P1
Stolen2 -.->|Cannot decrypt!| P2
Stolen2 -.->|Cannot decrypt!| P3
end
style Stolen fill:#ef4444,color:#fff
style Stolen2 fill:#22c55e,color:#fff
Увага
ЗАВЖДИ використовувати ECDHE! Ephemeral keys видаляються після сесії, тому минулі сесії залишаються захищеними навіть якщо приватний ключ сервера вкрадено.
Конфігурація веб-серверів¶
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)¶
flowchart LR
subgraph Regular ["Звичайний TLS"]
C1[💻 Client] -->|перевіряє| S1[🖥️ Server Cert]
end
subgraph Mutual ["mTLS (Mutual TLS)"]
C2[💻 Client] -->|перевіряє| S2[🖥️ Server Cert]
S3[🖥️ Server] -->|перевіряє| C3[📜 Client Cert]
end
style S1 fill:#3b82f6,color:#fff
style S2 fill:#3b82f6,color:#fff
style C3 fill:#22c55e,color:#fffВикористання mTLS:
- Мікросервіси (service mesh)
- API між серверами
- Корпоративні VPN
- IoT пристрої
Порада
При mTLS обидві сторони автентифікуються сертифікатами. Це значно підвищує безпеку.
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