Esse problema é solucionável usando o RadWare AppDirector e (para ser completo) provavelmente também usando o Apache mod_security conforme sua excelente descoberta no comentário abaixo.
Para uma solução AppDirector, acredito que é possível criar dois farms mapeados para os mesmos servidores back-end. Esses farms podem ter critérios e condições operacionais diferentes aplicados a eles. Um farm seria o "padrão" e o outro responderia aos URI: s que você define como sendo "uma sessão". O último obteria um limite para a quantidade de sessões que ele aceita no balanceador de carga.
A partir de agora, substituirei o termo "sessão" por "logado" por dois motivos:
- Isso evita ambiguidade, pois define claramente o estado desejado no qual o usuário é autenticado.
- O AppDirector User Guide e GUI redefinem o termo "conexão" para ter um significado para todos os fins práticos idênticos a "sessão", veja abaixo. Isso adiciona confusão que tentamos evitar.
Também é possível mostrar uma página de desculpas se o farm "logado" atingiu o limite de conexão escolhido.
Antes de começar, como devo declarar claramente que não tenho experiência operacional com o produto AppDirector, mas administro diariamente um balanceador de carga concorrente e um pouco menos avançado. O produto que eu uso pode fazer esse cenário imediatamente. Encontrei informações no Guia do usuário do AppDirector e qual documentação on-line está disponível, o que sugere que o mesmo se aplica ao AppDirector. No entanto, embora os conceitos sejam semelhantes, a terminologia é diferente. Estou simplesmente fazendo um ato quando em Roma com relação à redação, esperando acertar bastante sem ser obviamente um idiota sem noção.
O maior obstáculo foi o acesso a um manual, que não é disponibilizado, a menos que se seja um cliente ativo. Através de algumas pesquisas no Google, foi possível encontrar uma versão antiga que, espero, não esteja muito desatualizada, também encontrei alguns artigos da base de conhecimento e este link: Radware AppDirector - Configuração: aplicativo básico .
Aqui está um rascunho da solução, interpretado principalmente pelo Guia do Usuário:
A entrada do cliente no balanceador de carga é feita por meio de um VIP, usado para conectar as sessões "padrão" e as "sessões de logon". Isso é alcançado através de uma política L4, conforme a p.99 no Guia do Usuário:
"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.
A política L4 pode ser vinculada às políticas L7, usadas para selecionar um farm adequado. O processo da política L7 é descrito assim no Guia do Usuário p.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."
Os métodos disponíveis para definir um comportamento L7 estão descritos na p.106, dos quais você pode escolher um método adequado para escolher o roteamento para o seu farm "logado" em vez do farm "padrão":
"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."
Como visto no link do aplicativo básico , pode-se, por exemplo, criar uma política L7 que avalie os padrões de URI para rotear para diferentes farms. Os padrões de URI inventados '^ / login? = True' e '^ / login' podem ser roteados para o farm "logado". O padrão criado '^ / logout' (e todos os outros URI: s) também pode ser roteado para um farm "padrão".
Um farm é definido pelo Guia do Usuário p.121, assim: "Um farm do AppDirector é um grupo de servidores em rede que fornecem o mesmo serviço [...] Um servidor que fornece vários serviços pode ser usado em vários farms".
Um servidor é ainda mais diferenciado ao separar a definição de servidor backend em duas camadas, a camada de objeto 'Physical Server', que representa o endereço IP de um servidor, e a camada de objeto 'Farm Server', que representa serviços em execução em um ou mais servidores físicos .
A limitação de sessão em um farm pode, de acordo com o 'Guia do Usuário do AppDirector', ser realizada por cada objeto do Servidor do Farm definido para um farm (e por outros meios), além do objeto do Servidor Físico. Isso é descrito entre outros lugares na p.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."
A tabela do cliente e seu 'modo regular' estão definidos na p.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"
Em uma captura de tela de uma janela de definição de servidor na página Aplicativo Básico , a caixa de limite de conexão do servidor é vista ao lado da caixa de limite de largura de banda.
Então, dependendo da configuração, mas para os fins desta resposta, uma 'conexão' conforme definida na Tabela do Cliente e uma 'sessão' conforme definida por você basicamente acabam sendo a mesma coisa. E um limite para esse efeito pode ser imposto por objeto de servidor em um farm.
Como o AppDirector diferencia entre servidores físicos e servidores de farm, seria possível definir dois servidores de farm mapeados para o objeto de servidor físico do Apache, um com um limite de conexão baixo.
No entanto, o Apache também precisa atender chamadas de ambos os objetos do servidor do farm, por exemplo, sendo chamado em duas portas ou endereços IP separados - um sendo usado por cada combinação (servidor do farm / farm). A questão então se torna: você pode definir dois pontos de entrada do servidor de aplicativos? ou seja, você pode equipar seu aplicativo front end Apache (/ vhost?) para responder em duas portas ou endereços IP (um por farm)? Isso é um pouco de trabalho de adivinhação, já que não desejo gastar muito tempo com o manual, mas tenho certeza de que você poderia resolver isso com bastante elegância ao realmente olhar a GUI do AppDirector e o Apache.
Definir o limite de conexão é um pouco peculiar. De servidores físicos, limite de conexão p.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."
Portanto, seria necessário definir um limite de conexão muito alto (com uma ampla margem para o número máximo possível por meio de sua base de usuários) para o servidor de farm irrestrito "padrão" e definir o limite de conexão para o servidor de farm "conectado" como baixo como você precisa. A definição do servidor físico precisaria ter a soma dos dois como seu Limite de conexão, como condição prévia para ativar o limite de sessão desejado.
Você também tem este requisito em sua pergunta:
After the specified session limit has been reached, the next user should be
directed to a custom error page.
Isso é chamado de 'Nenhuma Página de Serviço HTTP' no Guia do Usuário, p.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.
Para a parte de monitoramento, não fiz uma pesquisa completa, mas eis o que penso:
track the current number of sessions for monitoring purposes
O AppDirector parece ter MIBs. Provavelmente, é difícil encontrar o OID certo, como normalmente é, mas é possível encaixá-lo na sua ferramenta de escolha.
whitelist the monitoring server (which is issuing queries to the webapp
periodically) and exempt it from the limit.
Este poderia exigir algum pensamento criativo. Supondo que o AppDirector não inclua um modelo para isso imediatamente, que tal:
- URIs fora do farm "conectado" não seriam afetados pelo limite de sessões. Portanto, monitore, é o mesmo servidor de qualquer maneira.
- Use as verificações de integridade do AppDirector; elas provavelmente não serão contabilizadas no limite de sessões que você impõe. Encontre uma maneira de passar alertas para o servidor de monitoramento :-)
- Configure um terceiro farm, através do qual você passa nas verificações de saúde. Confuso, mas funcionaria.