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.
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.
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.
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
Set Enable Geo-Restriction to Yes
Select the Restriction Type you want
Add countries to list and finally click on Yes, Edit to save
Once you save, you will see Geo Restriction’s status become Enabled and the type of restriction will also be shown.
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):
- Number of requests
- Data transfer through your distribution (in / out)
- Error rate (as a percentage of total request)
and the following additional monitoring points you can turn on, but with additional cost:
- 4xx and 5xx error rates by type
- Origin latency
- Cache hit rate
For more details of what each monitoring point is about, please refer to the official AWS documentation:
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
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.
On Step 1, click on Select metric
In the popup window, click on CloudFront
Click on Pre-Distribution Metrics to show default metric data
Expand the window a bit then select Requests and click on Select metric
Back to the Create alarm page, make sure you have selected the correct metric
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).
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.
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.
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.
On Step 4, review all settings and click on Create alarm when you are all set
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.
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.
What we will accomplished in this section
From the menu on the top left corner select Services and search for WAF.
From the panel on the left, click on IP sets, select Global and click on Create IP set
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
Select Global for Region, add IP you want to add to this IP sets then click on Create IP set
You will see the list of IP sets you created on the IP set page.
From the panel on the left, click on Web ACLs
Similarly to IP sets, you should choose Global as your region
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
Click on Add AWS resources
Select your CloudFront distribution you want to associate with this WAF and click on Add
Confirm the CloudFront distribution is correct then click Next
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
Select IP set and type in a name for your rule.
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.
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
Set the following fields:
Rule type: Rule builder
Rate limit: 300
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.
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.)
On Step 3, Rules are prioritized in the order they appear. We can leave it the order we added.
Click Next when you are satisfied with the order.
On Step 4, leave everything as default then click Next
On Step 5, review your settings. If everything looks correct then click Create web ACL.
You will be able to see your newly created WAF from the WAF page.
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.
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.