Networking & Content Delivery

How to configure block duration for IP addresses rate limited by AWS WAF

Volumetric attack is one of the most common type of cyberattack, where a web application is overwhelmed with an enormous number of HTTP requests. This flood of excessive requests puts a strain on the application’s servers, leading to degraded performance, increased latency for legitimate users and in severe cases, resource exhaustion.

AWS WAF’s rate-based rules monitor and control the rate of incoming requests. When configured with block action on source IP address as the aggregation key, it blocks the requests from clients that exceeds the rate-based rule’s threshold limit. However, some malicious actors may employ sporadic HTTP request floods over extended periods, reusing the same set of IP addresses by waiting for their IP addresses to be unblocked by AWS WAF rate-based rules when the request rate falls below the defined threshold.

To effectively prevent such malicious actors from reusing IP addresses to launch HTTP request floods on your applications, it becomes necessary to take more stringent measures. Malicious actors find it relatively expensive and time-consuming to acquire and employ multiple IP addresses for generating the HTTP request floods. As a result, they become discouraged, knowing that their efforts to disrupt the application are continuously thwarted.

In this post, you will learn how to leverage AWS WAF rate-based rules to block IPs that breach the threshold limit, for an extended time period. This is one of the effective approach to prevent malicious actors from reusing the same set of IP addresses to generate HTTP request floods. By combining this strategy with other security measures you can create a comprehensive defense for your web applications.

Solution overview and architecture

This solution lets you configure the time period for which you want the originating IP address to be blocked if it has previously violated the configured threshold for the rate-based rule.

  • It works with both IPv4 and IPv6 traffic.
  • It blocks the IP addresses blocked by a rate-based rule for a configurable time period. Minimum supported block period is 6 minutes.
  • The solution blocks a maximum of 10000 IPs for both IPv4 and IPv6 at a time.
  • The solution might release the blocked IP addresses with a delay of up to 75 seconds than the configured block period.

Architecture overview

Diagram showing the architecture of the proposed solution in the given blog

Figure 2: Solution Architecture

Solution workflow

When launching the AWS CloudFormation template, you must define the time period for which you would like the malicious IP addresses to remain blocked. The solution uses an Amazon EventBridge Rule to trigger an AWS Lambda function every minute that retrieves the IP addresses currently blocked by the rate-based rule using the AWS WAFv2 GetRateBasedStatementManagedKeys API. The Lambda function stores these IP addresses in a file within an Amazon Simple Storage Service (Amazon S3) bucket that is created by the solution and includes the current timestamp.

This solution adds the IP addresses from the Amazon S3 file to the custom IP sets that were created by the solution, which you must use in your custom IP block rule. In each subsequent iteration, any newly blocked IP addresses by the rate-based rule are added to the file. Any IP addresses that have been present in the file for more than the designated block period are removed from the list, and the custom IP sets are updated with the new list of IP addresses.

Prerequisites

The solution assumes that you’ve previously set up an AWS WAF WebACL with a rate-based rule. If you have not done so, then follow the instructions for creating AWS WAF Rate-Based Rule.

You must provide the following parameters while launching the CloudFormation template:

  • Custom Block Period: Specify the time in minutes to keep the IP address blocked, minimum is 6 minutes
  • Rate-Based Rule Name: Existing rate-based rule’s name
  • Scope: CLOUDFRONT or REGIONAL
  • WebACL Id: Existing WebACL Id
  • Web ACL Name: Existing WebACL name

Deploying the solution

Download the AWS CloudFormation template named customized-block-period-template.yaml from the solution’s GitHub page.

After you’ve downloaded the template, access the CloudFormation console to create the stack. See the CloudFormation User Guide for instructions on selecting a downloaded template in the CloudFormation console to deploy a stack.

Note: Deploy your stack in the region where your WebACL is present. To use this solution with a WebACL associated with Amazon CloudFront, deploy the stack in the US East (N. Virginia) Region.

On the Specify stack details page, enter the stack name and specify the values for the parameters described in prerequisites section of the blog.

The template spins up multiple cloud resources, such as the following:

Image showing resources created by the solution

Figure 3: Resources created by the solution

This solution is quickly deployed to your account and ready to use in less than 15 minutes. Once the stack status changes to CREATE_COMPLETE the next step is to create a custom AWS WAF rule below the rate-based rule to block the IPs present in the IPSets created by the template:

Image showing the configuration of a sample block rule created in the WebACL using the IPSets created by the solution

Figure 4: Custom WAF block rule using the IPSets created by the solution

Note : If there are any proxies or load balancers before the resource where your WebACL is associated, you should configure the rate-based rule and custom rule based on the forwarded IP address. This address is usually found in the X-Forwarded-For header.

Validating the solution

