AWS WAF : A primer and walkthrough of your first deployment

2022.06.22

AWS offers a wide range of services, out of which some are specifically built for security of our deployments and saves us from the hassle of setting up a security infrastructure from the developer's end. AWS WAF or Web Application Firewall as the name suggests is a firewall which protects our applications or APIs from web exploits and bots which can be used to launch a DDoS attack on your deployment.

Just like all firewalls, we can imagine WAF like a layer of protection around our deployment, like a city surrounded by protective walls. It does not allow seemingly malicious looking traffic through it, like the guards at the gates of our city will not let anyone who looks to be suspicious, or looks like they have intention to cause harm to the city and its citizens (in this case, the network's traffic). It does so by  monitoring HTTP and HTTPS requests directed towards our CloudFront distribution, ALB or API gateway. You can configure which IPs can make a request, more specifically, it allows you to blacklist malicious IPs for added security since WAF only protects against common exploits and attackers can get quite creative with their approaches we can also configure according to the query string parameters (parameters passed in URL). If the query string doesn't match the format then WAF returns a 403 error code.

It protects against web attacks on the basis of user defined characteristics, which are :

  • Source IP
  • Country of source
  • Values in query string
  • Strings that are part of query string
  • Length of requests

WAF works by detecting activity which imitates users which perform SQLi attacks, XSS (Cross side scripting) and DDoS attacks.

WAF's terminologies

Rule Statements : Conditions for the the inbound traffic to your distribution.

Rules : Allows us to perform certain operations on the conditions. These can be multiple operations with OR/AND/NOT association. There are also rate based rules (number of requests from a source). This blocks malicious actors from using too many resources and increasing the cost of running your distribution. Rules play a very important role, there are 2 ways of adding rules to your distribution. The first one is defining your own rules, the second is to use AWS defined rules. Rules provides a bunch of rules set 

WebACL : All the rules and rule statements fit under the WebACL, additionally you can also assign a default action on the ACL. Which can be one of BLOCK, ALLOW or COUNT. 

Association : The entity to which rules and rule statements belong to. Such as an API Gateway, CloudFront distribution, an ALB.

WAF cannot be associated with EC2 instance directly. It can only be associated with ALB, CloudFront and API Gateway.

Additionally, when you think about it deep enough, you might start wondering how can you test if your WAF works perfectly if you have opted the BLOCK WebACL action. There are multiple options under block, one of them being block by geolocation,  which can be particularly tough to do since it requires us to use a VPN, there are multiple ways to do this without VPN as well and that's something for you to figure out yourself.

Lets launch a WebACL

Prerequisites

Since WAF cannot be associated with EC2 instances alone, I have opted to launch 2 EC2 instances (Amazon Linux 2) which are part of the same security group. I have added theseto a new target group, which is the target of an application load balancer. This is associated with a WebACL.

architecture for the WebACL

Architecture of the sample deployment.

So lets launch the instances first, here is how they look:

EC2 instance dashboard displaying the 2 instances.

And here is the target group they are part of:

Target group for the ALB

After which we launch an ALB:

Application Load Balancer

Now, lets launch the WAF

Once we arrive on the WAF dashboard, here is what we see:

Landing page of the WebACL launch process

As you can see, I have highlighted Add AWS resources this button lets us associate 1 or more AWS resources to our WAF, this way multiple services in a single account can be protected and managed easily. What we see when you click on this button is this:

The association choices

Now lets get to adding rules, WebACL provides up to 1500 credits, each predefined AWS rule costs a certain amount of credits once you add all the rules you would like to add, the total must not cross 1500.

Rules and rule groups

As you can see, the credits consumed by each rule are stated under Capacity. We can even select what action needs to be performed on the requests which don't match the given rules, there are advanced options which lets you customise a response for the requests which do not follow the given rules. We shall explore that avenue later.

Now, when we do add multiple rules we do want to set priorities, to define which rule must be extremely stringent. For which, WAF does let us add a priority value to each rule, the lesser the value, the higher the priority.

Rule priority

We can select a rule and move it up and down the list to place the rules in their order of priority.

And now we can continue to the final step and deploy our WAF, it does take a couple of minutes so let AWS take its time.

Well, in this small time which AWS took, I did start thinking about what can WAF when it comes to logging? Well, don't sweat over it too much, WAF does log and also allows you to export logs to various locations such as an S3 bucket, an AWS Kinesis Firehose stream or to a CloudWatch log group.

Logging and its options

We can log all the queries to your distribution using the logging feature of WAF, this allows us to redact certain fields of our choice from the logs. These logs can be exported to a CloudWatch log group, Kinesis data stream or an S3 bucket.

Now, all of this, but not custom responses? Well, now is the time to get an overview of that. Custom responses let us customise a response for the invalid requests and modify the 403 HTTP code returned by WAF to other error code of our choice. These can be defined in various formats, out of which I have decided to do it in JSON format because of its widespread usage and high readability.

Customising HTTP response code and messages.

With that, we are done with all the basic configuration options present in WAF, and I hope this will let you launch your own WebACL without any hassles. For a deeper understanding on the topic I recommend you do try to do this on your own and play around with its options.

I hope this was a helpful and easy way to understand WAF. Until next time!