← Назад к вопросам

Как запустить HTTPS?

1.6 Junior🔥 251 комментариев
#REST API и HTTP#Безопасность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как запустить HTTPS

HTTPS — это зашифрованный HTTP с использованием SSL/TLS протокола. Это критично для безопасности: передача данных шифруется, и пользователи видят, что сайт защищён. Рассмотрю несколько способов запуска HTTPS для Python приложений.

Что нужно для HTTPS

  1. SSL сертификат — подтверждает, что сайт принадлежит вам
  2. Приватный ключ — используется для расшифровки данных
  3. Веб-сервер, который поддерживает SSL/TLS

Способ 1: Self-signed сертификат (для разработки)

Для локальной разработки можно создать самоподписанный сертификат:

# Генерируем приватный ключ и сертификат на 365 дней
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365

# При запросе информации можно нажимать Enter или вводить данные
# Country Name: RU
# State: Moscow
# Locality: Moscow
# Organization Name: MyCompany
# Common Name: localhost

Теперь у вас есть cert.pem (сертификат) и key.pem (ключ).

Способ 2: FastAPI с HTTPS локально

import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/api/hello")
async def hello():
    return {"message": "Это защищённый HTTPS endpoint"}

if __name__ == "__main__":
    # Запуск с самоподписанным сертификатом
    uvicorn.run(
        app,
        host="127.0.0.1",
        port=8443,
        ssl_keyfile="key.pem",      # Путь к приватному ключу
        ssl_certfile="cert.pem",    # Путь к сертификату
        ssl_keyfile_password=None    # Если ключ не зашифрован
    )

Запуск:

python app.py
# Сервер запустится на https://127.0.0.1:8443

Тестирование (проигнорируем самоподписанный сертификат):

curl -k https://127.0.0.1:8443/api/hello
# или в Python
import requests
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
response = requests.get("https://127.0.0.1:8443/api/hello", verify=False)
print(response.json())

Способ 3: Flask с HTTPS

from flask import Flask

app = Flask(__name__)

@app.route("/api/hello", methods=["GET"])
def hello():
    return {"message": "Защищённый endpoint"}

if __name__ == "__main__":
    # Запуск с SSL
    app.run(
        host="127.0.0.1",
        port=8443,
        ssl_context=("cert.pem", "key.pem")  # (сертификат, ключ)
    )

Способ 4: Let's Encrypt для продакшена

Для боевого сервера используем Let's Encrypt — бесплатные сертификаты, которые автоматически обновляются.

Установка Certbot (инструмент для Let's Encrypt):

sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx  # или python3-certbot-apache

Получение сертификата для домена:

sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com

# Сертификаты будут в:
# /etc/letsencrypt/live/yourdomain.com/fullchain.pem (сертификат)
# /etc/letsencrypt/live/yourdomain.com/privkey.pem (ключ)

Использование в Python:

import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/api/hello")
async def hello():
    return {"message": "Защищённый endpoint на боевом сервере"}

if __name__ == "__main__":
    uvicorn.run(
        app,
        host="0.0.0.0",
        port=443,  # Стандартный порт для HTTPS
        ssl_keyfile="/etc/letsencrypt/live/yourdomain.com/privkey.pem",
        ssl_certfile="/etc/letsencrypt/live/yourdomain.com/fullchain.pem"
    )

Автоматическое обновление сертификата (cron):

# Добавляем в crontab
sudo crontab -e

# Добавляем строку (проверяет обновление сертификата каждый день в 3 утра)
0 3 * * * /usr/bin/certbot renew --quiet

Способ 5: Nginx как reverse proxy

Это рекомендуемый подход — Nginx обрабатывает SSL, Python работает на localhost.

1. Генерируем сертификат:

sudo certbot certonly --nginx -d yourdomain.com

2. Конфигурируем Nginx:

upstream fastapi_app {
    server 127.0.0.1:8000;  # Python приложение слушает локально
}

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    
    # Редирект с HTTP на HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;
    
    # SSL сертификаты от Let's Encrypt
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    
    # Безопасные параметры SSL
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    
    # HSTS — принудительно использовать HTTPS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    # Проксируем запросы на Python приложение
    location / {
        proxy_pass http://fastapi_app;
        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;
    }
}

3. Запускаем Python приложение обычно:

uvicorn app:app --host 127.0.0.1 --port 8000

4. Перезагружаем Nginx:

sudo systemctl reload nginx

Теперь https://yourdomain.com будет работать с полной шифровацией.

Способ 6: Docker с HTTPS

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

# Копируем сертификаты
COPY cert.pem /app/cert.pem
COPY key.pem /app/key.pem

EXPOSE 8443

CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8443", "--ssl-keyfile=/app/key.pem", "--ssl-certfile=/app/cert.pem"]

docker-compose.yml:

version: '3.9'
services:
  api:
    build: .
    ports:
      - "8443:8443"
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt:ro  # Монтируем сертификаты от хоста

Важные правила безопасности

  1. Никогда не коммитьте ключи — добавьте в .gitignore:
key.pem
privkey.pem
*.key
  1. Защищайте сертификаты — ограничивайте права доступа:
chmod 600 key.pem  # Только владелец может читать
  1. Используйте сильные цифровые подписи:
# В продакшене всегда требуйте HTTPS
from fastapi import FastAPI
from fastapi.middleware.trustedhost import TrustedHostMiddleware

app = FastAPI()
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["yourdomain.com"])

Проверка HTTPS

# Проверка сертификата
openssl s_client -connect yourdomain.com:443

# Просмотр информации о сертификате
openssl x509 -in cert.pem -text -noout

# Проверка срока действия
openssl x509 -in cert.pem -noout -dates

Вывод

  • Локально: самоподписанные сертификаты + uvicorn/Flask с SSL
  • Боевой сервер: Let's Encrypt + Nginx как reverse proxy
  • Docker: пробрасываем сертификаты как volumes

Найпо современный и безопасный подход — использовать Nginx + Let's Encrypt. Python приложение работает на localhost без SSL, а Nginx занимается шифрованием и редиректом с HTTP на HTTPS.