Назад | Перейти на главную страницу

Как ограничить количество сеансов?

Мне нужен способ отслеживать и ограничивать веб-сеансы веб-приложением. «Сеанс» в общих чертах определяется как просмотр страниц указанного веб-приложения одним пользователем. Думаю, это можно перевести на:

После достижения указанного ограничения сеанса следующий пользователь должен быть направлен на настраиваемую страницу ошибки. Мне также нужен способ отслеживать текущее количество сеансов для целей мониторинга и возможность занести в белый список сервер мониторинга (который периодически отправляет запросы в веб-приложение) и освободить его от ограничения.

С чем я могу работать:

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

Обоснование всего этого заключается в том, что вышеупомянутое веб-приложение легко перегружается и начинает беспорядочно отклонять запросы, раздражая работающих пользователей, которые (обычно) теряют данные для ввода формы в процессе. Указав предел, при котором условие перегрузки менее вероятно, мы надеемся создать четко определенное условие отказа, при котором пользователям будет предложено вернуться позже, если нагрузка может резко возрасти.

редактировать: веб-приложение представляет собой трехуровневую реализацию, причем первый уровень (уровень представления, реализованный как код CGI в Apache vHost) довольно упрощен и, по-видимому, ограничен базовой обработкой ошибок и балансировкой нагрузки запросов между серверами приложений. Он не создает значительной нагрузки на веб-серверы, на которых он работает - вот почему мы запускаем его в режиме простого переключения при отказе (без балансировки нагрузки) в ферме AppDirector, что должно несколько упростить ситуацию.

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

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

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

Мне также нужен способ отслеживать текущее количество сеансов для мониторинга

Если предположить, что приложение представляет собой черный ящик с нет объема для модификации / инструментария (что крайне маловероятно) вы можете получить эту информацию из журналов Apache, включив файл cookie сеанса - отфильтруйте или отслеживайте журналы, чтобы поддерживать список активных файлов cookie - и удалять записи из списка, когда они совпадают с выходом из системы URL или не просматривались для TTL.

Эту проблему можно решить как с помощью RadWare AppDirector, так и (для полноты), вероятно, также с помощью Apache mod_security в соответствии с вашим отличным выводом в комментарии ниже.

Я считаю, что для решения AppDirector можно создать сопоставление двух ферм с одним и тем же внутренним сервером (серверами). Эти фермы могут иметь разные критерии и применяемые к ним условия работы. Одна ферма будет «по умолчанию», а другая будет отвечать на URI: s, которые вы определяете как «сеанс». Последний получит ограничение на количество сеансов, которые он принимает в балансировщике нагрузки.

С этого момента я собираюсь заменить термин «сеанс» на «вошел в систему» ​​по двум причинам:

  • Это позволяет избежать двусмысленности, поскольку четко определяет желаемое состояние, в котором пользователь аутентифицирован.
  • Руководство пользователя AppDirector и графический интерфейс пользователя переопределяют термин «соединение», чтобы он имел значение для всех практических целей, идентичное «сеансу», см. Ниже. Это добавляет путаницы, которой мы стараемся избежать.

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

Прежде чем перейти к тому, как это сделать, я должен четко заявить, что у меня нет опыта работы с продуктом AppDirector, но я ежедневно администрирую конкурирующий и немного менее продвинутый балансировщик нагрузки. Продукт, который я использую, может сразу же выполнить этот сценарий. Я нашел информацию в руководстве пользователя AppDirector и в доступной онлайн-документации, которая предполагает, что то же самое верно и для AppDirector. Однако, хотя концепции схожи, терминология отличается. Я просто действую в Риме в отношении формулировок, надеясь сделать это правильно, не будучи слишком явно невежественным идиотом.

Самым большим препятствием был доступ к руководству, которое не предоставляется, если вы не являетесь активным покупателем. Путем некоторого поиска в Google удалось найти старую версию, которая, я надеюсь, не слишком устарела, я также нашел пару статей из базы знаний и эту ссылку: Radware AppDirector - конфигурация: базовое приложение.

Вот черновик решения, интерпретируемый в основном в Руководстве пользователя:

Вход клиента в балансировщик нагрузки осуществляется через виртуальный IP-адрес, который используется для подключения как «сеансов по умолчанию», так и «сеансов, вошедших в систему». Это достигается с помощью политики L4 в соответствии со стр. 99 в Руководстве пользователя:

"When AppDirector receives the first packet of a session destined to a
Virtual IP address, it searches for a Layer 4 Policy that matches the
Layer 4 Protocol, Destination port, Source IP, etc. Then, based on this
information, AppDirector selects the farm allocated to this service and
the best server for the task from that farm, and forwards the packet to
that server.

