Как запустить HTTPS-сервер на Python?

«Как запустить HTTPS-сервер на Python?» — вопрос из категории Сети, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Запуск HTTPS-сервера на Python требует наличия SSL/TLS сертификата и приватного ключа. Подходы различаются для разработки и production-среды.

1. Для разработки: встроенные модули

Можно использовать стандартные модули http.server и ssl. Это удобно для быстрого локального тестирования.

Шаг 1: Генерация самоподписанного сертификата Для локальной разработки можно создать сертификат с помощью OpenSSL. Браузер будет выдавать предупреждение о безопасности, так как сертификат не подписан доверенным центром.

# Создает ключ (server.key) и сертификат (server.pem) на 365 дней
openssl req -x509 -newkey rsa:4096 -nodes -out server.pem -keyout server.key -days 365

Шаг 2: Запуск сервера

from http.server import HTTPServer, SimpleHTTPRequestHandler
import ssl

# Адрес и порт сервера
server_address = ('localhost', 4443)

# Создание HTTP-сервера
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)

# Оборачивание сокета в SSL/TLS
httpd.socket = ssl.wrap_socket(
    httpd.socket,
    keyfile="server.key",  # Путь к приватному ключу
    certfile='server.pem', # Путь к сертификату
    server_side=True
)

print("Сервер запущен на https://localhost:4443")
httpd.serve_forever()

2. Для разработки: с веб-фреймворками

Фреймворки, такие как Flask или FastAPI (Uvicorn), также поддерживают запуск с SSL-контекстом, что удобно при разработке.

Пример с Flask:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "HTTPS работает!"

if __name__ == '__main__':
    # Указываем пути к сертификату и ключу
    app.run(ssl_context=('server.pem', 'server.key'))

3. Рекомендация для Production

В production-среде SSL/TLS-терминацию почти всегда выполняет reverse-proxy сервер (Nginx, Caddy), а не Python-приложение.

Почему?

  • Производительность: Nginx оптимизирован для обработки SSL-шифрования.
  • Безопасность: Разделение ответственности, приватные ключи не хранятся в коде приложения.
  • Управление: Проще управлять сертификатами (например, автоматическое обновление с помощью Let's Encrypt / Certbot) и конфигурацией.

Приложение (Gunicorn/Uvicorn) в этом случае работает по обычному HTTP, а Nginx принимает HTTPS-трафик и проксирует его на приложение.