Now that the solution is deployed, let’s run a validation test using the bash script which generates a flood of HTTP GET requests at the beginning to the specified test URL, and then sends a request every 3 minutes to check the IP block status. It measures the time for which the source IP was blocked by calculating the time difference between the first and the last request with the 403 Forbidden status code.

Prerequisites before using the script:

  1. Make sure that your test URL returns a 200 status code by using the following command:

curl -s -o /dev/null -w "%{http_code}\n" http://example.com

Note: Ensure to replace the URL in the command with your own test URL.

  1. Make sure that the rate-based rule and the custom rule doesn’t have a custom response code set, as the validation script expects a 403 status code on getting blocked by AWS WAF.
  2. Set the rate-based rule’s threshold value to 150 for this test.

To execute this script, use the following commands from a Linux terminal. In the second command below, replace the given URL with your test URL:

$ chmod +x customized-block-period-validation-script.sh 
$ ./customized-block-period-validation-script.sh http://example.com 
Completed 10 requests without block 
Completed 20 requests without block 
Completed 30 requests without block 
…… 
Completed 820 requests without block
Completed 830 requests without block 
Your IP is blocked now 
Your IP is blocked now 
2023-06-03 17:22:27 HTTP Status Code= 403 
2023-06-03 17:22:28 HTTP Status Code= 403 
…… 
2023-06-03 18:02:16 HTTP Status Code= 403 
2023-06-03 18:02:19 HTTP Status Code= 403 
Your IP was blocked for around: 10 minutes 25 seconds

For this validation test, I had specified the custom block period as 10 minutes while deploying the solution and as my source IP was blocked for around 10 minutes 25 seconds which is within the expected range of variance in block period by the solution, that is a delay of up to 75 seconds than the configured block period. Therefore the solutions works as expected.

Cost for the Solution

The following tables shows an approximate cost breakdowns for running this solution in the US East (N. Virginia) Region (excludes AWS Free Tier). Prices are subject to change.

AWS Service Dimensions/Month Cost in USD
Amazon S3 44,640 PUT requests(31 days * 24 hours * 60 minutes), 44,640 GET requests, 2.5e-8 GB ~$0.24
AWS Lambda 128 MB: 1 functions, 44640 invocations, and 10000 millisecond duration(maximum) per Lambda run ~$0.94
AWS WAF rule 1 custom rule  $1.00
Total Per Month ~$2.18

The cost for custom WAF rule mention in the above table is over and above cost of your existing WAF charges which includes but not limited to Web ACL charges, rule charges, and request processing fees. See WAF Pricing for details.

Further, there would be additional charges for the CloudWatch logs generated by the AWS Lambda function and the Amazon S3 server access logs generated by S3 bucket used to store the list of blocked IPs, while the use of services like AWS CloudFormation and Amazon Eventbridge Rule is free of charge.

It’s recommend to delete or archive logs to reduce the cost and create a budget through AWS Cost Explorer to help manage costs. For full pricing details, refer to the pricing webpage for each AWS service you used in this solution.

Conclusion

It is crucial to emphasize that this solution should be employed in conjunction with other security measures to establish a comprehensive defense for your web applications. In addition, AWS WAF rate-based rules have evolved to support additional request parameters, including cookies, HTTP headers, and composite keys. These enhancements offer more precise and granular options for managing and securing web application traffic. To explore these advanced capabilities, refer to the “Aggregation options and keys” section for AWS WAF rate-based rules.

In this post, we have discussed a method to block IP addresses that have been rate-limited by an AWS WAF rate-based rule for a customizable duration. This approach effectively prevents malicious actors from reusing the same set of IP addresses to generate HTTP request floods against your application. By implementing this solution, you can bolster the effectiveness of rate-based rules and enhance the DDoS resilience of your web application.

To learn more about best practices for DDoS resiliency, see our whitepaper, AWS Best Practices for DDoS Resiliency.

For more information and guidance on AWS WAF rate-based rules, see this post: The three most important AWS WAF rate-based rules.

If you have feedback about this post, submit comments in the following Comments section. If you have questions about this post, start a new thread on the AWS WAF forum or contact AWS Support.

Devansh Agrawal

Devansh Agrawal

Devansh is a Cloud Engineer at AWS. He is passionate about protecting infrastructure from Layer 4 and Layer 7 attacks. Devansh enjoys working with customers to solve their technical challenges and create secure and scalable architectures on the AWS Cloud. He also has a keen interest in the edge domain. Outside of work, Devansh loves trying different cuisines and traveling.

Shivam Tripathi

Shivam Tripathi

Shivam is a Cloud Engineer with approximately four years of experience in AWS, specializing in networking and application security. He is also a subject matter expert in AWS WAF. As part of his work, he helps customers to troubleshoot technical issues, provide solutions for their technical requirements and optimize their use of AWS services. Outside of works he loves to travel and spend time with family and friends.