HTTPS для разработчиков

0
2
views
Photo by Franck on Unsplash

Если вы просто пользователь, и ваше взаимодействие с HTTPS ограничивается открытием URL в браузере, вам лучше почитать какую-нибудь из более легких статей, типа «Как работает HTTPS».

От редакции Techrocks. Мы можем предложить статью «Объяснение HTTPS на примере почтовых голубей».

Если вы занимаетесь криптографическими разработками, лучше начать с изучения криптографических примитивов, а затем почитать стандарты (RFCs).

Но если вы разработчик и хотите узнать достаточно технических подробностей о работе и использовании HTTPS в ваших приложениях, при этом не ныряя в глубины криптографии и веб-стандартов, эта статья как раз для вас!

О HTTPS

Представляя себе, что такое HTTPS, разработчик имеет в виду следующие вещи:

  • Для передачи данных по HTTPS сервер должен иметь «сертификаты», сгенерированные третьей стороной.
    • Эти сертификаты не просто генерируются, а покупаются у сторонних организаций.
  • Время жизни сертификатов ограничено.
    • Они «экспарятся» (от англ. expire — «прекращаться с истечением срока»).
    • Когда сертификат заэкспарился, его нужно обновить, то есть заново приобрести у третьей стороны.
  • Шифрование соединения происходит на уровне TCP.
    • Это на один уровень ниже HTTP.
    • Значит, использование сертификата и управление шифрованием осуществляются до HTTP.
  • TCP ничего не знает о доменах. Он знает только IP-адреса.
    • Информация о запрошенном домене поступает в HTTP-данных.
  • HTTPS-сертификаты «сертифицируют» определенный домен. Но протокол и шифрование происходят на TCP-уровне, когда еще неизвестно, о каком домене идет речь.
  • Это означает, что по умолчанию у вас может быть только один HTTPS-сертификат для одного IP-адреса.
    • Не важно, насколько велик ваш сервер и насколько мало каждое отдельное приложение на нем.
    • Но эта проблема решаема.
  • Есть расширение для TLS-протокола (именно он управляет шифрованием на TCP-уровне, до HTTP) — SNI.
    • Расширение SNI позволяет серверу (с одним IP-адресом) иметь несколько HTTPS-сертификатов и обслуживать несколько HTTPS доменов/приложений.
    • Чтобы это работало, отдельный компонент (программа), запущенный на сервере и прослушивающий публичный IP-адрес, должен иметь все HTTPS-сертификаты этого сервера.
  • После установки защищенного соединения протоколом коммуникации остается HTTP.
    • Хотя контент пересылается по HTTP-протоколу, он все равно шифруется.

TLS Termination Proxy

Распространенная практика — иметь один HTTP-сервер (т.е. программу) на сервере (машине, хосте). Этот сервер управляет всем, что касается HTTPS:

  • получением зашифрованных HTTPS-запросов,
  • отправкой расшифрованных HTTP-запросов к HTTP-приложению, запущенному на этом же сервере (в нашем примере — FastAPI-приложение),
  • получением HTTP-ответа от приложения, шифрованием этого ответа с использованием соответствующего HTTPS-сертификата,
  • отправкой зашифрованного ответа обратно клиенту с использованием HTTPS.

Этот сервер часто называют TLS termination proxy (прокси-сервером).

Есть несколько опций, которые можно использовать как TLS Termination Proxy:

  • Traefik (также может управлять обновлением сертификатов)
  • Caddy (также может управлять обновлением сертификатов)
  • Nginx
  • HAProxy

Let’s Encrypt

До появления Let’s Encrypt сертификаты продавались доверенными сторонними компаниями.

Процедура приобретения сертификата была обременительной. Она требовала работы с бумагами. Кроме того, сертификаты были довольно дороги.

Но затем появился Let’s Encrypt.

Это проект Linux Foundation. Он предлагает HTTPS-сертификаты бесплатно и автоматизированно. Эти сертификаты используют все стандартные подходы к безопасности, а «живут» только три месяца. Из-за такого короткого срока действия их защита даже лучше.

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

Основная идея Let’s Encrypt — автоматизация приобретения и обновления сертификатов, чтобы вы всегда могли иметь безопасный HTTPS, причем бесплатно.

HTTPS для разработчиков на примерах

Давайте рассмотрим (пошагово), как выглядит HTTPS API. Основное внимание уделим вещам, важным для разработчиков.

Доменное имя

Пожалуй, все начинается с покупки доменного имени. Затем вы настраиваете его в DNS-сервере (в роли DNS-сервера может выступать ваш облачный провайдер).

Вероятно, вы приобретете облачный сервер (виртуальную машину) или что-то типа того, и там будет постоянный публичный IP-адрес.

Чтобы ваш домен указывал на IP-адрес вашего сервера, вы настраиваете A record («А»-запись) на DNS-сервере.

Скорее всего вам придется проделать все это лишь однажды, при первоначальной настройке.

Примечание. Все действия, касающиеся доменного имени, проделываются задолго до действий, связанных непосредственно с HTTPS. Но все равно стоит упомянуть все, что касается домена и IP-адреса.

DNS

Теперь давайте сосредоточимся на том, что больше связано с HTTPS.

Все начинается с того, что браузер узнает IP домена при помощи DNS-серверов. В нашем примере домен — someapp.example.com.

DNS-сервера укажут браузеру соответствующий IP-адрес, который он должен использовать. Это будет публичный IP, используемый вашим сервером. Вы его прописали при помощи «А»-записи на DNS-сервере.

Начало TLS-рукопожатия

Затем браузер обратится по этому IP-адресу на порт 443 (это стандартный HTTPS-порт).

