From d56f02a9868ae6f90d2233ad5d12b25213774cb7 Mon Sep 17 00:00:00 2001 From: Vladislav Kramorenko <85196001+Xewus@users.noreply.github.com> Date: Mon, 8 May 2023 14:11:00 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20Add=20Russian=20translation=20fo?= =?UTF-8?q?r=20`docs/ru/docs/deployment/https.md`=20(#9428)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Artem Golicyn <86262613+AGolicyn@users.noreply.github.com> Co-authored-by: Sebastián Ramírez --- docs/ru/docs/deployment/https.md | 198 +++++++++++++++++++++++++++++++ docs/ru/mkdocs.yml | 1 + 2 files changed, 199 insertions(+) create mode 100644 docs/ru/docs/deployment/https.md diff --git a/docs/ru/docs/deployment/https.md b/docs/ru/docs/deployment/https.md new file mode 100644 index 000000000..a53ab6927 --- /dev/null +++ b/docs/ru/docs/deployment/https.md @@ -0,0 +1,198 @@ +# Об HTTPS + +Обычно представляется, что HTTPS это некая опция, которая либо "включена", либо нет. + +Но всё несколько сложнее. + +!!! tip "Заметка" + Если Вы торопитесь или Вам не интересно, можете перейти на следующую страницу этого пошагового руководства по размещению приложений на серверах с использованием различных технологий. + +Чтобы **изучить основы HTTPS** для клиента, перейдите по ссылке https://howhttps.works/. + +Здесь же представлены некоторые концепции, которые **разработчик** должен иметь в виду при размышлениях об HTTPS: + +* Протокол HTTPS предполагает, что **серверу** нужно **располагать "сертификатами"** сгенерированными **третьей стороной**. + * На самом деле эти сертификаты **приобретены** у третьей стороны, а не "сгенерированы". +* У сертификатов есть **срок годности**. + * Срок годности **истекает**. + * По истечении срока годности их нужно **обновить**, то есть **снова получить** у третьей стороны. +* Шифрование соединения происходит **на уровне протокола TCP**. + * Протокол TCP находится на один уровень **ниже протокола HTTP**. + * Поэтому **проверка сертификатов и шифрование** происходит **до HTTP**. +* **TCP не знает о "доменах"**, но знает об IP-адресах. + * Информация о **запрашиваемом домене** извлекается из запроса **на уровне HTTP**. +* **Сертификаты HTTPS** "сертифицируют" **конкретный домен**, но проверка сертификатов и шифрование данных происходит на уровне протокола TCP, то есть **до того**, как станет известен домен-получатель данных. +* **По умолчанию** это означает, что у Вас может быть **только один сертификат HTTPS на один IP-адрес**. + * Не важно, насколько большой у Вас сервер и насколько маленькие приложения на нём могут быть. + * Однако, у этой проблемы есть **решение**. +* Существует **расширение** протокола **TLS** (который работает на уровне TCP, то есть до HTTP) называемое **SNI**. + * Расширение SNI позволяет одному серверу (с **одним IP-адресом**) иметь **несколько сертификатов HTTPS** и обслуживать **множество HTTPS-доменов/приложений**. + * Чтобы эта конструкция работала, **один** её компонент (программа) запущенный на сервере и слушающий **публичный IP-адрес**, должен иметь **все сертификаты HTTPS** для этого сервера. +* **После** установления защищённого соединения, протоколом передачи данных **остаётся HTTP**. + * Но данные теперь **зашифрованы**, несмотря на то, что они передаются по **протоколу HTTP**. + +Обычной практикой является иметь **одну программу/HTTP-сервер** запущенную на сервере (машине, хосте и т.д.) и **ответственную за всю работу с HTTPS**: + +* получение **зашифрованных HTTPS-запросов** +* отправка **расшифрованных HTTP запросов** в соответствующее HTTP-приложение, работающее на том же сервере (в нашем случае, это приложение **FastAPI**) +* получние **HTTP-ответа** от приложения +* **шифрование ответа** используя подходящий **сертификат HTTPS** +* отправка зашифрованного **HTTPS-ответа клиенту**. +Такой сервер часто называют **Прокси-сервер завершения работы TLS** или просто "прокси-сервер". + +Вот некоторые варианты, которые Вы можете использовать в качестве такого прокси-сервера: + +* Traefik (может обновлять сертификаты) +* Caddy (может обновлять сертификаты) +* Nginx +* HAProxy + +## Let's Encrypt (центр сертификации) + +До появления Let's Encrypt **сертификаты HTTPS** приходилось покупать у третьих сторон. + +Процесс получения такого сертификата был трудоёмким, требовал предоставления подтверждающих документов и сертификаты стоили дорого. + +Но затем консорциумом Linux Foundation был создан проект **Let's Encrypt**. + +Он автоматически предоставляет **бесплатные сертификаты HTTPS**. Эти сертификаты используют все стандартные криптографические способы шифрования. Они имеют небольшой срок годности (около 3 месяцев), благодаря чему они даже **более безопасны**. + +При запросе на получение сертификата, он автоматически генерируется и домен проверяется на безопасность. Это позволяет обновлять сертификаты автоматически. + +Суть идеи в автоматическом получении и обновлении этих сертификатов, чтобы все могли пользоваться **безопасным HTTPS. Бесплатно. В любое время.** + +## HTTPS для разработчиков + +Ниже, шаг за шагом, с заострением внимания на идеях, важных для разработчика, описано, как может выглядеть HTTPS API. + +### Имя домена + +Чаще всего, всё начинается с **приобретения имени домена**. Затем нужно настроить DNS-сервер (вероятно у того же провайдера, который выдал Вам домен). + +Далее, возможно, Вы получаете "облачный" сервер (виртуальную машину) или что-то типа этого, у которого есть постоянный **публичный IP-адрес**. + +На DNS-сервере (серверах) Вам следует настроить соответствующую ресурсную запись ("`запись A`"), указав, что **Ваш домен** связан с публичным **IP-адресом Вашего сервера**. + +Обычно эту запись достаточно указать один раз, при первоначальной настройке всего сервера. + +!!! tip "Заметка" + Уровни протоколов, работающих с именами доменов, намного ниже HTTPS, но об этом следует упомянуть здесь, так как всё зависит от доменов и IP-адресов. + +### DNS + +Теперь давайте сфокусируемся на работе с HTTPS. + +Всё начинается с того, что браузер спрашивает у **DNS-серверов**, какой **IP-адрес связан с доменом**, для примера возьмём домен `someapp.example.com`. + +DNS-сервера присылают браузеру определённый **IP-адрес**, тот самый публичный IP-адрес Вашего сервера, который Вы указали в ресурсной "записи А" при настройке. + + + +### Рукопожатие TLS + +В дальнейшем браузер будет взаимодействовать с этим IP-адресом через **port 443** (общепринятый номер порта для HTTPS). + +Первым шагом будет установление соединения между клиентом (браузером) и сервером и выбор криптографического ключа (для шифрования). + + + +Эта часть клиент-серверного взаимодействия устанавливает TLS-соединение и называется **TLS-рукопожатием**. + +### TLS с расширением SNI + +На сервере **только один процесс** может прослушивать определённый **порт** определённого **IP-адреса**. На сервере могут быть и другие процессы, слушающие другие порты этого же IP-адреса, но никакой процесс не может быть привязан к уже занятой комбинации IP-адрес:порт. Эта комбинация называется "сокет". + +По умолчанию TLS (HTTPS) использует порт `443`. Потому этот же порт будем использовать и мы. + +И раз уж только один процесс может слушать этот порт, то это будет процесс **прокси-сервера завершения работы TLS**. + +Прокси-сервер завершения работы TLS будет иметь доступ к одному или нескольким **TLS-сертификатам** (сертификаты HTTPS). + +Используя **расширение SNI** упомянутое выше, прокси-сервер из имеющихся сертификатов TLS (HTTPS) выберет тот, который соответствует имени домена, указанному в запросе от клиента. + +То есть будет выбран сертификат для домена `someapp.example.com`. + + + +Клиент уже **доверяет** тому, кто выдал этот TLS-сертификат (в нашем случае - Let's Encrypt, но мы ещё обсудим это), потому может **проверить**, действителен ли полученный от сервера сертификат. + +Затем, используя этот сертификат, клиент и прокси-сервер **выбирают способ шифрования** данных для устанавливаемого **TCP-соединения**. На этом операция **TLS-рукопожатия** завершена. + +В дальнейшем клиент и сервер будут взаимодействовать по **зашифрованному TCP-соединению**, как предлагается в протоколе TLS. И на основе этого TCP-соедениния будет создано **HTTP-соединение**. + +Таким образом, **HTTPS** это тот же **HTTP**, но внутри **безопасного TLS-соединения** вместо чистого (незашифрованного) TCP-соединения. + +!!! tip "Заметка" + Обратите внимание, что шифрование происходит на **уровне TCP**, а не на более высоком уровне HTTP. + +### HTTPS-запрос + +Теперь, когда между клиентом и сервером (в нашем случае, браузером и прокси-сервером) создано **зашифрованное TCP-соединение**, они могут начать **обмен данными по протоколу HTTP**. + +Так клиент отправляет **HTTPS-запрос**. То есть обычный HTTP-запрос, но через зашифрованное TLS-содинение. + + + +### Расшифровка запроса + +Прокси-сервер, используя согласованный с клиентом ключ, расшифрует полученный **зашифрованный запрос** и передаст **обычный (незашифрованный) HTTP-запрос** процессу, запускающему приложение (например, процессу Uvicorn запускающему приложение FastAPI). + + + +### HTTP-ответ + +Приложение обработает запрос и вернёт **обычный (незашифрованный) HTTP-ответ** прокси-серверу. + + + +### HTTPS-ответ + +Пркоси-сервер **зашифрует ответ** используя ранее согласованный с клиентом способ шифрования (которые содержатся в сертификате для домена `someapp.example.com`) и отправит его браузеру. + +Наконец, браузер проверит ответ, в том числе, что тот зашифрован с нужным ключом, **расшифрует его** и обработает. + + + +Клиент (браузер) знает, что ответ пришёл от правильного сервера, так как использует методы шифрования, согласованные ими раннее через **HTTPS-сертификат**. + +### Множество приложений + +На одном и том же сервере (или серверах) можно разместить **множество приложений**, например, другие программы с API или базы данных. + +Напомню, что только один процесс (например, прокси-сервер) может прослушивать определённый порт определённого IP-адреса. +Но другие процессы и приложения тоже могут работать на этом же сервере (серверах), если они не пытаются использовать уже занятую **комбинацию IP-адреса и порта** (сокет). + + + +Таким образом, сервер завершения TLS может обрабатывать HTTPS-запросы и использовать сертификаты для **множества доменов** или приложений и передавать запросы правильным адресатам (другим приложениям). + +### Обновление сертификата + +В недалёком будущем любой сертификат станет **просроченным** (примерно через три месяца после получения). + +Когда это произойдёт, можно запустить другую программу, которая подключится к Let's Encrypt и обновит сертификат(ы). Существуют прокси-серверы, которые могут сделать это действие самостоятельно. + + + +**TLS-сертификаты** не привязаны к IP-адресу, но **связаны с именем домена**. + +Так что при обновлении сертификатов программа должна **подтвердить** центру сертификации (Let's Encrypt), что обновление запросил **"владелец", который контролирует этот домен**. + +Есть несколько путей осуществления этого. Самые популярные из них: + +* **Изменение записей DNS**. + * Для такого варианта Ваша программа обновления должна уметь работать с API DNS-провайдера, обслуживающего Ваши DNS-записи. Не у всех провайдеров есть такой API, так что этот способ не всегда применим. +* **Запуск в качестве программы-сервера** (как минимум, на время обновления сертификатов) на публичном IP-адресе домена. + * Как уже не раз упоминалось, только один процесс может прослушивать определённый порт определённого IP-адреса. + * Это одна из причин использования прокси-сервера ещё и в качестве программы обновления сертификатов. + * В случае, если обновлением сертификатов занимается другая программа, Вам понадобится остановить прокси-сервер, запустить программу обновления сертификатов на сокете, предназначенном для прокси-сервера, настроить прокси-сервер на работу с новыми сертификатами и перезапустить его. Эта схема далека от идеальной, так как Ваши приложения будут недоступны на время отключения прокси-сервера. + +Весь этот процесс обновления, одновременный с обслуживанием запросов, является одной из основных причин, по которой желательно иметь **отдельную систему для работы с HTTPS** в виде прокси-сервера завершения TLS, а не просто использовать сертификаты TLS непосредственно с сервером приложений (например, Uvicorn). + +## Резюме + +Наличие **HTTPS** очень важно и довольно **критично** в большинстве случаев. Однако, Вам, как разработчику, не нужно тратить много сил на это, достаточно **понимать эти концепции** и принципы их работы. + +Но узнав базовые основы **HTTPS** Вы можете легко совмещать разные инструменты, которые помогут Вам в дальнейшей разработке. + +В следующих главах я покажу Вам несколько примеров, как настраивать **HTTPS** для приложений **FastAPI**. 🔒 diff --git a/docs/ru/mkdocs.yml b/docs/ru/mkdocs.yml index 5b6e338ce..b167eacd1 100644 --- a/docs/ru/mkdocs.yml +++ b/docs/ru/mkdocs.yml @@ -76,6 +76,7 @@ nav: - Развёртывание: - deployment/index.md - deployment/versions.md + - deployment/https.md - project-generation.md - alternatives.md - history-design-future.md