Политику L4 можно связать с политиками L7, которые используются для выбора подходящей фермы. Таким образом, процесс политики L7 описан в Руководстве пользователя на стр.104:

"The Layer 7 content aware decision making mechanism allows you to have
a single point of entry to the site, and provides differentiated service
for different user groups.

A Layer 7 decision is made using a mechanism called Delayed Binding.
When Delayed Binding is used, AppDirector first performs a TCP handshake
with the client to receive the HTTP request. AppDirector parses the HTTP
request’s data, usually HTTP headers, and performs the load balancing
decision. Only after that, does AppDirector select a farm and a server.
Lastly, AppDirector initiates a TCP handshake with the server and
forwards the traffic to it
[...]
When Layer 7 Policies are used, farm selection is based on matching the
request data with a list of Layer 7 Policies defining the Layer 7
parameters differentiating the service. The process of server selection
within the farm can also be content-based, using a third Layer 7
parameter."

Методы, доступные для определения поведения L7, описаны на стр.106, из которых вы можете выбрать подходящий метод, чтобы выбрать маршрутизацию на ферму, "вошедшую в систему", а не на ферму "по умолчанию":

"Methods are the basic building blocks for Layer 7 service selection.
They define content by which traffic is differentiated. You can use
the same Method to select one or more services. The following Method
Types are available:

- URL: Looks for a specified host name and/or path in the HTTP request.
- File Type: Looks for a specified File Type in the HTTP request.
- Header Field: Looks for a specified Header Field in the HTTP request.
- Cookie: Looks for a specified Cookie in the HTTP request.
- Regular Expression: Looks for a regular expression anywhere in the
HTTP request. AppDirector supports Posix 1002.3 regular expressions;
the string can be up to 80 characters.
- Text: Looks for a text string anywhere in the HTTP request."

Как видно из Базовое приложение link, можно, например, создать политику L7, оценивающую шаблоны URI для маршрутизации в разные фермы. Созданные шаблоны URI «^ / login? = True» и «^ / loggedin» могут быть перенаправлены на вашу ферму «авторизованных». Созданный шаблон '^ / logout' (и все другие URI: s) можно аналогичным образом направить в ферму «по умолчанию».

Ферма определяется в Руководстве пользователя на стр.121 следующим образом: «Ферма AppDirector - это группа сетевых серверов, которые предоставляют одну и ту же службу [...] Сервер, который предоставляет несколько служб, может использоваться в нескольких фермах».

Сервер дополнительно различается путем разделения определения внутреннего сервера на два уровня: объектный уровень «Физический сервер», который представляет IP-адрес сервера, и объектный уровень «Сервер фермы», который представляет службы, работающие на одном или нескольких физических серверах. .

В соответствии с «Руководством пользователя AppDirector» ограничение сеансов в ферме может выполняться для каждого объекта Farm Server, определенного для фермы (а также с помощью других средств) в дополнение к каждому объекту Physical Server. Это описано среди других мест на стр.137:

"The Connection Limit is the maximum number of users that can be directed
to a server for a service provided by the farm. The number of users allowed
depends on the Sessions mode selected because it determines the number of
active entries in the Client Table for sessions destined to the specific server.

When the Entry Per Session or Server Per Session modes are selected, the number
of active entries destined to the same server is higher than in the Regular
mode (see Regular, page 153).

When the Regular mode is selected, all requests from a single client IP destined
to the same server are reflected by a single entry in the Client Table (see
Client Table Views, page 164).

The default value for the Connection Limit parameter is 0. When it is configured
to 0, it is disabled for this server and there is no user number limit."

Таблица клиентов и ее «Обычный режим» описаны на стр.153:

"The Layer 3 Client Table is always used when Entry Per Session is used.
AppDirector uses the Layer 3 Client Table to ensure Layer 3 persistency.

This table contains information about the server selected for each client
(Source IP address) in each farm, and it allows AppDirector to select a
server for a new session.
[...]
In the Regular mode, AppDirector maintains Layer 3 persistency. In this mode,
each entry is identified by the following parameters:
• Layer 4 Policy VIP Address
• Client IP Address
• Destination TCP/UDP Port Used from the Client to the Server"

На скриншоте окна определения сервера на Базовое приложение на странице, поле ограничения подключения к серверу отображается рядом с полем ограничения пропускной способности.

Таким образом, это немного зависит от конфигурации, но для целей этого ответа «соединение», определенное в таблице клиентов, и «сеанс», как определено вами, по сути, оказывается одним и тем же. И ограничение на этот эффект может быть наложено на серверный объект в ферме.

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

