For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

Parveez_70209's avatar
Parveez_70209
Icon for Nimbostratus rankNimbostratus
Sep 20, 2014

Removing global variables from Irule : LTM Ver 10.2.4

DO NOT DUPLICATE THIS IRULE WITHOUT MAKING ALL static namespace VARIABLES UNIQUE! THESE VARIABLES ARE AVAILABLE TO ALL iRules ON THE LTM!!! This iRule will rate limit based on source IP address A dataclass must be created, and the name assigned to the IPWhitelist variable in the RULE_INIT event

when RULE_INIT {

Set Static variables to be shared amongst all TMMs These variables must not be changed by the iRule itself, only referenced If the values need to be tweaked, they must be edited from the GUI MaxRate_AGO is the threshold where requests will start to be blocked in transactions per second WindowCalc is the length of the window in seconds used to calculate the transaction rate. Making this value too small may result in legitimate traffic being blocked on initial page load if there are a large number of small objects ShortBlockTime is the amount of time in seconds that an IP will be blocked unless it triggers the long block time LongBlockTime is the amount of time in seconds that an IP will be blocked after triggering the long block time LongBlockTrigger is the number of times an IP can trigger the short time block before having the long block time assigned ie: If LongBlockTrigger is set to 3, the first three times an IP exceeds the MaxRate_AGO it will be blocked for ShortBlockTime. the fourth time it exceeds the MaxRate_AGO it will be blocked for the LongBlockTrigger GracePeriod is the amount of time in seconds after the last block that the block count is cleared. After this time, any IP that was blocked for the LongBlockTime that exceeds the MaxRate_AGO will first be blocked for the ShortBlockTime Redirect_URL is the URL to send clients to that are being blocked. Debug_Logging : Setting to 1 enables additional logging to help troubleshoot issues with the iRule and to see what the iRule might do if Debug_Action is set to 1 Debug_Action Setting to 1 will cause the iRule to do all traffic processing, but not actually block requests.
            set static::IPWhitelist "outlet.lenovo.com_prevent_abuse_whitelist"
            set static::MaxRate_AGO 15
            set static::WindowCalc_AGO 300
            set static::ShortBlockTime_AGO 1800
            set static::LongBlockTime_AGO 3600
            set static::LongBlockTrigger_AGO 3
            set static::GracePeriod_AGO 3600
            set static::Redirect_URL_AGO "http://www.lenovo.com/us/en/blocked/index-block.html?AGO"
            set static::Debug_Logging_AGO 1
            set static::Debug_Action_AGO 1

}

when HTTP_REQUEST {

            if { [HTTP::header exists "True-Client-IP"] } {
                            set ClientIP [HTTP::header "True-Client-IP"]
            } else {
                            set ClientIP [IP::client_addr]
            }
            set currentTime [clock seconds]
            set windowStart [expr {$currentTime - $static::WindowCalc_AGO}]
            set reqCount 0
            set RepeatOffender 0



             Check to see if the IP is in the White list.  If so, no reason to do the math and track requests


            if { ![class match $ClientIP equals "$static::IPWhitelist" ] } {
                             Check to see if the IP is in the BlackList table, if so no need for math.
                            if { [table lookup -notouch -subtable "BlackList" $ClientIP] ne "" } {
                                            if { $static::Debug_Logging_AGO == 1 } {
                                                            log local0. "LOG100AGO-${ClientIP} Client IP found in Blacklist, default action is block"
                                            }
                                            if { $static::Debug_Action_AGO == 0 } {
                                                            HTTP::respond 503 Location $static::Redirect_URL_AGO
                                            }
                            } else {                  
                                             Sum the number of requests made during the defined window to calculate 
                                             the rate and remove pointers that are older than the window start
                                            foreach { requestTime  } [table keys -subtable "REQ:${ClientIP}"] {
                                                            if { $requestTime > $windowStart } {
                                                                            incr reqCount 1
                                                            } else {
                                                                            table delete -subtable "REQ:${ClientIP}" $requestTime
                                                            }
                                            }
if { $reqCount < $static::MaxRate_AGO } { add new record to the session table for counting purposes set keyvalue "$currentTime..[expr { int(10000000 * rand()) }]" table set -subtable "REQ:${ClientIP}" $keyvalue "ignored" $static::ShortBlockTime_AGO $static::ShortBlockTime_AGO } else { Uncomment the line below if you want messages indicating when a client exceeds the request limit if { $static::Debug_Logging_AGO == 1 } { log local0. "LOG200AGO-${ClientIP} has exceeded the request limit, Request denied" } if { $static::Debug_Action_AGO == 0 } { HTTP::respond 503 Location $static::Redirect_URL_AGO } Check to see if this is a frequent flyer and apply the LongBlockTime_AGO if so Otherwise the ShortBlockTime_AGO if { [table lookup -notouch -subtable "RepeatOffender" ${ClientIP}] > $static::LongBlockTrigger_AGO } { table set -subtable "BlackList" $ClientIP "ignored" $static::LongBlockTime_AGO $static::LongBlockTime_AGO if { $static::Debug_Logging_AGO == 1 } { log local0. "LOG300AGO-${ClientIP} is a repeat offender, applying LongBlockTime_AGO" } } else { table set -subtable "BlackList" $ClientIP "ignored" $static::ShortBlockTime_AGO $static::ShortBlockTime_AGO table incr -subtable "RepeatOffender" $ClientIP table timeout -subtable "RepeatOffender" $ClientIP $static::GracePeriod_AGO if { $static::Debug_Logging_AGO == 1 } { log local0. "LOG400AGO-${ClientIP} has been blocked for the ShortBlockTime_AGO" } return } } } } else { return } }

9 Replies

  • Hi Team,

     

    Expecting to get the biggest benefit from simply removing the global variables, which then should allow both LTM processors to have the workload more evenly distributed. Based on LTM documentation/discussions, we know that with global variables, the code can only be executed on 1 processor on the LTM, which is ultimately our goal to drive down the highest processor usage.

     

    How to edit the mentioned Irule. Kindly guide

     

  • Parveez,

     

    Can you paste your iRule over a https://gist.github.com so I can read it in its proper formatting? Just provide a link to it here.

     

  • Hi Kevin,

     

    Uploaded the Irule into the below: Subject of the Irule is: Irule To Remove Global Variables

     

    https://gist.github.com/parveezarif/9806a99e08eb1a4fd449

     

    Kindly guide, our LTM Processing is increasing a lot because of these variables.

     

    Thanks and Regards Parveez

     

  • Their is no performance penalty with static::variables. It is only non-static variables which cause this behaviour. Your iRule is already running on across all available LTM processors. You can verify this with

     

    watch tmsh show ltm virtual vs_http

     

    Look for

     

    CMP : enabled

     

    CMP Mode : all-cpus

     

  • The first suggestion that comes to mind for performance improvement is replace every instance of == with eq

     

    More as I read it in more detail.

     

  • Hi Kevin,

     

    We are in a first phase, we will try replacing with == with eq, can you also suggest whether we need to look into the $ replacement too.

     

    Kindly guide, if yes, how my Irule will look like. Please suggest.

     

    Thanks and Regards PZ

     

  • And, are the below also non-compatible Irules ?

    } elseif {[matchclass [HTTP::uri] contains abc_admin_paths]} {
    } elseif {[matchclass [HTTP::uri] starts_with dg_abc_mgd_url_blocks]} {
    
    Can we make it as class match instead of matchclass ? If we do so any syntax change apart from this will happen ?