Este problema se puede resolver usando RadWare AppDirector y (para completar) probablemente también usando Apache mod_security según su excelente hallazgo en el comentario a continuación.
Para una solución AppDirector, creo que es posible crear dos granjas asignadas a los mismos servidores de fondo. Estas granjas pueden tener diferentes criterios y condiciones de operación aplicadas a ellas. Una granja sería la "predeterminada" y la otra respondería a los URI: s que usted define como "una sesión". Este último obtendría un límite en la cantidad de sesiones que acepta en el equilibrador de carga.
De ahora en adelante, voy a sustituir su término de "sesión" por "conectado" por dos razones:
- Evita la ambigüedad, ya que define claramente el estado deseado en que el usuario está autenticado.
- La Guía del usuario y la GUI de AppDirector redefine el término "conexión" para que tenga un significado para todos los fines prácticos idénticos a "sesión", ver más abajo. Esto agrega confusión que tratamos de evitar.
También es posible mostrar una página de disculpas si la granja "iniciada" ha alcanzado el límite de conexión elegido.
Antes de llegar al cómo, debo decir claramente que no tengo experiencia operativa con el producto AppDirector, pero administro diariamente un equilibrador de carga competitivo y un poco menos avanzado. El producto que uso puede hacer este escenario de inmediato. He encontrado información a través de la Guía del usuario de AppDirector y qué documentación en línea está disponible, lo que sugiere que lo mismo es cierto para AppDirector. Sin embargo, si bien los conceptos son similares, la terminología es diferente. Simplemente estoy haciendo un acto cuando estoy en Roma con respecto a la redacción, con la esperanza de hacerlo bien sin ser obviamente un imbécil despistado.
El mayor obstáculo fue obtener acceso a un manual, que no está disponible a menos que uno sea un cliente activo. A través de algunas búsquedas en Google fue posible encontrar una versión anterior que espero no esté demasiado desactualizada, también encontré un par de artículos de la base de conocimiento y este enlace: Radware AppDirector - Configuración: Aplicación básica .
Aquí hay un borrador de solución, interpretado principalmente a través de la Guía del usuario:
La entrada del cliente al equilibrador de carga se realiza a través de un VIP que se utiliza para conectar las sesiones "predeterminadas" y las "sesiones conectadas". Esto se logra a través de una política L4 según p.99 en la Guía del usuario:
"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.
La política L4 se puede vincular a las políticas L7 que se utilizan para seleccionar una granja adecuada. El proceso de la política L7 se describe así en la Guía del usuario 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."
Los métodos disponibles para definir un comportamiento L7 se describen en la p.106, de los cuales puede elegir un método adecuado para elegir el enrutamiento a su granja "iniciada" en lugar de la granja "predeterminada":
"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 se ve en el enlace de la Aplicación básica , se podría crear, por ejemplo, una política L7 que evalúe los patrones de URI para el enrutamiento a diferentes granjas. Los patrones de URI creados '^ / login? = True' y '^ / loginin' se pueden enrutar a su granja de servidores "iniciada sesión". El patrón inventado '^ / logout' (y todos los demás URI: s) podrían enrutarse de manera similar a una granja "predeterminada".
La Guía del usuario, p. 121, define una granja de servidores de la siguiente manera: "Una granja de AppDirector es un grupo de servidores en red que proporcionan el mismo servicio. Un servidor que proporciona múltiples servicios puede utilizarse en varias granjas".
Un servidor se diferencia aún más mediante la separación de la definición de un servidor de fondo en dos capas, la capa de objeto 'Servidor físico' que representa la dirección IP de un servidor y la capa de objeto 'Servidor agrícola' que representa los servicios que se ejecutan en uno o más Servidores físicos .
La limitación de sesión en una granja de servidores se puede realizar de acuerdo con la 'Guía del usuario de AppDirector' por cada objeto del servidor de granja definido para una granja (así como a través de otros medios) además de por objeto del servidor físico. Esto se describe entre otros lugares en la 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."
La tabla de clientes y su 'modo regular' se definen en la 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"
En una captura de pantalla de una ventana de definición de servidor en la página de Aplicación Básica , el cuadro de límite de conexión del servidor se ve justo al lado del cuadro de límite de ancho de banda.
Por lo tanto, depende un poco de la configuración, pero a los fines de esta respuesta, una 'conexión' definida a través de la Tabla del cliente y una 'sesión' definida por usted esencialmente terminan siendo lo mismo. Y se puede imponer un límite a ese efecto por objeto de servidor en una granja.
Como AppDirector distingue entre servidores físicos y servidores de granja, sería posible definir dos servidores de granja de mapeo a su objeto de servidor físico Apache, uno con un límite de conexión bajo.
Sin embargo, Apache también necesita responder llamadas de ambos objetos del servidor de la granja de servidores, por ejemplo, a través de dos puertos o direcciones IP separados, uno usado por cada combo (granja / servidor de granja). La pregunta es: ¿puede definir dos puntos de entrada del servidor de aplicaciones? es decir, ¿puede equipar su aplicación front-end Apache (/ vhost?) para responder en dos puertos o direcciones IP (una por granja)? Esto es a través de un poco de trabajo de conjetura, ya que no deseo pasar demasiado tiempo con el manual, pero estoy seguro de que podría resolverlo de manera bastante elegante cuando realmente mire la GUI de AppDirector y el Apache.
Establecer el límite de conexión tiene un pequeño capricho. Desde servidores físicos, límite de conexión 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."
Por lo tanto, deberá definir un Límite de conexión muy alto (con un amplio margen hasta el número máximo posible a través de su base de usuarios) para el servidor de granja "predeterminado" sin restricciones, y establecer el Límite de conexión para el servidor de granja "conectado" como bajo como tienes que hacerlo. La definición del servidor físico necesitaría tener la suma de los dos como su límite de conexión, como condición previa para activar el límite de sesión deseado.
También tiene este requisito en su pregunta:
After the specified session limit has been reached, the next user should be
directed to a custom error page.
Esto se denomina 'No hay página de servicio HTTP' en la Guía del usuario, 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 la parte de monitoreo no he hecho una investigación exhaustiva, pero esto es lo que pienso:
track the current number of sessions for monitoring purposes
AppDirector parece tener MIB. Probablemente sea una molestia encontrar el OID correcto, como suele ser, pero probablemente pueda usarlo con la herramienta que elija.
whitelist the monitoring server (which is issuing queries to the webapp
periodically) and exempt it from the limit.
Este podría requerir un poco de pensamiento creativo. Suponiendo que AppDirector no incluya una plantilla para esto de inmediato, ¿qué tal si:
- Los URI fuera de la granja "iniciada" no se verían afectados por el límite de sesión. Así que vigile, es el mismo servidor (s) de fondo de todos modos.
- Utilice las comprobaciones de estado de AppDirector en su lugar, es probable que no cuenten para el límite de sesión que impone. Sin embargo, encuentre una forma de pasar alertas a su servidor de monitoreo :-)
- Configure una tercera granja, a través de la cual pasa los controles de salud. Desordenado, pero funcionaría.