AJP (Apache JServ Protocol)

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 08:08, 27 июня 2016.
Open book.svg Авторство
Куликов А.В.
Согласовано: 21.05.2016

AJP (англ. The Apache JServ Protocol) — это бинарный протокол, который может проводить входящие запросы с веб-сервера через сервера приложений, которые находятся позади веб-сервера.

Общие сведения

AJP поддерживает наблюдение за состоянием сервера, в том числе позволяет проводить ping сервера приложений. AJP обычно используется в системах со сбалансированной нагрузкой, где один или более front-end’ов рассылают запросы в один или более серверов приложений. Сессии направляются к нужному серверу приложений, используя механизм роутинга, где каждый сервер приложений получает своё имя. В таком случае веб сервер функционирует как обратный прокси для сервера приложений.

AJP реализован в Apache HTTP Server 1.x и использует плагин mod jk, и в Apache 2.2, где использует прокси ajp (плагины mod proxy, mod proxy ajp), модули для балансирования прокси. Выполнение существует для еще не выпущенного lighttpd версии 1.5., nginx, Grizzly 2.1 и Internet Information Server. Zpach Tomcat и JBoss AS/WildFly servlet поддерживают AJP. Сервер apache написан на языке C++, серверы приложений обычно написаны на языке Java.
Оригинальный протокол, построенный в Apache JServ Servlet Engine, был разработан простым для первых использований этого модуля. Использование и постоянное развитие привели к необходимости в новых функциях. Apache JServ Protocol версии 2.1 обеспечивает новые функции, такие как улучшение производительности и дополнения для сервлетов.

Протокол построен на вершине подключения и зависит только от возможностей двух сторон общаться между собой в дуплексной связи.

История

Алексей Косут изначально разработал в Organic Online Apache JServ Protocol в июле 1997. Apache JServ Protocol был специально разработан простым из-за необходимости подобного проекта в то время.В том же месяце был релиз Apache JServ Servlet Engine 0.9 и Apache mod_jserv 0.9a (выпущен 30 июля 1997).

The Original JServ Protocol (AJPv1)

Протокол включает в себя начальный этап, когда Apache Web Server запускает JServ Servlet Engine и задает ему начальные параметры для проверки подлинности, которые после будут использованы для всех сервлет запросов. Также в него включен “ручной” режим для сервлетов, где аутентификация не требовалась. Это потенциально опасно при использовании без какой-либо другой защиты от злоумышленников. Затем для каждого запроса HTTPD процесс должен подключиться к Servlet Engine с помощью сокета и отправить несколько текстовых строк в формате ASCII с заголовками запроса. Servlet Engine должен отвечать всем в ответ.

Использование протокола JServ привело к следующим проблемам:

  • Выходы сервлета всегда буферизированы. Но не буферизированные выходы желательны во многих случаях;
  • Разработчики захотели иметь возможность посылать запросы обратно к Apache Web Server для работы с информации о конфигурации, доступной только HTTPD;
  • Настройка сокета сверху была определена как потенциальная угроза производительности;

AJPv2

AJPv2 – пакетно-ориентированный протокол. Все данные, проходящие через AJPv2 соединение, могут быть инкапсулированы в один или более пакетов. Данная форма бинарного поведения была выбрана вместо более читаемого простого текстового протокола (такого как HTTP), потому что является более производительной (меньше траффика генерируется) и быстрой для выполнения (типы пакетов лучше понимаются машинами, а не текстовыми строками) Пакетный формат брался небольшим (32 бита) для повышения производительности, и в то же время некоторые пакеты обязаны включать в себя всю содержащуюся информацию в одном пакете, а некоторые можно было разделить. Это было необходимо, чтобы разрешить нагрузки более чем 16 Мб. Эти протоколы использовались для аутентификации безопасных соединений и запрета возможных запросов в обход безопасности веб сервера. При правильной настройке AJPv2 считается безопасным, и поэтому защищает сервлеты от ненадежных запросов и/или нападения.

Формат данных AJPv2.0

Заголовки пакетов должны быть 64 бита в длину:

  • Октет 0 (8 бит) содержит тип пакета и подпакета;
    • Менее значимые 5 бит (0-4) отражают тип пакета, используя беззнаковые значения;
    • Более значимые 3 бита (5-7) отображают подтип пакета, используя целые беззнаковые значения;
  • Октет 1 (8 бит) содержит флаги;
    • Бит 0 содержит флаг "Окончание данных сессии";
    • Бит 1 содержит флаг "Сессия закрыта";
    • Бит 2 содержит флаг "Соединение закрыто";
    • Биты 3-7 зарезервированы для будущего расширения. Они должны быть заданы нулевыми отправителем и игнорироваться получателем;
  • Октет 2-3 (16 бит) запускает сессию, к которой относится пакет;
  • Октет 4-7 (32 бита) задает размер загрузочных данных, может быть равен нулю;
  • Октет 8 содержит данные;

Формат данных AJPv2.1

Формат данных AJPv2.1
Заголовки запросов
AUTH_TYPE
CONTENT_LENGTH
CONTENT_TYPE
DOCUMENT_ROOT
PATH_INFO
PATH_TRANSLATED
QUERY_STRING
REQUEST_METHOD
REMOTE_USER
REMOTE_ADDR
REMOTE_HOST
SCRIPT_NAME
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE

Все данные, передаваемые по дуплекcному соединению между клиентом и сервером, должны следовать следующей структуре:

  • Данные отправляют в виде пакетов, сформированных с заголовком, описывающим некоторую информацию о пакете, длину данных и данные о загрузке;
  • Все пакеты должны следовать стилю с прямым порядком байт (“сетевой”);
  • Заголовок пакета должен быть всегда длиной 32 бита в следующем формате:
    • 0 октет (8 бит) содержат тип пакета и подтип:
      • Не менее четырех существенных бит (0-3) отображают тип пакета, используя беззнаковые значения;
      • Наиболее значимые биты (4-7) отображают подтип пакета, используя беззнаковые значения;
    • 1-3 октеты (24 бита) устанавливают длину загрузочных данных, могут быть нулевыми;
    • 4 октет – октет сведений;

AJPv3

Протокол AJPv3 практически не отличается от предыдущей версии AJPv2.

Структура пакетов

AJPv3 использует сетевой порядок байт для всех типов данных. Существует 4 типа данных в протоколе: биты, booleans, integers и strings.
Биты: Один бит

Boolean: Один бит, 1 = true, 0 = false. Использование другого не нулевого значения в качестве true (например, C-style) может работать в одном месте, но не работать в другом.

Integer: Число в диапазоне от 0 до 2^16 (32768). Хранится в двух байтах с первым значимым

String: Строка длиной 2^16.

Размер пакета

Максимальный размер пакета 8 * 1024 байт (8K). Длина пакета закодирована в заголовке.

Безопасность

Секрет целого числа – алгоритм аутентификации AJPv1 - не был перенесен в AJPv3, потому что считается не безопасным. В AJPv3 алгоритм проверки подлинности зависит от всех клиентов и серверов, имеющих доступ в секретный файл или строки с идентичным содержанием. Это основано на предположении о том, что администрация AJPv3 клиентских и серверных систем либо одинаковые, либо в сотрудничестве друг с другом. Этот алгоритм использует алгоритм хеширования MD5. Это возможность убедиться, что обе стороны владеют секретом текста (аналог пароля) без передачи его в открытом виде по сети.

См. также