Однако Apache также должен отвечать на вызовы от обоих объектов сервера фермы, например, посредством вызова на двух отдельных портах или IP-адресах - по одному из каждой комбинации (ферма / сервер фермы). Тогда возникает вопрос: можете ли вы определить две точки входа для сервера приложений? т.е. можете ли вы оборудовать свое клиентское приложение Apache (/ vhost?) для ответа на двух портах или IP-адресах (по одному на ферму)? Это связано с небольшими догадками, поскольку я не хочу тратить слишком много времени на руководство, но я уверен, что вы могли бы решить эту проблему довольно элегантно, глядя на графический интерфейс AppDirector и Apache.

Установка лимита подключения имеет небольшую причуду. С физических серверов, ограничение на количество подключений стр.140:

"Connection Limit

Maximum number of Client Table entries that can run simultaneously on 
the physical server. This depends on the farm’s Sessions mode (see 
Sessions Modes, page 150). When the limit is reached, new requests are 
no longer directed to this server. All open sessions are continued.

When the Connection Limit parameter is configured to 0 (default), this 
mechanism is disabled for this physical server and there is no user 
number limit.

Note: When configuring the physical server, ensure that the Connection 
Limit in the farm servers with the same Server Name is lower than or 
equal to the Connection Limit in the physical server. Total number of 
active sessions that run simultaneously on the farm servers must not 
be higher than the Connection Limit value defined on the physical server."

Поэтому вам необходимо определить очень высокий предел подключения (с широким запасом до максимального числа, доступного для вашей пользовательской базы) для неограниченного сервера фермы «по умолчанию» и установить предел подключения для сервера фермы «вошедший в систему» ​​как низко, как нужно. В определении физического сервера должна быть сумма двух в качестве предела количества подключений в качестве предварительного условия для активации желаемого ограничения сеанса.


У вас также есть это требование в вашем вопросе:

After the specified session limit has been reached, the next user should be
directed to a custom error page.

Это называется «Страница без службы HTTP» в Руководстве пользователя, стр. 134:

When all servers belonging to a farm cannot be used for a specific
session, AppDirector can reply to a Web request (destined to port 80)
with a simple Web page, indicating that the service is currently not
available. Servers that cannot be used for a session include servers
in Not In Service or in No New Sessions mode. No HTTP Service Page is
configured for each farm. Each Web page is limited to 1K of HTML code.

Что касается мониторинга, я не проводил столь тщательного исследования, но вот что я думаю:

track the current number of sessions for monitoring purposes

AppDirector, похоже, имеет MIB. Наверное, сложно найти правильный OID, как это обычно бывает, но вы, вероятно, можете подключить его к своему выбору.

whitelist the monitoring server (which is issuing queries to the webapp
periodically) and exempt it from the limit.

Это может потребовать творческого мышления. Предполагая, что AppDirector не включает шаблон для этого прямо из коробки, как насчет:

  • Ограничение сеанса не повлияет на URI за пределами фермы «вошедшего в систему». Так что следите, в любом случае это один и тот же серверный сервер.
  • Вместо этого используйте проверки работоспособности AppDirector, они, скорее всего, не будут учитываться при наложенном вами ограничении сеанса. Найдите способ передавать предупреждения на ваш сервер мониторинга :-)
  • Создайте третью ферму, через которую вы пройдете проверки работоспособности. Беспорядочно, но это сработает.

Это не совсем то, о чем вы просите, но я уже сделал следующее с балансировщиками нагрузки F5:

  • Подсчитайте количество запросов на публикацию на странице входа.
  • Задерживать пользователей, если количество входов в секунду превышает первое ограничение
  • Отправлять пользователей на страницу обслуживания, если количество входов в секунду превышает ограничение в секунду

Так как сайт иногда был сильно загружен (скачки), это помогало.

Если AppDirector не может вам помочь, вот еще один подход, который потребует небольшого кода. Я бы решил проблему следующим образом:

  • В цикле продолжайте читать файл журнала apache (и снова откройте его при logrotate)
  • Когда пользователь посещает любую страницу (не только входит в систему), добавьте его в белый список iptables.
  • Когда пользователь выходит из системы или после бездействия (так что сохраняйте таймеры для активных сеансов!), Удалите их из белого списка.
  • Если белый список заполнен, перенаправить весь трафик, не внесенный в белый список, на специальный порт.
  • Запустите простой vhost на этом порту с вашей собственной ошибкой

Построить график количества сеансов становится так же просто, как построить график длины цепочки iptables. Сервер мониторинга можно просто добавить в белый список.