Introduction

In the previous tutorial Set up custom domain with HTTPS and add global cache we added a CDN layer before our S3 Bucket to prevent users from directly accessing our files on S3 Bucket. While AWS CloudFront already provides protections against anomaly attacks, there are still a few configurations we can and should turn on to keep our website secure. We will go over three levels of protections in this tutorial and discuss how to choose the one that fits your needs the most.

Entry level – Geo Restriction

Recall that during the CloudFront creation, we have chosen the region we want to distribute our CDN cache. Typically you will choose the region that is closest to your audiences. However, this does not mean visitors from other regions cannot access your site. It simply means their connection speed will be slower because they need to download contents from a cache server that is physically further from their location.

If you are running a local business and expect your audiences will only come from the country that you’re in. Then it makes no sense to allow visitors from all over the world because these visitors will not only produce additional cost on your server, but more importantly take over the network bandwidth you reserve for your potential customers. If that is the case then this approach is good for you.

CloudFront has a restriction policy you can turn on to solve this scenario – Geo Restriction. Geo Restriction has two modes you can choose from: blacklist or whitelist.

Blacklist restriction:
You can choose which countries your visitors CANNOT access your website from. In short, your website is open to all countries except those that are listed in your blacklist.

Whitelist restriction:
You can choose which countries your visitors CAN access your website from. In short, only countries that are included in your whitelist can access your website, all other countries are not allowed.

It is recommended to go with the whitelist approach because with this approach you are aware of where your visitors are from and hence easier to manage.

To turn on the Geo Restriction on AWS CloudFront, login to the AWS console and navigate to the CloudFront dashboard.

CloudFront console
CloudFront console

Click on the ID of the distribution you want to modify to enter the setting page. Go to the Restrictions tab, select Geo Restriction and click on Edit

Turn on Geo Restriction on CloudFront
Turn on Geo Restriction on CloudFront

Set Enable Geo-Restriction to Yes
Select the Restriction Type you want
Add countries to list and finally click on Yes, Edit to save

Edit Geo Restrictions
Edit Geo Restrictions

Once you save, you will see Geo Restriction’s status become Enabled and the type of restriction will also be shown.

Geo Restriction Enabled
Geo Restriction Enabled

Intermedium level – Monitor requests sent to CloudFront

If your business use case is a bit more complex, and Geo Restriction cannot fully fulfill your needs, then you can set up monitoring points to monitor how users interact with your CloudFront. At the same time send a real time notification via SMS or email when there are suspicious activities or when something goes wrong.

High level perspective of this approach:
Set up monitoring point to track a specific event -> Send notification when incident occurs

CloudFront provides the following monitoring points for free (or referred to as metric data by AWS):

  1. Number of requests
  2. Data transfer through your distribution (in / out)
  3. Error rate (as a percentage of total request)

and the following additional monitoring points you can turn on, but with additional cost:

  1. 4xx and 5xx error rates by type
  2. Origin latency
  3. Cache hit rate

For more details of what each monitoring point is about, please refer to the official AWS documentation:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/viewing-cloudfront-metrics.html

Since this tutorial is about protecting against anomaly attacks, we will use the Number of requests monitoring point.

From the menu on the top left corner, select Services and search for CloudWatch

Search for CloudWatch
Search for CloudWatch
CloudWatch dashboard
CloudWatch dashboard

Note. Recall that CloudFront is not region specific, make sure you choose N. Virginia as your region in order to see metric data of CloudFront on CloudWatch.

From the panel on the left, click on Alarm to enter the alarm setting page.

CloudWatch Alarm page
CloudWatch Alarm page

On Step 1, click on Select metric

Alarm creation - Step 1 specify metric and conditions
Alarm creation – Step 1 specify metric and conditions

In the popup window, click on CloudFront

Select metric data of CloudFront
Select metric data of CloudFront

Click on Pre-Distribution Metrics to show default metric data

Select CloudFront default metric data
Select CloudFront default metric data

Expand the window a bit then select Requests and click on Select metric

Select metric data - Requests
Select metric data – Requests

Back to the Create alarm page, make sure you have selected the correct metric

Metric data selected
Metric data selected

Approach 1 – Anomaly detection
Select Anomaly detection for Threshold type, select Greater than the band and set standard deviation number (the higher the number – the harder it is to trigger the alarm; the lower the number – the easier it is to trigger the alarm. default is 2).

Select Anomaly detection
Select Anomaly detection

Note. The Anomaly detection here provided AWS will build models based on the number of requests your website normally has. So if your application does not have any traffic data prior to this, this approach is probably not a good approach for you. If that’s the case use the second approach instead.

Approach 2 – static threshold
Select Static for Threshold type and set whenever the request is Greater than the threshold and set a threshold.

Set static threshold
Set static threshold

Click Next when you are ready to move on the next step

On Step 2, select In alarm and choose your SNS topic or create a new one if you didn’t have any SNS topic before.

Select alarm action
Select alarm action
Select SNS topic
Select SNS topic

Here we can tell AWS how we want to be notified when an incident occurs. We do so by creating/selecting a SNS (Simple Notification Service) topic. The idea of SNS is that you define a notification group called topic and add people you want to notify into this group (referred to as subscribers). They can be added via telephone number (for SMS message) or via email.

