Forum Discussion

domokos_23867's avatar
domokos_23867
Icon for Nimbostratus rankNimbostratus
Oct 30, 2009

Connection limit based on IP subnet

Hi,

 

 

I found this link http://devcentral.f5.com/Wiki/default.aspx/iRules/LimitConnectionsFromClient.html that is great, and works fine. There is only one thing that I would need to change and I cannot figure out how. We need to limit the connections based on IP ranges with variable subnets instead of IPs. I could of course list all the possible IPs but that could get very messy. So what I would really need is a white list of IP subnets and not hosts. Does anybody have an idea how?

 

 

Thanks in advance

 

Carol

5 Replies

  • Hi Carol,

    If you use assume a /24 subnet, you could use something like this:

     
     when RULE_INIT { 
      
         The maximum number of TCP connections to the virtual server from a single client subnet 
        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 named white_client of type 'address' once done testing! 
        set ::white_client [list \ 
          10.41.0.0 \ 
          10.11.12.0 \ 
        ] 
     } 
      
     when CLIENT_ACCEPTED { 
      
        log local0. "\$::active_clients: [array get ::active_clients] (size: [array size ::active_clients])" 
      
         Scan the octets of the client IP address into four variables 
        scan [IP::client_addr] {%[0-9].%[0-9].%[0-9].%[0-9]} 1 2 3 4 
      
         Save the "network" of the IP using /24 subnet (last octet is 0) 
        set slash_24_subnet "$1.$2.$3.0" 
      
         Check if the client is already in the active clients array 
        if { ([info exists ::active_clients($slash_24_subnet)]) } { 
      
            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($slash_24_subnet) 
           log local0. "Incremented \$::active_clients($slash_24_subnet) to: $::active_clients($slash_24_subnet)" 
      
            Check if client is already over the maximum 
           if {$::active_clients($slash_24_subnet) > $::max_connections_per_ip} { 
      
               Send TCP reset to client 
              reject 
      
              log local0. "Rejected IP [IP::client_addr] (subnet: $slash_24_subnet), count ($::active_clients($slash_24_subnet))" 
      
           } 
            Don't need an else clause here.  The default action will be to allow the connection to continue. 
      
        } elseif { ![matchclass [IP::client_addr]/24 equals $::white_client] }{ 
      
            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($slash_24_subnet) 1 
           log local0. "Initialised \$::active_clients($slash_24_subnet) to: 1" 
        } 
     } 
     when CLIENT_CLOSED { 
      
         Check if the client has a count in the array 
        if { [info exists ::active_clients($slash_24_subnet)]} { 
      
            Decrement the count by 1 
           incr ::active_clients($slash_24_subnet) -1 
      
            Check if the count is 0 or negative 
           if { $::active_clients($slash_24_subnet) <= 0 } { 
      
               Clear the array element 
              unset ::active_clients($slash_24_subnet) 
           } 
        } 
     } 
     

    Aaron
  • Well you could use a catch statement

     

     

    Here is an forum post that talks about validating IP address especially if there are ip subnets involved.

     

    http://devcentral.f5.com/Default.aspx?tabid=53&view=topic&postid=16332

     

     

    I hope this helps

     

     

    CB
  • Thank you both for the very quick answers. I was hammered today with operational issues so did not yet have time to digest the info. I hope to be able tot test them out tomorrow. Thanks again!
  • Hi Carol,

     

     

    make sure to replace the TCL list in the RULE_INIT event with a datagroup of type 'address' which contains the client hosts and/or subnets you do not want to apply the restrictions for. You can then remove the setting of the whitelist from the RULE_INIT event.

     

     

    Aaron