Come limitare il numero di sessioni?


8

Ho bisogno di un modo per tracciare e limitare le sessioni Web a un'app Web. Una "sessione" è liberamente definita come il singolo utente che naviga nelle pagine di detta app Web. Penso che possa essere tradotto in:

  • una sessione è definita come una tupla <clientIP,vHost>alternativamente come <clientIP,serverIP,serverPort>o <cookie,vHost>, a seconda del livello e dei dati disponibili
  • una sessione inizia dopo che l'utente ha inviato i dati di autenticazione a un URI di accesso definito
  • una sessione termina dopo che l'utente ha raggiunto l'URI di disconnessione definito
  • una sessione termina se un timeout specificato è scaduto dopo che il client ha richiesto l'ultimo oggetto

Dopo che è stato raggiunto il limite di sessione specificato, l'utente successivo deve essere indirizzato a una pagina di errore personalizzata. Ho anche bisogno di un modo per tenere traccia del numero corrente di sessioni a fini di monitoraggio e la possibilità di autorizzare il server di monitoraggio (che sta inviando periodicamente query alla webapp) ed esentarlo dal limite.

Con cosa posso lavorare:

  • RadWare AppDirector in cui l'applicazione Web ha una propria farm definita ed è in esecuzione in modalità proxy inversa
  • Apache 2.2
  • SLES 11 SP2

Preferirei non coinvolgere un server proxy aggiuntivo, sebbene lo considererei se non rimanessero altre opzioni.

La logica alla base di tutto ciò è che l'app di cui sopra è facilmente sovraccaricabile e inizia a negare le richieste in modo irregolare, facendo incazzare gli utenti che, di solito, perdono i dati di immissione dei moduli nel processo. Specificando un limite in cui una condizione di sovraccarico è meno probabile, speriamo di creare una condizione di errore ben definita in cui agli utenti verrebbe comunicato di tornare in seguito se è probabile che il carico aumenti.

Modifica : l'app Web è un'implementazione a 3 livelli con il primo livello (livello di presentazione, implementato come codice CGI in un ApHost vHost) essendo piuttosto semplicistico e apparentemente limitato alla gestione degli errori di base e al bilanciamento del carico delle richieste tra i server delle applicazioni. Non impone alcun carico significativo sui server Web su cui viene eseguito: è per questo che lo stiamo eseguendo in semplice modalità di failover (senza bilanciamento del carico) nella farm AppDirector, che dovrebbe semplificare un po 'le cose.

Tutto al di là di questo punto è sostanzialmente una scatola nera per noi - a livello di dati abbiamo un database MSSQL, ma è pressoché impossibile ottenere dal fornitore qualsiasi informazione significativa sulla struttura della tabella. I server delle applicazioni sono a sorgente chiuso, il fornitore ha utilizzato un framework piuttosto completo per l'implementazione, ma sembra incapace di rispondere a domande ancora meno complesse relative alle operazioni.


Potete fornire dettagli generali sull'app Web? È lo stesso su ogni vHost? O non hai fornito i dettagli, perché forse desideri una soluzione indipendente dall'app Web? È un'app Web proprietaria?
liscio il

Dopo che la connessione è stata chiusa, a causa dell'inattività, qualcuno può riprendere una sessione usando il cookie di sessione (se il timeout dell'applicazione non è stato raggiunto)?
manjiki,

@jijix questo è un caso limite che è considerato abbastanza raro da non preoccuparsene se si aggiunge alla complessità dell'implementazione. Oltre a ciò, penso che potrebbe essere meglio specificato come "reinstalla la sessione senza verificare i limiti della sessione" .
the-wabbit il

Di solito lo faccio contando gli URL "tipici" nel registro di accesso httpd. Qual è il numero approssimativo concorrente di cui stiamo parlando qui? Forse un limite di thread può aiutare qui sul lato httpd?
Nils,

So che HAProxy può limitare il numero di connessioni. Ma stai chiedendo qualcosa di un po 'diverso ...
Matt,

Risposte:


5

Il problema che alla fine stai cercando di risolvere è con la capacità dell'applicazione - ed è qui che dovresti risolvere il problema. Nessuno dei componenti citati ha nulla a che fare con la gestione delle sessioni per un'applicazione HTTP.

Ci sono alcuni trucchi che puoi applicare con il modulo recente in iptables o usando fail2ban in modo opposto allo scopo per cui è stato progettato - ma entrambi richiedono una comprensione molto dettagliata degli strumenti e del dominio del problema. È possibile implementare il controllo degli accessi a livello di questi componenti ma guidato dalle informazioni sullo stato pubblicate dall'applicazione sul numero di sessioni.

