Технологии: Обратный WebSocket-прокси

Многие современные веб-приложения используют для передачи данных не только привычные протоколы HTTP и HTTPS, но и протокол WebSocket (RFC 6455). Например, через HTTPS может работать фронтенд веб-приложения, а через WebSocket — подгружаться видеопоток. Зачастую апстримы WebSocket располагаются на тех же IP-адресах или в тех же сетях, что и HTTP-апстримы, таким образом, незащищённый WebSocket-трафик может упростить для злоумышленника проведение атаки на вашу сеть даже при полной защищённости HTTP-трафика.

Поэтому клиентам, разрабатывающим такие мультипротокольные веб-приложения, следует обеспечить прохождение всего трафика приложения через сеть Qrator Labs. Для этого нужно использовать комбинацию из обратного HTTP-прокси и обратного WebSocket-прокси.

О том, как начать использовать обратный WebSocket-прокси от Qrator Labs, читайте в статье Подключение: Обратный WebSocket-прокси.

Принцип работы

Частью протокола WebSocket является рукопожатие (handshake), которое должны выполнить пользователь и апстрим, прежде чем начать пересылку данных. Для самого рукопожатия используется протокол HTTP. После завершения рукопожатия обе стороны могут отправлять друг другу трафик по протоколу WebSocket до тех пор, пока соединение не будет закрыто одной из сторон.

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

Ответственность за разбор и обработку данных, передаваемых после рукопожатия, лежит на приложении. Обратный прокси не анализирует и не изменяет WebSocket-трафик, что позволяет использовать его вне зависимости от формата пересылаемых данных.

Ниже подробнее описана процедура рукопожатия с участием обратного WebSocket-прокси.

  1. Пользователь отправляет запрос HTTP 101 Switching Protocols.

    Получив этот запрос, обратный прокси проверяет, не превышает ли количество запросов с IP-адреса пользователя заданный клиентом лимит. Если лимит ещё не превышен, то обратный прокси выбирает апстрим для данного пользователя, исходя из его IP-адреса, см. раздел Балансировка.

  2. На выбранный апстрим проксируется запрос HTTP 101 Switching Protocols с заголовками, которые указал пользователь в своём запросе, а также дополнительными HTTP-заголовками.

    Важно

    По умолчанию обратный прокси настроен так, что перед передачей запроса на апстрим из него удаляются заголовки, содержащие знак подчёркивания _. Если вам необходимо, чтобы такие заголовки оставались в запросе, обратитесь в техническую поддержку Qrator Labs для изменения этой настройки.

  3. Обратный прокси ожидает ответ от апстрима в течение 5 секунд. Если апстрим не отвечает, то обратный прокси возвращается к шагу 2 и предпринимает попытки обратиться к другим апстримам клиента. Подробнее об этом написано в разделе Балансировка.

    • Если ответ ни от одного апстрима не приходит, обратный прокси возвращает пользователю ответ со статусом HTTP 400 Bad Request, и попытка начать работу по протоколу WebSocket прекращается.

    • Если апстрим отвечает сообщением об ошибке с любым статусом, то соединения сбрасываются, и попытка начать работу по протоколу WebSocket прекращается.

    • Если апстрим отвечает рукопожатием со статусом HTTP 101 Switching Protocols и корректными заголовками, обратный прокси проксирует это ответ пользователю без изменений. В этом случае соединение между обратным прокси и апстримом считается успешно установленным.

  4. Пользователь проверяет статус и заголовки полученного ответа. На этом рукопожатие завершается, и WebSocket-соединение между пользователем и обратным прокси считается успешно установленным. Протокол HTTP в рамках этого соединения больше не используется.

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

Обратный прокси не анализирует пересылаемые данные и не изменяет их содержимое при пересылке, что позволяет корректно работать вне зависимости от формата пересылаемых данных.

Когда одна из сторон закрывает соединение с обратным прокси, обратный прокси автоматически закрывает соединение с другой стороной.

expand_less