Первая часть коммуникации — просто установка соединения между клиентом и сервером и определение ключей шифрования, которые они будут использовать.

Взаимодействие между клиентом и сервером для установки TLS-соединения называется TLS-рукопожатием.

TLS с расширением SNI

На одном порту IP-адреса может прослушиваться только один процесс на сервере. Другие процессы могут прослушивать другие порты по тому же IP-адресу, но по каждой комбинации IP-адреса и порта прослушивается лишь один процесс.

TLS (HTTPS) по умолчанию использует порт 443. Поэтому нам понадобится именно этот порт.

Поскольку на этом порту может прослушиваться только один процесс, это должен быть процесс TLS Termination Proxy.

TLS Termination Proxy будет иметь доступ к одному или большему числу TLS (HTTPS) сертификатов.

При использовании расширения SNI (мы его упоминали ранее) TLS Termination Proxy будет определять, какой из имеющихся TLS (HTTPS) сертификатов следует использовать для каждого конкретного соединения. Это должен быть сертификат, соответствующий домену, который запрашивает клиент.

В нашем случае это будет сертификат для someapp.example.com.

Клиент доверяет организации, которая сгенерировала TLS-сертификат (в нашем случае это Let’s Encrypt). Поэтому эта организация может подтвердить валидность сертификата.

Затем, используя этот сертификат, клиент и TLS Termination Proxy решают, как зашифровать дальнейшую TCP-коммуникацию. Этим завершается TLS-рукопожатие.

После этого TCP-соединение клиента и сервера зашифровано — это обеспечивает TLS. Это соединение они могут использовать, чтобы начать собственно HTTP-коммуникацию.

Это и есть HTTPS. Это простой HTTP внутри защищенного TLS-соединения вместо чистого (незащищенного) TCP-соединения.

Примечание. Обратите внимание, что шифрование коммуникации происходит на уровне TCP, а не на уровне HTTP.

HTTPS-запрос

Теперь, когда между клиентом и сервером (если более конкретно — между браузером и TLS Termination Proxy) есть зашифрованное TCP-соединение, они могут начать HTTP-коммуникацию.

Клиент отсылает HTTPS-запрос. Это просто HTTP-запрос, проходящий по зашифрованному TLS-соединению.

Расшифровка запроса

Для расшифровки запроса TLS Termination Proxy использует оговоренное ранее шифрование. Он передает простой (расшифрованный) HTTP-запрос процессу, запускающему приложение (например, процессу, в котором Uvicorn запускает приложение FastAPI).

HTTP-ответ

Приложение обрабатывает запрос и отсылает простой (незашифрованный) HTTP-ответ на TLS Termination Proxy.

HTTPS-ответ

Далее TLS Termination Proxy шифрует этот ответ, используя оговоренное ранее шифрование (оно оговорено при помощи сертификата для someapp.example.com). Ответ в зашифрованном виде отсылается браузеру.

Браузер проверяет, валиден ли ответ и зашифрован ли он при помощи соответствующего криптографического ключа. Затем он расшифровывает ответ и обрабатывает его.

Клиент (браузер) знает, что ответ пришел с правильного сервера, потому что в нем использовано шифрование, оговоренное при помощи HTTPS-сертификата.

Несколько приложений на одном сервере

На одном сервере (или серверах) может быть много приложений. Например, другие API-программы или базы данных.

На одном порту по одному адресу обслуживается лишь один процесс (в нашем примере — TLS Termination Proxy). Но на сервере (или серверах) могут быть запущены и другие приложения/процессы, если только они не используют ту же комбинацию публичного IP и порта.

Таким образом, TLS Termination Proxy может управлять HTTPS и сертификатами для нескольких доменов и нескольких приложений, а затем передавать запросы соответствующим приложениям.

Обновление сертификата

Рано или поздно у каждого сертификата истекает срок годности (например, через три месяца после приобретения).

После этого специальная программа (иногда — тот же TLS Termination Proxy) обращается к Let’s Encrypt и возобновляет сертификат(ы).

TLS-сертификаты привязаны к доменному имени, не к IP-адресу.

Поэтому, чтобы обновить сертификаты, человеку или программе нужно доказать организации, генерирующей сертификаты, свое право собственности и контроль над доменом.

Это можно сделать разными способами. Например:

  • Модифицировать какие-нибудь DNS-записи.
    • Для этого программа должна поддерживать API DNS-провайдера. Поэтому то, доступен ли для вас такой вариант, зависит от вашего провайдера.
  • Запуститься как сервер на публичном IP-адресе, связанном с доменом (по крайней мере на время процедуры получения сертификата).
    • Как уже говорилось, на одном адресе и одном порту может прослушиваться только один процесс.
    • Это одна из причин, почему полезно «поручать» обновление сертификатов тому же TLS Termination Proxy.
    • Если обновлением занимается другая программа, вам нужно будет остановить TLS Termination Proxy, запустить другую программу для получения сертификатов, затем настроить их в TLS Termination Proxy и перезапустить его. Это не идеальный выход, потому что во время этой процедуры ваше приложение будет недоступно.

Вся эта процедура обновления — малоприятное занятие. И это основная причина, почему люди предпочитают иметь отдельную систему для управления HTTPS при помощи TLS Termination Proxy, а не просто подкладывать TLS-сертификаты в сервер приложения напрямую.

Итоги

HTTPS имеет большое значение, зачастую даже критически важное. Самое главное, что требуется от вас как разработчика, — понять саму концепцию HTTPS и принцип работы. Когда вы во всем этом хорошенько разберетесь, вы сможете без проблем комбинировать и настраивать различные инструменты, которые будут делать за вас большую часть работы, связанной с HTTPS.

Перевод статьи «HTTPS for Developers».

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here