Ho anche bisogno di un modo per tenere traccia del numero corrente di sessioni a fini di monitoraggio

Supponendo, per il momento, che l'applicazione sia una scatola nera senza possibilità di modifica / strumentazione (che è altamente improbabile) puoi ottenere queste informazioni dai tuoi log di apache includendo il cookie di sessione - filtra o modifica i log per mantenere un elenco di cookie attivi - e rimuovere le voci dall'elenco quando coincidono con l'URL di logout o non sono state visualizzate per il TTL.


Dimentica le mie domande sopra, questo è esattamente quello a cui stavo arrivando.
liscio il

Sei sicuro che RadWare AppDirector non può risolvere questo problema almeno nel trattamento esteso? - è richiesto il controllo della sessione per prevenire il sovraccarico del nodo che può essere ottenuto con altri mezzi.
Veniamin,

No, non ne sono sicuro - come ho detto sopra, puoi confondere la gestione delle sessioni altrove nello stack - ma è molto, MOLTO più difficile farlo nel posto sbagliato. Risolvere il problema in cui si verifica il problema è molto più semplice.
symcbean,

Se si considera che il posto giusto per la gestione delle sessioni è un modulo integrato nell'applicazione o altrove in base al nodo, non è chiaro come farlo funzionare insieme al bilanciamento del carico a livello di AppDirector.
Veniamin,

L'idea di utilizzare i log di Apache per il monitoraggio della sessione ha qualche merito. Per il resto, sai che non ho scritto l'app e ho poca (se presente) influenza su ulteriori sviluppi. Non è stata una mia decisione metterlo in atto, la mia autorità è limitata all'infrastruttura in cui è in esecuzione. Il punto in cui l'applicazione non è ottimale è stato chiarito alla direzione, ma anche se questo fosse in grado di cambiare qualcosa, qualsiasi cambiamento sarebbe impiega molto tempo. Quindi il mio lavoro attuale è quello di trovare una modalità operativa "buono come si arriva".
the-wabbit il

1

Questo non è esattamente quello che stai chiedendo, ma ho già fatto quanto segue con i bilanciatori del carico F5:

  • Conta il numero di richieste di post nella pagina di accesso.
  • Ritarda gli utenti se gli accessi al secondo superano il primo limite
  • Invia gli utenti a una pagina di manutenzione se gli accessi al secondo superano il secondo limite

Poiché il sito Web era talvolta sotto carico (corse di cavalli), ha aiutato.


Grazie per l'idea, devo verificare con i nostri ragazzi di AppDirector se potremmo implementare qualcosa di simile.
the-wabbit il

@ syneticon-dj: se hai bisogno di verificare se potresti implementare qualcosa del genere (che non risolve effettivamente il problema, a proposito) e non riesci a risolvere l'applicazione, allora sei davvero nei guai. Riflettendomi, riesco a pensare ad almeno altri 2 modi per risolvere il problema - ma entrambi sono tecnicamente impegnativi - e implementati in modo errato peggiorerà il problema anziché migliorarlo. Hai bisogno di più aiuto di quello che otterrai qui.
symcbean,

@symcbean Nulla che io possa fare risolverà il problema, che è la mancanza di qualifica all'interno del personale di sviluppo e supporto del venditore e una decisione presa per utilizzare questa applicazione nell'ignoranza di ciò. Se hai altre idee, sarò felice di sentirle. "Esigere" non è un problema fintanto che non aumenta la complessità delle operazioni quotidiane.
the-wabbit il

1

Questo problema è risolvibile sia usando RadWare AppDirector, sia (per completezza) probabilmente anche usando Apache mod_security secondo l'eccellente scoperta nel commento qui sotto.

Per una soluzione AppDirector credo che sia possibile creare due farm mappando sugli stessi server back-end. A queste aziende possono essere applicati criteri e condizioni operative diversi. Una farm sarebbe "predefinita" e l'altra risponderebbe a URI: s che definisci "una sessione". Quest'ultimo otterrebbe un limite alla quantità di sessioni accettate nel bilanciamento del carico.

D'ora in poi sostituirò il termine "sessione" con "accesso" per due motivi:

  • Evita le ambiguità poiché definisce chiaramente lo stato desiderato in cui l'utente è autenticato.
  • La Guida dell'utente di AppDirector e la GUI ridefiniscono il termine "connessione" per avere un significato per tutti gli scopi pratici identico a "sessione", vedere di seguito. Questo aggiunge confusione che cerchiamo di evitare.

