In this post, you will learn about the basics of the AWS Web Application Firewall (WAF) and write CDK code to protect a REST API Gateway service. We will enable WAF metrics, add managed rules to the ACL, and enable logging into a Cloudwatch log group.
This is the second of three posts in the WAF series.
In the first post, I provided tips and tricks for using AWS WAF for a production-ready SaaS service.
In the third post, we will review AWS Firewall Manager and how it allows an organization to manage AWS Application Web Firewall ACLs at scale.
Table of Contents
AWS Web Application Firewall (WAF) Introduction
AWS WAF is a web application firewall that lets you monitor or block the HTTP(S) requests forwarded to your protected web application resources. You can protect the following resource types:
Amazon CloudFront distribution
Amazon API Gateway REST API
Application Load Balancer
AWS AppSync GraphQL API
Amazon Cognito user pool
AWS App Runner service
AWS Verified Access instance
As you can see from the list above, AWS WAF can protect both your container-based and Serverless services. I covered the threats that WAF protects you from in the first post in the series.
To understand how WAF provides an extra layer of security, we first need to understand how it works. Let's see how we can configure WAF to protect our SaaS service.
ACL and Rules
To use WAF with your AWS resources (as defined above), create a WAF access control list (ACL), define its rules, and associate the ACL with the resource you wish to protect.
The associated resources forward incoming requests to AWS WAF for inspection by the web ACL. In your web ACL, you create rules to define traffic patterns to look for in requests and to specify the actions to take on matching requests. - AWS
Each rule has action to run when matched. Action choices include the following:
Allow the requests to go to the protected resource for processing and response.
Block the requests.
Count the requests.
Run CAPTCHA or challenge checks against requests to verify human users and standard browser use.
AWS provides managed rules that are out of the box, and I highly suggest you use them as much as possible. These rules, constantly updated by AWS, are easy to use and there's really no reason to reinvent the wheel. However, sometimes, we need to use custom rules.
A rule can have multiple conditions with an 'and,' 'or' or 'not' between them. A condition can use a regex to match HTTP header, rate-based element, block traffic originating from specific countries, or even an IP set (for example, block traffic that doesn't originate from your work VPN IP ranges). WAF also has the option to alter headers (transform) before examining them. You have many custom options; just be aware that the more advanced and custom you go, the more WCU you use (see WCU section).
Another important notion to remember is that rules have priority. WAF examines traffic from the top priority to the bottom, and when a rule matches its conditions, it performs the defined action, whatever it may be.
Logging is also an essential aspect of WAF debugging. In this post, I will cover logging to a CW log group, but there are two other options - I covered them with my recommendations in the first post.
Lastly, you can enable CloudWatch metrics for your WAF rules. I suggest you enable them as they provide valuable insight into whether they make a difference (know what and why you're paying for!). For more information, check the AWS docs.
Now that we have the basics down, let's move on to the CDK code.
Sample Serverless Service Architecture
The 'orders' service allows users to order products. We will use my open-source Serverless template project: AWS Lambda Handler Cookbook.
This repository provides a working, deployable, open-source, serverless service template with an AWS Lambda function and AWS CDK Python code, all the best practices, and a complete CI/CD pipeline. You can start a serverless service in 3 clicks!
Now, let's protect our API Gateway from DDoS and other attacks or disruptions.
Lets add an AWS WAF ACL to the mix and associate it with our API Gateway:
The API Gateway will pass traffic to our AWS WAF ACL for inspection. The ACL will try to match the traffic against its list of rules (ordered by priority) and execute the action of the first rule that matches.
AWS CDK Code
For the API Gateway CDK code click here.
For the complete WAF code click here.
Lets' review the WAF CDK code below. We want to create a new WAF ACL with three AWS managed rules and enable metrics and logging:
In line 10 we get the API Gateway construct we wish to associate with our WAF ACL.
In lines 14-88, we define the WAF ACL, enable CW metrics, and define the ACL list of rules.
Between lines 23 and 88, we define the rules with a priority, statements, and a visibility configuration that includes CloudWatch metrics for comprehensive monitoring and control.
In line 91 we associate our service API Gateway to the ACL.
In lines 94-128, we add the logging configuration. We create the log group, allow WAF to create log streams inside it and enable the logging configurations.
After deployment, we get the AWS managed rules we defined ordered by their priority:
and this logging config:
That's it!
Check WAF's advanced logging features such as filters or redacted fields at the official documentation.