5. HTTP и HTTPS (L7)
Методы/коды HTTP, заголовки и Keep-Alive; TLS handshake, SNI, цепочка сертификатов, mTLS и ALPN + быстрая проверка L7 через curl и openssl s_client.
HTTP
Методы
| Метод | Назначение |
|---|---|
| GET | Получить ресурс. Идемпотентный, кэшируемый. |
| POST | Создать ресурс или отправить данные (форма, JSON). |
| PUT | Заменить ресурс по URI. Идемпотентный. |
| PATCH | Частичное обновление ресурса. |
| DELETE | Удалить ресурс. Идемпотентный. |
| HEAD | Как GET, но без тела ответа (проверка заголовков, кэша). |
| OPTIONS | Какие методы и заголовки разрешены (CORS, preflight). |
Прокси и балансировщики (Nginx, Envoy, ALB) видят метод в первой строке запроса и могут маршрутизировать, логировать и ограничивать по нему.
Коды ответа (3xx, 4xx, 5xx)
- 2xx — успех (200 OK, 201 Created, 204 No Content).
- 3xx — перенаправление: 301/302 (редирект), 304 Not Modified (кэш).
- 4xx — ошибка клиента: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 405 Method Not Allowed, 408 Request Timeout, 429 Too Many Requests.
- 5xx — ошибка сервера: 500 Internal Server Error, 502 Bad Gateway (прокси не получил ответ от бэкенда), 503 Service Unavailable, 504 Gateway Timeout.
При разборе инцидентов: 502/504 часто означают, что прокси/ALB не дождался ответа от upstream или upstream упал; 4xx — неверный запрос, авторизация или ограничения на стороне приложения/прокси.
Заголовки (headers)
Заголовки задают метаданные запроса и ответа. Важные для DevOps:
- Host — имя виртуального хоста (обязателен в HTTP/1.1); по нему Nginx/ALB выбирают виртуальный сервер.
- Content-Type, Content-Length — тип и размер тела.
- Authorization — Bearer, Basic и т.д.
- Cache-Control, ETag, If-None-Match — кэширование.
- X-Forwarded-For, X-Real-IP — реальный IP клиента за прокси.
- Connection: keep-alive — переиспользование TCP-соединения (см. ниже).
Keep-Alive
Keep-Alive (HTTP/1.1 по умолчанию — постоянное соединение): одно TCP-соединение используется для нескольких запросов подряд. Заголовок Connection: keep-alive (или отсутствие Connection: close) разрешает это. Снижает задержку и нагрузку за счёт меньшего числа handshake. Прокси и балансировщики должны корректно передавать Keep-Alive к бэкендам и к клиенту.
HTTPS / TLS
TLS handshake
При установлении HTTPS клиент и сервер:
- Согласовывают версию TLS и набор шифров.
- Сервер отправляет свой сертификат (и цепочку до корня).
- Клиент проверяет сертификат (подпись, срок, имя в CN/SAN).
- Обмениваются ключами и переходят на шифрованный обмен данными.
Handshake добавляет RTT и нагрузку на CPU; переиспользование сессий (session resumption) сокращает повторные handshake.
SNI (Server Name Indication)
SNI — расширение TLS: клиент в начале handshake отправляет имя хоста (например, api.example.com), чтобы сервер мог выбрать правильный виртуальный хост и сертификат. Без SNI на одном IP можно было бы обслуживать только один HTTPS-сайт. Балансировщики и прокси используют SNI для маршрутизации и для подстановки своего сертификата при терминации TLS.
Цепочка сертификатов (certificate chain)
Сервер отдаёт не только свой сертификат, но и цепочку промежуточных сертификатов до корневого (root CA). Клиент проверяет подпись каждого звена: сертификат сервера подписан промежуточным CA, тот — корневым. В хранилище клиента должны быть корневые CA (или промежуточные, если сервер их не присылает). Ошибки вроде «unable to get local issuer certificate» означают обрыв цепочки — не хватает промежуточного или корневого сертификата.
mTLS (mutual TLS)
mTLS — клиент тоже предъявляет сертификат; сервер проверяет его и допускает только доверенных клиентов. Используется в сервисной сетке (Istio, Linkerd), API-шлюзах и внутренних сервисах. Для диагностики нужны клиентский сертификат и ключ (например, в curl или openssl s_client).
ALPN (Application-Layer Protocol Negotiation)
ALPN — согласование протокола поверх TLS (HTTP/1.1, HTTP/2, h2). В handshake клиент указывает список поддерживаемых протоколов, сервер выбирает один. Важно для HTTP/2 и для правильной маршрутизации на прокси (например, gRPC поверх TLS).
Практика: команды
curl (запросы и заголовки)
# Подробный вывод: заголовки запроса и ответа
curl -v https://example.com/
# Только заголовки ответа
curl -I https://example.com/
# Указать метод и заголовок
curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' https://api.example.com/
# Указать Host (проверка виртуального хоста)
curl -v -H "Host: api.example.com" https://1.2.3.4/
openssl s_client (TLS и сертификаты)
# Подключение к HTTPS, вывод сертификата и цепочки
openssl s_client -connect example.com:443 -servername example.com
# Проверить цепочку до корня (без -servername может быть другой сертификат при SNI)
openssl s_client -connect example.com:443 -servername example.com -showcerts
# Проверка с клиентским сертификатом (mTLS)
openssl s_client -connect api.example.com:443 -cert client.crt -key client.key
!!! tip "Практика"
При «не открывается сайт» или «502 за прокси»: 1) curl -v по URL — какой статус и заголовки; 2) openssl s_client — доходит ли TLS, валидна ли цепочка и имя в сертификате (SNI). При 502 — смотреть таймауты и доступность бэкенда за прокси.
Паттерны и антипаттерны
| Паттерн | Описание |
|---|---|
| Читать статус и заголовки | По коду ответа и заголовкам (X-Cache, Retry-After) понимать, где проблема: клиент, прокси или бэкенд. |
| Проверять цепочку и SNI | Ошибки TLS часто из-за неверного имени в SAN или обрыва цепочки; s_client показывает, что видит клиент. |
| Учитывать Host за прокси | За балансировщиком приложение может смотреть на Host; тестировать с тем же Host, что и реальный трафик. |
| Антипаттерн | Почему плохо | Что делать |
|---|---|---|
| Игнорировать 502/504 | Означают сбой между прокси и бэкендом или таймаут. | Проверять здоровье бэкендов, таймауты прокси и сети. |
| Подставлять сертификат без полной цепочки | Клиент не доверяет из-за «unable to get local issuer». | Отдавать полную цепочку до корня (или до доверенного промежуточного). |