rate limiting
8 TopicsCan I use the F5 for Rate Limiting?
I had been looking at the Session Tracking in ASM previously hoping that it would be able to perform rate limiting. Unfortunately it seems that in order for any lockout to occur via Session Tracking in ASM, a threshold of policy violations needs to be triggered. This is a great feature however not what I am looking for. In the event that a user is spamming or replaying valid requests back to the application, we would want to lockout that user or at least slow them down. Is there some way that the F5 can be utilised to perform rate limiting from an individual eg. session based etc.Solved1KViews0likes1CommentRate Limiting based on ACCESS TOKEN (OAuth 2.0)
Problem this snippet solves: When publishing web services, you need to implement some rate limiting functions to avoid abuses. There are plenty of ways to setup Rate limiting How to use this snippet: The code below setup a rate limiting based on the ACCESS TOKEN. The client will receive a response "429 Too much requests" after 1000 requests in a window of 300 seconds. The client can request its current status by doing a request to /rate_limit_status. He will then receive the following JSON message : { "x-rate-limit-limit": 1000, "x-rate-limit-remaining": 800, "x-rate-limit-reset": 100 } Code : when RULE_INIT { ### # rate limit options ### set static::request_limit 1000 set static::window_size 300 ### # define URI endpoints ### set static::status_uri "/rate_limit_status" } when HTTP_REQUEST { ### # initialize vars ### set access_token "" set client_ip "" ### # retrieve the access_token. It will be used as a mandatory key to evaluate rate limiting ### if { [HTTP::header exists Authorization] and [HTTP::header Authorization] contains "Bearer" } { set access_token [getfield [HTTP::header Authorization] " " 2] set client_ip [IP::client_addr] } if { !($access_token eq "") } { ### # provide client with rate limit status ### set key [sha1 $access_token] set count [table lookup -notouch $key] set time [table timeout -remaining $key] ### # Provide a status page to the client ### if { [HTTP::path] eq $static::status_uri and [HTTP::method] eq "GET" } { if { $count > 0 } { set x_rate_limit_limit "$static::request_limit" set x_rate_limit_remaining "[expr {$static::request_limit-$count}]" set x_rate_limit_reset "$time" } else { set x_rate_limit_limit "$static::request_limit" set x_rate_limit_remaining "$static::request_limit" set x_rate_limit_reset "$static::window_size" } HTTP::respond 200 content "{\"x-rate-limit-limit\": $x_rate_limit_limit,\"x-rate-limit-remaining\": $x_rate_limit_remaining,\"x-rate-limit-reset\": $x_rate_limit_reset}" noserver Content-Type "application/json" Connection Close event disable all } else { ### # Handle the case where a client reach the rate limit ### if { $count >= $static::request_limit } { set x_rate_limit_limit "$static::request_limit" set x_rate_limit_remaining "0" set x_rate_limit_reset "$time" HTTP::respond 429 content "{\"x-rate-limit-limit\": $x_rate_limit_limit,\"x-rate-limit-remaining\": $x_rate_limit_remaining,\"x-rate-limit-reset\": $x_rate_limit_reset}" noserver Content-Type "application/json" Connection Close event disable all } else { if { $count == 0 } { table add $key 1 $static::window_size $static::window_size } else { table incr -notouch $key } } } } } Tested this on version: 11.5999Views0likes1CommentBot and Request Limiting iRule
Problem this snippet solves: This iRule limits robots and what they can do. Furthermore, it restricts requests per second and blacklists a client that goes above the limit Note: Not CMP Compatible. Code : when RULE_INIT { #Define blacklist timeout set ::bl_timeout 30 #Define request per minute threshold set ::req_limit 5 #Expiration for tracking IPs set ::expiration_time 300 #Sets iRule Runlevel 0-log only 1 - Logging and Blocking set ::runlevel 1 } when HTTP_REQUEST { #Captures User-Agent header to check for known robots set ua [string tolower [HTTP::header User-Agent]] log local0. "User Agent: $ua" #Checks to see if the connection is a known robot or requests the robot.txt file if { ([matchclass $ua contains $::RUA]) or ([string tolower [HTTP::uri]] contains "robot.txt") } { set robot 1 log local0. "Robot Detected" } else { set robot 0 } #Defines client_ip variable with the address of the client set client_ip [IP::client_addr] log local0. "Client IP: $client_ip" #Robot logic if { $robot > 0 }{ set bl_check [session lookup uie blacklist_$client_ip] log local0. "Value of bl_check variable: $bl_check" set req_uri [string tolower [HTTP::uri]] log local0. "Request URI: $req_uri" #Checks to see if IP address is on blacklist if { $bl_check ne ""}{ log local0.warn "Request Blocked: $client_ipClient on Blacklist[HTTP::request]" if { $::runlevel > 0 }{ HTTP::respond 403 } } #Checks to see if Robot is allowed and sets restrictions. Default is no access switch -glob $ua { "*slurp*" - "*yahooseeker*" - "*googlebot*" - "*msnbot*" - "*teoma*" - "*voyager*" { if { [matchclass $req_uri starts_with $::robot_block] }{ log local0.warn "Request Blocked: $client_ipRequest Blocked. Robot not following Robot.txt[HTTP::request]" if { $::runlevel > 0 }{ HTTP::respond 403 } } else { pool dave_pool } } default { log local0.warn "Request Blocked: $client_ipRequest Blocked, Unauthoried Robot[HTTP::request]" if { $::runlevel > 0 }{ HTTP::respond 403 } } } } #Logic for non-robots. Checks to see if blacklisted set bl_check [session lookup uie blacklist_$client_ip] log local0. "Non-Robot bl_check: $bl_check" if { $bl_check ne "" }{ log local0.warn "Request Blocked: $client_ipClient on Blacklist[HTTP::request]" log local0.warn "Session Record: $bl_check" if { $::runlevel > 0 }{ HTTP::respond 403 } } set curr_time [clock seconds] set timekey starttime_$client_ip set reqkey reqcount_$client_ip set request_count [session lookup uie $reqkey] log local0. "Request Count: $request_count" #If user uses search their request count is reset if { [HTTP::uri] starts_with "/search" }{ session delete uie $reqkey } #Sets up new count for first time connections. If not a new connection, connection count is incremented and the iRule checks to #see if over the threshold if { $request_count eq "" } { log local0. "Request Count is 0" set request_count 1 session add uie $reqkey $request_count $::expiration_time log local0. "Current Time: $curr_time" log local0. "Timekey Value: $timekey" log local0. "Reqkey value: $reqkey" session add uie $timekey [expr {$curr_time - 2}] [expr {$::expiration_time + 2}] log local0. "Request Count is now: $request_count" } else { set start_time [session lookup uie $timekey] log local0. "Start Time: $start_time" log local0. "Request Count (beyond first request): $request_count" incr request_count session add uie $reqkey $request_count $::expiration_time set elapsed_time [expr {$curr_time - $start_time}] log local0. "Elapsed Time: $elapsed_time" if {$elapsed_time < 60} { set elapsed_time 60 } set curr_rate [expr {$request_count / ($elapsed_time/60)}] log local0. "Current Rate of Request for $client_ip: $curr_rate" if {$curr_rate > $::req_limit}{ log local0.warn "Request Blocked: $client_ipClient over Threshold. Added to Blacklist[HTTP::request]" if { $::runlevel > 0 }{ session add uie blacklist_$client_ip $::bl_timeout HTTP::respond 403 } } } } Tested this on version: 9.0700Views0likes1CommentSession Tracking with ASM - Block All Vs Delay Blocking
Hi Guys, I'm just looking to understand exactly the difference between the 'Block All' and 'Delay Blocking' options for session tracking on ASM policy. Both seem to block after a defined threshold is reached and will block for a defined period of time. It looks like the 'Delay Blocking' options is more granular however I expect that there is something significant I am overlooking. Also, the application I wish to use session tracking on does not have a login page. As a result I will be setting the 'Application Username' to 'none'. Will this allow me to still accurately track if an individual is spamming the application? Thank you599Views0likes1CommentHTTP Rate Limiting - CMP Compatible
Problem this snippet solves: This iRule is a CMP compatible Request per Second Throttling iRule. Code : when HTTP_REQUEST { set debug 1 set expiration_time 300 set client_ip [IP::client_addr] set req_limit 200 set curr_time [clock seconds] set timekey starttime set reqkey reqcount set request_count [session lookup uie $reqkey] if {$debug}{log local0. "Request Count: $request_count"} #Sets up new count for first time connections. If not a new connection, connection count is incremented and the iRule checks to #see if over the threshold if { $request_count eq "" } { if {$debug}{log local0. "Request Count is 0"} set request_count 1 session add uie $reqkey $request_count $expiration_time if {$debug}{log local0. "Current Time: $curr_time"} if {$debug}{log local0. "Timekey Value: $timekey"} if {$debug}{log local0. "Reqkey value: $reqkey"} session add uie $timekey [expr {$curr_time - 2}] [expr {$expiration_time + 2}] if {$debug}{log local0. "Request Count is now: $request_count"} } else { set start_time [session lookup uie $timekey] if {$debug}{log local0. "Start Time: $start_time"} if {$debug}{log local0. "Request Count (beyond first request): $request_count"} incr request_count session add uie $reqkey $request_count $expiration_time set elapsed_time [expr {$curr_time - $start_time}] if {$debug}{log local0. "Elapsed Time: $elapsed_time"} if {$elapsed_time < 60} { set elapsed_time 60 } set curr_rate [expr {$request_count / ($elapsed_time/60)}] if {$debug}{log local0. "Current Rate of Request: $curr_rate"} if {$curr_rate > $req_limit}{ if {$debug}{log local0.warn "Request Blocked: $client_ipClient over Threshold.[HTTP::request]"} HTTP::redirect http://www.company.com/sorry.html } } }460Views0likes1CommentApply DoS Profile Only to Specific URLs
I'm using 11.4.1 and have been tasked with adding additional protection to public facing pages that contain a form that when submitted sends emails. We get a lot of complaints when those pages are scanned and a huge number of emails are sent throughout the company. We are looking for a solution that can be applied for all pages that have this action instead of putting this protection into each website. My initial thought on this was to use the DoS Profile setup for TPS-based Anomaly. However this is applied on a virtual server level and will therefor apply to every page on that server. My preference is to only apply this to the public facing email forms without applying rate limiting across the entire site which could break customer processes. I was hoping this would be as easy as using an LTM policy to turn on and off the DoS Profile per URL, but it doesn't look like that functionality is available. Is there any way of either applying the DoS Profile based on the URL? If not, is there a way to send specific URLs to a specific virtual server which I could then setup just to manage the email page and have the DoS Profile applied? Any other ways of doing rate limiting in the F5. I realize that doing rate limiting on the websites or servers themselves would be best, but getting developers to update websites for changes like this is like herding narcoleptic cats.448Views0likes1CommentProtecting APIs with Access Policy Manager and custom iRules
The problem: Unprotected API - Vulnerable to Overload Without Rate-Limiting Enforcement Our customer in the B2B sector is encountering a challenge with their public API. Despite having implemented a custom method for generating long-lived API keys, they find themselves unable to enforce rate-limiting effectively. This absence of rate-limiting mechanisms poses significant challenges, potentially resulting in the overloading of their system due to excessive requests or the exploitation of their API by unauthorized users. Without proper rate-limiting controls in place, the customer faces risks to both the performance and security of their API infrastructure, necessitating a solution to mitigate these concerns and ensure the smooth operation of their services for their clients. Our customers wants to offer two tiers of service level agreements (SLAs) - gold and standard. Complicating matters further, the API key, integral to authentication, is transmitted via a custom HTTP header. The solution: BIG-IP APM and Custom iRules for Effective Rate-Limiting My solution involves leveraging the API Protection feature of BIG-IP APM in conjunction with a custom iRule. By utilizing this combination, our customer can effectively extract the API Keys from HTTP requests and enforce rate limiting on specific API endpoints. As for now they only want to enforce rate limiting on the POST endpoints. This approach empowers the customer to secure their API while efficiently managing and controlling access to critical endpoints, ensuring optimal performance and safeguarding against abuse or overload. With this iRule we can to extract the API key from the HTTP Requests and store it in a variable, that can later be used by the API Protection feature of the APM. API Keys and the associated SLA level are stored in a Data Group of the type string. # Enable (1) or disable (0) logging globally when RULE_INIT { set static::debug 1 } # Access and analyze the HTTP header data for SLA value when HTTP_REQUEST { set sla [class lookup [HTTP::header value apikey] dg_apikeys] if { $static::debug } {log local0. "Made it to HTTP_REQUEST event with SLA value $sla."} } # Evaluate SLA value during per-request access policy execution when ACCESS_PER_REQUEST_AGENT_EVENT { set id [ACCESS::perflow get perflow.irule_agent_id] if { $id eq "read-sla" } { if { $static::debug } {log local0. "Made it to iRule agent in perrequest policy with SLA value $sla."} ACCESS::perflow set perflow.custom "$sla" } } And this is how the Per Request Policy in the API Protection profile looks. It uses the value of the API Key (extracted with the help of the the iRule) and the Source IP of the client to enforce Rate Limiting on the POST endpoints, using two different SLAs. In the APM log you should see the following message, once the client exceeds his quota defined in the SLA. Apr 28 20:12:42 ltm-apm-16.mylab.local notice tmm[11094]: 01870075:5: (null):/Common: API request with weight (1) violated the quota in rate limiting config(/Common/demo_api_ratelimiting_auto_rate_limiting_standard). Apr 28 20:12:42 ltm-apm-16.mylab.local notice tmm[11094]: 0187008d:5: /Common/demo_api_ratelimiting_ap:Common:6600283561834577940: Execution of per request access policy (/Common/demo_api_ratelimiting_prp) done with ending type (Reject) Further reading: You can find a more detailed write-up on my GitHub page: https://github.com/webserverdude/f5_APM_API_Protection There you can find the Per Request Policy explained in all details. The Data Group with for the iRule. A demo API for testing my solution. A Postman Collection for working with my demo API.238Views2likes0CommentsEffective Traffic Management: Addressing ADC04's Insufficient Traffic Controls
Applications today face unprecedented demand variability, requiring organizations to prioritize effective traffic management to ensure a seamless user experience. ADC04, one of the key challenges in application delivery per F5's "Application Delivery Top 10," highlights insufficient traffic controls. This issue plagues high-demand environments across industries such as e-commerce, healthcare, high-tech, automotive, insurance, and more, leading to performance bottlenecks, reduced availability, inefficiencies, and scalability challenges. Let's discuss the implications and solutions for this issue, with an added use case to demonstrate practical implementation. AI Reference Architecture The Challenge of Insufficient Traffic Controls Modern digital ecosystems experience fluctuating traffic volumes due to use cases like e-commerce promotions, flash sales, or API-driven workloads. For example, an e-commerce API could go from handling hundreds of requests per second (RPS) to thousands or more during promotional events. Without proper rate limiting, throttling, or caching mechanisms, public APIs become vulnerable to overburdened backend services, Distributed Denial of Service (DDoS) attacks, and inefficient scaling. Automated processes, such as analytics workloads, CI/CD deployments, and backups, exacerbate uneven workloads on backend systems. Furthermore, modern AI applications with data-intensive processing introduce yet another layer of complexity, requiring sophisticated traffic controls. The Consequences of Inefficient Traffic Controls Performance Issues Excessive traffic without sufficient controls leads to backend overload, degrading application response time. For example: User Frustration: Slow response times result in poor customer experiences, where 70% of shoppers abandon purchases due to delays. Critical Application Failures: In AI use cases, such as real-time conversational bots, processing delays impact outcomes and user trust. Reduced Availability API services lacking rate limiting and traffic throttling are especially prone to DDoS attacks or service outages. Additionally, backend systems may face resource starvation due to unoptimized caching mechanisms, reducing availability even during normal traffic conditions. Limited Scalability Applications unable to intelligently manage traffic flows struggle to handle unexpected traffic spikes. Inefficient caching and chaotic workload distribution limit the capacity to scale dynamically. Operational Inefficiencies The absence of automated traffic controls forces manual monitoring and intervention during traffic surges. High operational overhead and inefficient resource usage affect cost-effective management of infrastructure. Use Case example: Implementing Traffic Controls for an E-Commerce Public API The diagram below illustrates a practical implementation of traffic controls using advanced Application Delivery Controller (ADC) features (e.g., BIG-IP Local Traffic Manager) for an e-commerce public API. While tailored for e-commerce, these are equally applicable to other industries, such as finance, insurance, high-tech, and automotive. Key Features for Effective Traffic Management: Global Rate Limiting: Enforces a cap on total requests per second (RPS) to avoid backend overload. Per-API Key Throttling: Limits RPS at an API key level (e.g., 100 RPS per user), ensuring fair usage. CAPTCHA Trigger: Introduces CAPTCHA challenges for clients exceeding predefined limits to mitigate abuse. Circuit Breaker Logic: Detects faults in backend API servers and reroutes traffic to stable instances where possible. Traffic Forwarding or Rejection: Directs healthy requests to backend API servers and rejects problematic traffic. Comprehensive Logging and Metrics: Logs control events, such as rate-limit breaches or circuit-break activations, and streams them into observability platforms like ELK, Prometheus, or Datadog for dashboards and automated alerts. Functionality Overview Clients Send API Requests: Public API clients interact with the ADC (BIG-IP LTM), where all incoming requests are initially processed. Rate Limiting and Key Enforcement: The ADC enforces global rate limits and per-client throttling policies to avoid overloading backend servers. Action on Violations: Requests breaching limits trigger appropriate actions—delays, CAPTCHAs, or outright rejection. Health-Check Monitoring: The ADC regularly monitors backend API servers for faults and dynamically reroutes traffic to healthy nodes using circuit-breaker policies. Logs and Metrics Streaming: All traffic patterns, rule activations, and violations are logged and streamed to observability platforms for operational transparency. Best Practice Recommendations for Traffic Controls Rate Limiting and Throttling Global and per client rate limits are critical for protecting backend services during demand surges. For example: Put a 100 RPS cap per API key. Differentiate limits for premium services or geographies where critical workloads demand higher quality of service. Intelligent Caching Caching reduces backend load by offloading repetitive requests: Use semantic and edge caching for dynamic workloads like AI APIs. Adopt adaptive caching mechanisms to handle variable traffic patterns and reduce latency. Circuit Breaker Logic Circuit breakers prevent cascading failures in the API ecosystem by rerouting traffic to healthy systems: Monitor backend server health dynamically. Use adaptive retry mechanisms to minimize disruptions. Observability and Logging Real-time logging and monitoring tools like ELK or Prometheus provide insights into API performance: Set up custom dashboards to monitor API health, rate-limit violations, and traffic loads. Automate alerts for anomalies (e.g., high latency or recurring limit breaches). Conclusion As demonstrated by the use case, robust traffic controls are essential for managing fluctuating workloads, ensuring availability, and optimizing operational efficiency. Layered controls such as rate limiting, advanced caching, and circuit breaker mechanisms enforce resilience and scalability. Integrating observability tools ensures transparency and rapid issue resolution in real time. With insufficient traffic controls identified as a major challenge, adopting these strategies is crucial for long-term API operational success, particularly for high-traffic environments across industries such as e-commerce, finance, insurance, high-tech, and automotive. Reference Article Managing Traffic with Bandwidth Controllers Intelligent Traffic Management with the F5 BIGIP Platform Mitigating OWASP API Security Risks: Unrestricted Resource Consumption using BIG-IP iRule::ology - Table Based Rate Limiting AI reference architecture ADSP Platform overview The Application Delivery Top 1065Views1like0Comments