← Назад к вопросам
Как используется SSL сертификат?
1.8 Middle🔥 181 комментариев
#REST API и HTTP#Безопасность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
SSL/TLS Сертификаты: использование и применение
SSL (Secure Sockets Layer) / TLS (Transport Layer Security) сертификаты обеспечивают **безопасное шифрование данных** при передаче между клиентом и сервером, а также **проверку подлинности** сервера.
Как работает SSL/TLS
Принцип работы: HTTPS
Клиент Сервер
| |
|------ 1. ClientHello ------------------>|
| |
|<----- 2. ServerHello + Certificate -----|
| |
|------ 3. Key Exchange ----------------->|
| |
|<----- 4. Session Established -----------|
| |
|------ 5. Encrypted data ------->--------|
| |
Использование SSL в Python
1. Запросы HTTPS с проверкой сертификата
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.ssl_ import create_urllib3_context
# Простой запрос с проверкой сертификата (по умолчанию)
response = requests.get('https://api.example.com/data')
# Python автоматически проверяет сертификат!
# Отключить проверку (ОПАСНО!)
response = requests.get(
'https://api.example.com/data',
verify=False # НЕ ДЕЛАЙ ЭТОГО В ПРОДАКШЕНЕ
)
# Использовать кастомный сертификат
response = requests.get(
'https://api.example.com/data',
verify='/path/to/ca-bundle.crt'
)
# Использовать клиентский сертификат
response = requests.get(
'https://api.example.com/data',
cert=('/path/to/client.crt', '/path/to/client.key')
)
2. Async запросы с aiohttp
import aiohttp
import ssl
async def fetch():
# Стандартная проверка сертификата
async with aiohttp.ClientSession() as session:
async with session.get('https://api.example.com/data') as resp:
return await resp.json()
# С кастомным SSL контекстом
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False # Отключить проверку hostname
ssl_context.verify_mode = ssl.CERT_NONE # Отключить проверку сертификата
connector = aiohttp.TCPConnector(ssl=ssl_context)
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get('https://api.example.com/data') as resp:
return await resp.json()
3. FastAPI сервер с SSL
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Secure endpoint"}
if __name__ == "__main__":
# Запуск с SSL сертификатом
uvicorn.run(
app,
host="0.0.0.0",
port=443,
ssl_keyfile="/path/to/key.pem",
ssl_certfile="/path/to/cert.pem"
)
4. Flask сервер с SSL
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Secure endpoint"
if __name__ == "__main__":
# Запуск с SSL сертификатом
app.run(
host="0.0.0.0",
port=443,
ssl_context=(
"/path/to/cert.pem",
"/path/to/key.pem"
)
)
5. Django с SSL
# settings.py
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
STANDARD_FORCE_HTTPS_URLS = True
# Запуск dev сервера
# python manage.py runserver_plus --cert-file /path/to/cert.pem --key-file /path/to/key.pem
Работа с сертификатами
Проверка сертификата
import ssl
import socket
def check_certificate(hostname):
context = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
print(f"Certificate info: {cert}")
# Получить детали
print(f"Subject: {dict(x[0] for x in cert['subject'])}")
print(f"Issuer: {dict(x[0] for x in cert['issuer'])}")
print(f"Valid from: {cert['notBefore']}")
print(f"Valid until: {cert['notAfter']}")
check_certificate('google.com')
Проверка срока действия
import ssl
import socket
from datetime import datetime
def is_certificate_valid(hostname):
context = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
# Парсим дату истечения
exp_date_str = cert['notAfter']
exp_date = datetime.strptime(exp_date_str, '%b %d %H:%M:%S %Y %Z')
if datetime.now() < exp_date:
days_left = (exp_date - datetime.now()).days
print(f"Certificate valid, expires in {days_left} days")
return True
else:
print("Certificate expired")
return False
is_certificate_valid('github.com')
SSL/TLS в Nginx (reverse proxy для Python)
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# SSL параметры
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:8000; # Python приложение
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Редирект с HTTP на HTTPS
server {
listen 80;
server_name api.example.com;
return 301 https://$server_name$request_uri;
}
Self-signed сертификат для разработки
# Создание self-signed сертификата
openssl req -x509 -newkey rsa:4096 -nodes \
-out cert.pem -keyout key.pem -days 365
# Проверка
openssl x509 -in cert.pem -text -noout
# Использование self-signed в dev
response = requests.get(
'https://localhost:8000/data',
verify=False # Только для разработки!
)
Сертификаты Let's Encrypt (бесплатные)
# Установка certbot
pip install certbot certbot-nginx
# Получение сертификата
sudo certbot certonly --standalone -d api.example.com
# Сертификат сохранится в /etc/letsencrypt/live/api.example.com/
Мониторинг истечения сертификатов
import ssl
import socket
from datetime import datetime, timedelta
class CertificateMonitor:
def check_expiration(self, hostname: str, warning_days: int = 30):
"""Проверить, близко ли истечение сертификата"""
context = ssl.create_default_context()
try:
with socket.create_connection((hostname, 443), timeout=5) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
exp_date_str = cert['notAfter']
exp_date = datetime.strptime(exp_date_str, '%b %d %H:%M:%S %Y %Z')
days_left = (exp_date - datetime.now()).days
if days_left < 0:
return f"CRITICAL: Certificate expired!"
elif days_left < warning_days:
return f"WARNING: Certificate expires in {days_left} days"
else:
return f"OK: Certificate valid for {days_left} days"
except Exception as e:
return f"ERROR: {str(e)}"
monitor = CertificateMonitor()
print(monitor.check_expiration('google.com'))
Лучшие практики
- Всегда проверяй сертификаты в продакшене (verify=True по умолчанию)
- Не отключай проверку кроме разработки (verify=False опасно)
- Используй проверенные CA (Let's Encrypt, Comodo, DigiCert)
- Обновляй сертификаты перед истечением
- Используй TLSv1.2 и выше (TLSv1.0, TLSv1.1 устарели)
- Отслеживай дату истечения в мониторинге
- Используй HSTS для принудительного перенаправления на HTTPS
SSL/TLS — неотъемлемая часть безопасного веб-приложения. Правильная конфигурация защищает данные пользователей от перехвата.