Forum Discussion

kanokwut_thanad's avatar
kanokwut_thanad
Icon for Nimbostratus rankNimbostratus
Mar 08, 2005

Concurrent connection limit

Hi,

 

 

We are using Big-IP 6400 in our network for managing of 30-40k concurrent connections with 4-5 comprehensive rules.

 

 

Now, I would like to limit concurrent connections from the same client IP to our virtual servers (e.g. less than 10 connections per client).

 

 

Anyone here, could you please advice me how to do?

 

 

Best regards,

 

Kanokwut
  • drteeth_127330's avatar
    drteeth_127330
    Historic F5 Account
    This feature has been requested several times and will be added to a subsequent version of the product. However, you can enforce the limit using iRules. I would prefer that you attempt to write the rule first, and I will help if you get stuck. You can use the session command to add an entry in the session table for each client IP. The session table will automatically expire old entries if you specify a timeout. If the limit is exceeded, you can reject the connection. Hope this helps.
  • drteeh,

     

     

    Could you please give me a format of session command?

     

     

    I could not found this command in a Configuration Guide manual.

     

     

    Thank you for your response,

     

    Kanokwut
  • drteeth_127330's avatar
    drteeth_127330
    Historic F5 Account

     

    session add []

     

    session lookup

     

    session delete

     

    = | { [any [virtual|service|pool] | pool ...] }

     

    = simple | source_addr | sticky | dest_addr | ssl | uie | universal | hash

     

     

     

    UnRuley might have posted this in the past. You should probably search the old forum posts. Good luck!
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Here is a sample rule that uses cookies to track a given client and limit the total number of clients to 50. This rule uses a Tcl array to track the current clients:

       
       rule session_limit {   
          when RULE_INIT {   
             array set ::active_sessions { }   
             set ::total_active_clients 0   
             set ::max_active_clients 50   
          }   
          when HTTP_REQUEST {   
             if { not [info exists client_id] } {   
                if { [HTTP::cookie exists "ClientID"] } {   
                   set client_id [HTTP::cookie "ClientID"]   
                   set need_cookie 0   
                } else {   
                   set client_id [string range [AES::key 128] 8 end]   
                   set need_cookie 1   
                }   
                if { not [info exists ::active_sessions($client_id)] } {   
                   if { $::total_active_clients >= $::max_active_clients } {   
                      HTTP::redirect "http://yoursiteisdown.com/"   
                      return   
                   }   
                   incr ::total_active_clients   
                   set ::active_sessions($client_id) 1   
                } else {   
                   incr ::active_sessions($client_id)   
                }   
             }   
          }   
          when HTTP_RESPONSE {   
             if { $need_cookie } {   
                HTTP::cookie insert name "ClientID" value $client_id   
                set need_cookie 0   
             }   
          }   
          when CLIENT_CLOSED {   
             if { [info exists client_id] and [info exists ::active_sessions($client_id)] } {   
                incr ::active_sessions($client_id) -1   
                if { $::active_sessions($client_id) <= 0 } {   
                   unset ::active_sessions($client_id)   
                   incr ::total_active_clients -1   
                }   
             }   
          }   
       }   
       

    The above example can easily be converted to simply track the client IP's:

       
       rule session_limit {   
          when RULE_INIT {   
             array set ::active_clients { }   
          }   
          when CLIENT_ACCEPTED {   
             set client_ip [IP::remote_addr]   
             if { [info exists $::active_clients($client_ip)] and $::active_clients($client_ip) > 10 } {   
                log "Client $client_ip has too many connections"   
                reject   
                return   
             }   
             incr ::active_clients($client_ip)   
          }   
          when CLIENT_CLOSED {   
             if { [info exists ::active_clients($client_ip)] } {   
                incr ::active_clients($client_ip) -1   
                if { $::active_clients($client_ip) <= 0 } {   
                   unset ::active_clients($client_ip)   
                }   
             }   
          }   
       }   
       

    NOTE: a problem has been discovered with the session command in that it causes the tmm to restart when used in the CLIENT_CLOSED event. This makes using the session command for this kind of problem less useful. This will be fixed in a future release (CR46047).
  • hirox_127495's avatar
    hirox_127495
    Historic F5 Account
    This code will work on 9.0.4...

     

     

    when RULE_INIT {    
       array set ::active_clients { } 
       log local0. "phase1"  
     }    
     when CLIENT_ACCEPTED {    
       set client_ip [IP::remote_addr]    
       if { [info exists ::active_clients($client_ip)] } { 
         if  {$::active_clients($client_ip) > 10 } { 
           log "Client $client_ip has too many connections"    
           reject    
           return    
         } else { 
           log local0. "$::active_clients($client_ip)" 
           incr  ::active_clients($client_ip) 
         } 
       } else { 
         set ::active_clients($client_ip) 1 
       } 
     }    
     when CLIENT_CLOSED {    
       if { [info exists ::active_clients($client_ip)] } {    
         incr ::active_clients($client_ip) -1    
         if { $::active_clients($client_ip) <= 0 } {    
           unset ::active_clients($client_ip)    
         }    
       }    
     }