Note. You can add/remove people from a topic at any time on the SNS console.

On step 3, specify the Alarm name and Alarm description then click on Next. This will be the message that will be sent to alarm subscribers in SMS or email.

Add alarm notification message detail
Add alarm notification message detail

On Step 4, review all settings and click on Create alarm when you are all set

Review alarm settings - 1
Review alarm settings – 1
Review alarm settings - 2
Review alarm settings – 1

Please note that an email recipient must first validate their email address by clicking on the link that AWS sent to their email addresses before they can start receiving notification. If none of the subscribers in the SNS topic has validated their email, the alarm will stay in the Insufficient state.

Alarm created
Alarm created

After you validate your email, the alarm will move to OK state and you will receive an email the next time suspicious activities are happening on your website.

Advanced level – Add firewall protection

In the Intermedium level approach, we’ve learned how to set up monitoring points to detect anomaly attacks and send out notifications when incidents occur. However, if you want to block hackers or bots that are attacking your website based on IP, you will need to add a firewall protection layer before your CloudFront. AWS provides a service called Web Application Firewall (WAF) that allows us to monitor incoming requests from the network level.

Original infrastructure
Original infrastructure

What we will accomplished in this section

Infrastructure with firewall protection
Infrastructure with firewall protection

From the menu on the top left corner select Services and search for WAF.

Search for WAF
Search for WAF
WAF dashboard
WAF dashboard

From the panel on the left, click on IP sets, select Global and click on Create IP set

IP set page
IP set page

Note. Since we need to integrate WAF to our CloudFront later, be sure to choose Global.

Enter a name for this IP set name and a Description

Fill in IP set name and description
Fill in IP set name and description

Select Global for Region, add IP you want to add to this IP sets then click on Create IP set

Add IPs to IP set
Add IPs to IP set

You will see the list of IP sets you created on the IP set page.

IP set created
IP set created

From the panel on the left, click on Web ACLs
Similarly to IP sets, you should choose Global as your region

Web ACL page
Web ACL page

On Step 1, fill in the following information
Name: the name you want to set for this WAF
Description: Any description to help you understand easier what this WAF is about
CloudWatch metric name: The metric name of this WAF
Resource type: Resource that the WAF will be applied on.
Choose CloudFront distributions

ACL creation step 1 - Fill in ACL details
ACL creation step 1 – Fill in ACL details

Click on Add AWS resources

ACL creation step 1 - Select AWS resources
ACL creation step 1 – Select AWS resources

Select your CloudFront distribution you want to associate with this WAF and click on Add

Select CloudFront distribution
Select CloudFront distribution

Confirm the CloudFront distribution is correct then click Next

Confirm selected CloudFront distribution
Confirm selected CloudFront distribution

On Step 2, we need to add rules by selecting the IP set we created.

From the Add rules dropdown menu, select Add my own rules and rule groups

Add custom rules
Add custom rules

Select IP set and type in a name for your rule.

Select IP set
Select IP set

From the IP set dropdown menu, select the IP set that you created, mark Source IP addresses, and select Block for Action. Then click on Add rule to return to Step 2.

Select action of this IP set
Select action of this IP set

The first rule we added allows us to add suspicious IPs to the IP set we created. Now let’s add a second rule that will detect anomaly IP automatically.

From the Add rule dropdown menu select Add my own rules and rule groups

Add additional rule
Add additional rule

Set the following fields:
Rule type: Rule builder
Name: rate-based-rule
Type: Rate-based-rule
Rate limit: 300

Select  rule builder
Select rule builder

IP address to use for rate limiting: Source IP addresses
Select consider all requests and select Block for action. Then click Add rule when you are ready.

Select rate-based-rule
Select rate-based-rule

The rate-based-rule we just added will automatically block incoming requests if the requests are made by an IP address that makes more than 300 requests in 5 minutes. The IP will be unblocked when the number of requests falls below the threshold.

For Default action, choose Allow then click on Next. (Since we are blocking IPs that match our rule, we should allow IPs that fall outside of our rule.)

Select default action
Select default action

On Step 3, Rules are prioritized in the order they appear. We can leave it the order we added.

Set rule priorities
Set rule priorities

Click Next when you are satisfied with the order.

On Step 4, leave everything as default then click Next

Step 4
Step 4

On Step 5, review your settings. If everything looks correct then click Create web ACL.

Step 5 - Review
Step 5 – Review
Step 5 - Create web ACL
Step 5 – Create web ACL

You will be able to see your newly created WAF from the WAF page.

WAF created
WAF created

Navigate back to the CloudFront console and select your distribution. You should see your WAF rule is already applied to your CloudFront distribution. If not, click Edit and select the WAF manually.

Confirm WAF setting on CloudFront
Confirm WAF setting on CloudFront
Monitor incoming requests in WAF console
Monitor incoming requests in WAF console

Summary

In this tutorial we have covered three different levels of protections that you can add to your AWS CloudFront. While they are independent of each other, you may also apply all three of them for the maximum security.

In our current setup (if you have been following from the first tutorial), when there are any code changes and we need to update the site, we will need to manually upload the new compiled code to S3 Bucket and request for cache invalidation from the CloudFront console. In the next tutorial, we will finish the series by adding a CICD (continuous integration & continuous delivery) pipeline to automate the website update process.