È anche possibile mostrare una pagina di scusa se la farm "connessa" ha raggiunto il limite di connessione selezionato.

Prima di arrivare al come, devo chiaramente affermare di non avere esperienza operativa del prodotto AppDirector, ma amministrare quotidianamente un bilanciamento del carico concorrente e leggermente meno avanzato. Il prodotto che utilizzo può eseguire questo scenario fin dall'inizio. Ho trovato informazioni attraverso la Guida dell'utente di AppDirector e quale documentazione online è disponibile, il che suggerisce che lo stesso vale per AppDirector. Tuttavia, mentre i concetti sono simili, la terminologia è diversa. Sto semplicemente facendo un atto quando a Roma per quanto riguarda la formulazione, sperando di farlo abbastanza bene senza essere troppo chiaramente un idiota senza senso.

Il più grande ostacolo è stato l'accesso a un manuale, che non è reso disponibile se non si è clienti attivi. Attraverso alcuni googling è stato possibile trovare una versione precedente che spero non sia troppo datata, ho anche trovato un paio di articoli della knowledge base e questo link: Radware AppDirector - Configurazione: Applicazione di base .

Ecco una bozza di soluzione, interpretata principalmente attraverso la Guida per l'utente:

L'accesso client al bilanciamento del carico viene effettuato tramite un VIP che viene utilizzato per connettere sia le sessioni "predefinite" che le "sessioni connesse". Ciò si ottiene attraverso una politica L4 come da pagina 99 nella Guida dell'utente:

"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 politica L4 può essere legata alle politiche L7 utilizzate per selezionare una farm adatta. Il processo della politica L7 è descritto quindi nella Guida per l'utente 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."

I metodi disponibili per definire un comportamento L7 sono descritti a p.106, di cui è possibile scegliere un metodo adatto per scegliere il routing alla farm "registrata" piuttosto che alla farm "predefinita":

"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."

Come si vede nel link Applicazione di base , si potrebbe ad esempio creare un criterio L7 che valuti i pattern URI per il routing a diverse farm. I modelli di URI creati '^ / login? = True' e '^ / loggin' possono essere instradati alla tua fattoria "login". Il modello creato '^ / logout' (e tutti gli altri URI: s) potrebbero essere indirizzati in modo simile a una farm "predefinita".

Una Farm è definita dalla Guida per l'utente p.121 in questo modo: "Una farm AppDirector è un gruppo di server in rete che forniscono lo stesso servizio [...] Un server che fornisce più servizi può essere utilizzato in più farm".

Un server viene ulteriormente differenziato separando la definizione di un server back-end in due livelli, il livello oggetto "Physical Server" che rappresenta l'indirizzo IP di un server e il livello oggetto "Farm Server" che rappresentano i servizi in esecuzione su uno o più server fisici .

La limitazione della sessione in una farm può essere eseguita in base alla "Guida dell'utente di AppDirector" per ogni oggetto Farm Server definito per una farm (oltre che con altri mezzi) oltre all'oggetto Physical Server. Questo è descritto tra l'altro a 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 tabella client e la sua "Modalità normale" sono definite a 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"

In uno screenshot di una finestra di definizione del server nella pagina Applicazione di base , la casella del limite di connessione al server viene visualizzata accanto alla casella del limite di banda con.

Quindi, un po 'a seconda della configurazione, ma ai fini di questa risposta, una "connessione" come definita attraverso la tabella client e una "sessione" come definita dall'utente finiscono essenzialmente per essere la stessa cosa. E un limite a tale effetto può essere imposto per oggetto server in una farm.

Poiché AppDirector distingue tra server fisici e server della farm, sarebbe possibile definire due mapping dei server della farm sull'oggetto server fisico Apache, uno con un limite di connessione basso.

Tuttavia, Apache deve anche rispondere alle chiamate da entrambi gli oggetti del server della farm, ad esempio tramite la chiamata su due porte o indirizzi IP separati, uno utilizzato da ciascuna combinazione (server farm / farm). La domanda diventa quindi: sei in grado di definire due punti di ingresso del server delle applicazioni? cioè sei in grado di equipaggiare la tua applicazione front-end Apache (/ vhost?) per rispondere su due porte o indirizzi IP (uno per farm)? Questo è attraverso un po 'di ipotesi di lavoro in quanto non desidero passare troppo tempo con il manuale, ma sono sicuro che potresti risolverlo abbastanza elegantemente quando guardi effettivamente la GUI di AppDirector e l'Apache.

