Создание локального HTTPS-сервера

Последнее обновление: 09.12.2025

Разработка веб-приложений часто требует защищенного соединения (HTTPS) даже на локальной машине. Это необходимо, например, для тестирования Service Workers, доступа к камере/микрофону или проверки работы безопасных cookie. К счастью, Python позволяет поднять HTTPS-сервер буквально за пару минут, используя встроенные библиотеки и самоподписанный сертификат. Рассмотрим, как это сделать.

Генерация SSL-сертификата

Для работы HTTPS прежде всего необходим сертификат и приватный ключ. Поскольку мы работаем локально, мы можем сгенерировать самоподписанный сертификат с помощью утилиты openssl. Для этого откроем терминал, перейдем в папку нашего сервера и выполним следующую команду:

openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem

Что делает эта команда:

  • req -newkey rsa:2048: создает новый запрос на сертификат и 2048-битный ключ RSA.

  • -nodes: указывает не шифровать приватный ключ паролем (чтобы сервер мог запуститься автоматически).

  • -days 365: сертификат будет валиден 1 год.

  • -out cert.pem и -keyout key.pem: сохраняет сертификат и ключ в файлы cert.pem и key.pem соответственно

В процессе выполнения вас могут попросить ввести информацию о стране и организации. Для локального теста можно просто нажимать Enter для пропуска, или ввести любые значения.

В итоге в текущей папке появятся сертификат и ключ - файлы cert.pem и key.pem

Написание Python-скрипта

Определим в той же папке, где мы создали сертификаты, файл с именем app.py и пропишем в нем следующий код:

from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html; charset=utf-8")
        self.end_headers()
        self.wfile.write("<h1>Hello METANIT.COM</h1>".encode("utf-8"))

# Настройка SSL контекста
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile="cert.pem", keyfile="key.pem")

# Настройки запуска
hostName = "localhost"
serverPort = 4443

# Инициализация сервера
webServer = HTTPServer((hostName, serverPort), MyHandler)
# "Оборачиваем" сокет сервера в SSL-защиту
webServer.socket = context.wrap_socket(webServer.socket, server_side=True)

print(f"Сервер запущен: https://{hostName}:{serverPort}")

# Бесконечный цикл прослушивания порта
try: webServer.serve_forever()
except KeyboardInterrupt: pass

webServer.server_close()
print("Сервер остановлен...")

Разберем основные моменты:

  1. import ssl

    Для шифрования подключаем модуль ssl

  2. Далее создаем контекст безопасности ssl.SSLContext и загружаем в него сгенерированные на файлы cert.pem и key.pem

    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    context.load_cert_chain(certfile="cert.pem", keyfile="key.pem")
    
  3. Ключевой момент - берем обычный сокет нашего сервера и "оборачиваем" его в SSL, превращая HTTP в HTTPS.

    webServer.socket = context.wrap_socket(webServer.socket, server_side=True)

Для теста просто будет отправлять клиенту строку с кодом html.

Запустим наш скрипт на выполнение, откроем браузер и перейдем по адресу https://localhost:4443

HTTP-сервер на Python с HTTPS и SSL

При переходе на сайт ваш браузер выдаст предупреждение о безопасности: "Your connection is not private" (Ваше подключение не защищено). Это нормально. Дело в том, что браузеры доверяют только сертификатам, подписанным авторитетными центрами сертификации. Наш автосгенерированный сертификат является самоподписанным (подписан нами же). Поэтому браузер не может подтвердить нашу личность. Что делать в этом случае? Для локальной разработки нажмем на кнопку "Advanced" (Дополнительно) и выберем "Proceed to localhost" (Перейти на сайт (небезопасно)).

HTTP-сервер на Python с SSL и HTTPS HTTPS-сервер на Python с ssl.SSLContext
Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850