IRULE
THE TABLE COMMAND
So that we can rate-limit traffic the iRule command 'table' is used. The table command (as the name suggests) provides the ability to create, delete, and append tables, along with being able to define timeouts for each table entry.
Each table that's created contains the following columns.
- Key - This is a key that is assigned to the table entry and reference during table look up.
- Value - This is a value that is assigned to the key.
- Timeout - This is the timeout for the key.
- Lifetime - This is the lifetime for the key. The difference between the timeout and the lifetime value is that at the point of table look up the timeout value is reset.
- Touch Time - This value indicates when the key entry was last touched. This value is mainly used internally.
- Create Time - This value indicates when the key entry was created. This value is mainly used internally.
TABLE EXAMPLE
Below shows an example of the table that is created.
Table : 8.8.8.8:/database/lookup
KEY | VALUE | TIMEOUT | LIFETIME | TOUCH TIME | CREATE TIME |
1 | 8.8.8.8:/database/lookup | indefinite | 1 | 1223830112 | 1223830112 |
2 | 8.8.8.8:/database/lookup | indefinite | 1 | 1223830110 | 1223830110 |
3 | 8.8.8.8:/database/lookup | indefinite | 1 | 1223830107 | 1223830107 |
EXAMPLE
Within our example we will rate-limit on a per IP, per URI basis.
Below is the iRule:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# Function : RateLimit HTTP GET requests per IP, per URI # Created : 29/10/12 when RULE_INIT { set static::maxRate 3 set static::windowSecs 1 } when HTTP_REQUEST { if { ([HTTP::method] eq "GET") and ([class match [string tolower [HTTP::uri]] starts_with DATAGROUP-RATELIMIT-URI] ) } { # whitelist if { [class match [IP::client_addr] equals DATAGROUP-RATELIMIT-WHITELIST] }{ return } # set variables set limiter [string tolower [HTTP::uri]] set clientip_limitervar [IP::client_addr]:$limiter set get_count [table key -count -subtable $clientip_limitervar] # main condition if { $get_count < $static::maxRate } { incr get_count 1 table set -subtable $clientip_limitervar $get_count $clientip_limitervar indefinite $static::windowSecs } else { log local0. "$clientip_limitervar has exceeded the number of requests allowed." drop return } } } |
HOW IT WORKS
The way in which this iRule works is by creating a new table, named IP + URI and appending subsequent requests to the same table.
Each entry has a lifetime value and is removed once reached.
Finally the table is then counted to ensure that the total amount of requests for a given IP and URI has not exceeded the configured threshold.
DATAGROUPS
Within this iRule 2 datagroups are used.
DATAGROUP-RATELIMIT-WHITELIST - (Type:Address) - Contains addresses that are not to be rate-limited.
DATAGROUP-RATELIMIT-URI - (Type:String) - Contains URIs that are to be rate-limited. If all URIs should be rate-limited then just add an / to this datagroup.
CUSTOMIZATION
In order to customize this iRule review the following 2 variables:
1 2 |
set limiter [string tolower [HTTP::uri]] set clientip_limitervar [IP::client_addr]:$limiter |
RATELIMIT USING DIFFERENT ATTRIBUTES
If you wanted to ratelimit on a per IP, per hostname basis then then the line would be:
1 |
set limiter [string tolower [HTTP::host]] |
RATELIMIT USING A SINGLE ATTRIBUTE
Likewise if you wanted to only rate-limit of a per IP basis then the ':limiter' would be removed from the 'clientip_limitvar' variable.
RATELIMIT CONNECTIONS
If you want to rate limit traffic that is not HTTP based or the traffic is encrypted (SSL) then the following iRule can be used (click here).
GOOD TO KNOW
MEMORY
It is worth nothing that the F5 places NO limits on the amount of memory that can be consumed when using the table command. Because of this it is recommended that once you have implemented this iRule that the memory of the device is monitored via the use of the command "show sys mem" within TMSH.
BUGS
There are a number of bugs that can cause excessive memory usage or TMM instability when using the table/session command.
Below are the main F5 bug IDs, ref : BIG-IP cumulative hotfix version 10.2.4
ID381096 - Fixed a TMM connflow memory leak caused by iRule commands that temporarily suspend execution
ID363612 - Memory utilization for TCL string cache has been optimized. Ref : sol13889
ID374923 - Fixed a defect which could cause TMM to restart and leave a core when using the table command in an iRule on an SSL-enabled virtual server.
All of the above are fixed within HF5. However it is recommended to upgrade to the latest hotfix, which at time of writing this is HF7.
MIRRORING
When session or tables are used within iRules Session DB mirroring is still performed, even if mirroring is not enabled on the virtual server.
https://www.fir3net.com/Loadbalancers/F5-BIG-IP/f5-ltm-ratelimiting.html
文章评论