Forum Discussion

Alberto_Peretti's avatar
Alberto_Peretti
Icon for Nimbostratus rankNimbostratus
May 27, 2010

Limit connections from the same IP address

Hello,

 

I'm trying to write an iRule to be able to limit the number of TCP connections established on a virtual server per single IP address. On the code share I see that there is an iRule that should do this, but on my enviroment it doesn't work. I have 2 BigIPs 3600 running version 10.0.1. If I use this iRule I see that the connections are properly counted but once I reach the limit defined in the iRule the same IP address can still establishes new connections on the same viryual server.

6 Replies

  • The log seems to work properly. I mean that I can see the counter incrementing while the same IP address establishes connections to a virtual server. For example I set the limit to 3 connections and I see the counter reach 5 connections established
  • This is the iRule limited ti ip adress 10.10.10.110:

     

     

    when RULE_INIT {

     

     

    The maximum number of TCP connections to the virtual server from a single client IP address

     

    set ::max_connections_per_ip 10

     

     

    Clear the array of clients with open connections to the VIP

     

    array set ::active_clients { }

     

     

    Replace this array with a datagroup of type 'address' once done testing!

     

    array set white_client {

     

    10.10.10.110

     

    }

     

    }

     

     

    when CLIENT_ACCEPTED {

     

     

    log local0. "\$::active_clients: [array get ::active_clients] (size: [array size ::active_clients])"

     

     

    Check if the client is already in the active clients array

     

    if { ([info exists ::active_clients([IP::client_addr])]) } {

     

     

    Regardless of whether we reject this client, we've already accepted the TCP connection.

     

    so increment the counter for this client. The count will be decremented when the connection is closed.

     

    incr ::active_clients([IP::client_addr])

     

    log local0. "Incremented \$::active_clients([IP::client_addr]) to: $::active_clients([IP::client_addr])"

     

     

    Check if client is already over the maximum

     

    if {$::active_clients([IP::client_addr]) > $::max_connections_per_ip} {

     

     

    Send TCP reset to client

     

    reject

     

     

    log local0. "Rejected IP [IP::client_addr], count ($::active_clients([IP::client_addr]))"

     

     

    }

     

    Don't need an else clause here. The default action will be to allow the connection to continue.

     

     

    } elseif { ![info exists ::white_client([IP::client_addr])] }{

     

     

    Client wasn't already in the array and isn't in the white list, so add them to the array with a count of 1.

     

    set ::active_clients([IP::client_addr]) 1

     

    log local0. "Initialised \$::active_clients([IP::client_addr]) to: 1"

     

    }

     

    }

     

    when CLIENT_CLOSED {

     

     

    Check if the client has a count in the array

     

    if { [info exists ::active_clients([IP::client_addr])]} {

     

     

    Decrement the count by 1

     

    incr ::active_clients([IP::client_addr]) -1

     

     

    Check if the count is 0 or negative

     

    if { $::active_clients([IP::client_addr]) <= 0 } {

     

     

    Clear the array element

     

    unset ::active_clients([IP::client_addr])

     

    }

     

    }

     

    }

     

  • 10.10.10.110 is in the whitelist so by design, it wouldn't ever get limited. Can you either remove 10.10.10.110 from the whitelist or test from a different client IP address?

     

     

    Aaron