L'impostazione del limite di connessione ha un piccolo inconveniente. Da server fisici, limite di connessione 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."

È quindi necessario definire un limite di connessione molto elevato (con un ampio margine al numero massimo possibile attraverso la base utenti) per il server farm "predefinito" senza restrizioni e impostare il limite di connessione per il server farm "connesso" come basso come devi. La definizione del server fisico dovrebbe avere la somma dei due come limite di connessione, come prerequisito per l'attivazione del limite di sessione desiderato.


Hai anche questo requisito nella tua domanda:

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

Questa è definita una "Pagina di servizio HTTP" nella Guida dell'utente, 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.

Per quanto riguarda il monitoraggio, non ho svolto attività di ricerca approfondita, ma ecco cosa penso:

track the current number of sessions for monitoring purposes

AppDirector sembra avere MIB. Probabilmente è una seccatura trovare l'OID giusto come è di solito, ma probabilmente puoi snmparlo sul tuo strumento preferito.

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

Questo potrebbe richiedere un po 'di pensiero creativo. Supponendo che AppDirector non includa un modello per questo immediatamente, come su:

  • Gli URI all'esterno della farm "registrata" non sarebbero interessati dal limite di sessione. Quindi monitora, sono comunque gli stessi server back-end.
  • Utilizzare invece i controlli di integrità di AppDirector, probabilmente non verranno conteggiati ai fini del limite di sessione imposto. Trova un modo per inviare avvisi al tuo server di monitoraggio :-)
  • Configurare una terza farm, attraverso la quale si superano i controlli sanitari. Disordinato, ma funzionerebbe.

1
Finora, ho scoperto che il modulo mod_security2 è in grado di gestire la sessione in un modo molto simile a quello che ho specificato: secure.jwall.org/blog/2009/01/08/1231374852674.html . Farò qualche ricerca in più sulla tua idea di 2 fattorie, se tale implementazione fosse possibile, certamente semplificherebbe le cose.
the-wabbit il

Risposta del supporto tecnico di Radware: "In AD possiamo limitare solo la larghezza di banda per farm. [...] Il metodo [A] per limitare il numero totale di sessioni su base farm non è attualmente disponibile." Quindi è mod_security allora.
the-wabbit il

Ok, è stato inaspettato. A meno che non mi manchi qualcosa, penso comunque che chiudere la fattoria con un controllo sanitario fallito sarebbe una soluzione più pulita. La tua scoperta su mod_security è molto interessante a prescindere.
ErikE

Probabilmente anche se il supporto è stato un po 'limitato nell'interpretazione della domanda, sembra che sia possibile un limite di sessione a livello di server in AppDirector (a cui sicuramente c'è qualche logica). Ho cercato su
Google

L'articolo KB di Radware riguarda LinkProof, un acceleratore WAN. Non ho idea di quale software stia funzionando e se esistessero servizi simili per AppDirector. A proposito: il codice di gestione della sessione fa sicuramente parte del set di funzionalità di AppDirector - ha una tabella di sessione che assomiglia esattamente a ciò che mi aspetterei. Ma a quanto pare, non c'è modo di imporre un limite al numero di sessioni sessuali - solo sulle connessioni. Il massimo che ho potuto ottenere da esso è limitare il numero di hit in una determinata pagina (ad esempio la pagina di accesso) per unità di tempo come "l'altro" suggeriva Eric.
the-wabbit il

0

Se AppDirector non può aiutarti, ecco un altro approccio che richiederà un po 'di codifica. Affronterei il problema come segue:

  • In un ciclo, continua a leggere il file di registro di Apache (e riaprilo su logrotate)
  • Quando un utente visita qualsiasi pagina (non solo l'accesso), aggiungili a una whitelist di iptables
  • Quando un utente si disconnette o dopo l'inattività (quindi mantieni i timer per le sessioni attive!), Rimuovili dalla whitelist
  • Se la whitelist è piena, reindirizza tutto il traffico non autorizzato a una porta speciale
  • Esegui un semplice vhost su quella porta con il tuo errore personalizzato

Rappresentare graficamente il numero di sessioni diventa semplice quanto rappresentare graficamente la lunghezza della catena iptables. Il server di monitoraggio può essere semplicemente inserito nella whitelist.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.