Networking & Content Delivery

How to boost the performance and security of your dynamic websites with AWS edge services in a few steps

Customers use AWS edge services to improve the performance and the security of their websites. In certain cases, they appreciate being able to quickly set up a Content Delivery Network (CDN) and a Web Application Firewall (WAF) to stop a DDoS attack targeting their website, or to decrease page load times. And they prefer doing this without investing time beforehand to read the service documentation and configure everything from scratch.

If this resonates with you, then you should benefit from reading this post. In this post, you deploy just a few clicks, using an AWS CloudFormation template, an Amazon CloudFront distribution as a reverse proxy to your origin servers, protected by an AWS WAF WebACL. CloudFormation is a service that takes care of provisioning and configuring resources described in a YAML configuration template. CloudFront helps you accelerate your website thanks to caching when it applies, advanced internet protocols (e.g., HTTP3, TL1.3), and the AWS Global network. CloudFront natively protects your application against infrastructure DDoS attacks, and it integrates with AWS WAF to allow you to write rules for managing threats at application layer.

Architecture of a web application with CloudFront and AWS WAF

Figure 1: Architecture of a web application with CloudFront and AWS WAF

The provided solution is scoped to dynamic websites, such as Server Side Rendered frontends, which is served from origin servers, such as an Elastic Load Balancer (ELB), or servers that are on-premises. It helps you get started quickly with CloudFront and AWS WAF to protect and accelerate your dynamic website within minutes. After you get started, you can spend more time understanding the full capabilities of both services to further customize and improve the configuration for your application specific needs.

Deploy CloudFront and AWS WAF for your website in a few minutes

To implement the CloudFront based reverse proxy in front of your website, complete the following steps. We walk you through the deployment steps using www.example.com domain as an example, serving a website using an Application Load Balancer (ALB).

Step 1 – Create new secret domain for the origin servers

Make your website available on a new and secret domain name. This domain name is only used by CloudFront to proxy requests to your origin servers over HTTPS. This prevents malicious actors from bypassing CloudFront and sending traffic directly to your servers. For our www.example.com website, we make the ALB available over a new secret domain name (my-hidden-origin-x4Fsnfk3ad.example.com). To do that, we add another HTTPS (port443) listener to the ALB, using a new TLS certificate covering the new secret domain.

Step 2 – Deploy CloudFront and AWS WAF using CloudFormation

Download this CloudFormation template and then deploy it using CloudFormation in North Virginia region (us-east-1). Note that when you associated an AWS WAF WebACL to a CloudFront distribution, the WebACL resource must be created in the us-east-1 Region, which makes it mandatory to deploy the CloudFormation template in this AWS Region. Fill the required parameters based on your application. To enable CloudFront to serve requests using your own domain name, you must create a TLS certificate using AWS Certificate Manager (ACM) in us-east-1, and attach it to the CloudFront distribution.

  • If you are using Amazon Route 53 as the authoritative DNS server for your application domain name, then enter the corresponding Route 53 Hosted Zone ID. Then CloudFormation automatically generates a new TLS certificate and attaches it to the CloudFront distribution. The hosted zone should be in the same AWS account where you are deploying the CloudFormation template.
  • Otherwise, create a TLS certificate for your application domain name using ACM in us-east-1, and enter its resource identifier (ARN) in the template parameters.

Finally, wait for the deployment to complete in a few minutes, and note the generated CloudFront distribution domain name (e.g., ds3ds9xoad.cloudfront.net) as well as the shared secret header value (e.g., dc214070-2960-11ee-a2cc-0ed426a1090d) in the output of the CloudFormation template. You use these values in the following steps.

Example of parameters entered in the CloudFormation template

Figure 2: Example of parameters entered in the CloudFormation template

Step 3 – Test

Test your web application using the generated CloudFront distribution domain name, and make sure it works seamlessly. For example, you can navigate to your website pages and make sure that all application functionalities are working, or verify the output of your automated tests (e.g., unit tests, integration, visual regression). At this stage, we typically look for content that shouldn’t have been cached, legitimate request patterns blocked by AWS WAF, or unexpected origin behavior with CloudFront as a reverse proxy.

Step 4 – Shift traffic to CloudFront

After conducting successful tests in the previous step, start shifting your traffic through CloudFront. To do this, change the DNS record of your application domain name to point to the generated CloudFront distribution domain name instead of pointing to your origin servers directly. If you are using Route 53, then you can use an alias record. Otherwise, you must use a CNAME record. It’s recommended to create this record with a short DNS TTL (60 seconds) to quickly roll back traffic to your origin servers in case anything goes wrong. Note that the traffic might take some time to complete the transition to CloudFront, depending on the previously configured DNS TTL.

Step 5 – Secure with Origin Cloaking

When traffic is fully shifted to CloudFront, make sure that your origin is receiving the X-Shared-Secret header from CloudFront. Then, configure it to drop any request not including this header with the secret value received in the output of CloudFormation (e.g., using ALB rules). Remove from your origin any unused HTTPS listeners, and for a better security, block any IP packet not coming from CloudFront IPs. VPC-based origins, like ALBs, can simply implement this origin cloaking technique using CloudFront Managed Prefix list in the Security Group configuration.

Now you can enjoy increased performance and security with your web application!

Understand the deployed resources

Let’s dive into what CloudFormation has deployed using the provided template. It deployed a TLS certificate using ACM if this option was selected, a CloudFront distribution, and an AWS WAF WebACL attached to it. The CloudFront distribution is configured in the following way:

    • Requests to files with the jpg, jpeg, png, ico, gif, bmp, webp, svg, tiff, woff, woff2, mp3, mp4, mov, aif, wav, zip, pdf, doc, js, css, and txt file extensions are cached by default for a duration up to one day, unless the origin specifically returns a Cache-Control header specifying otherwise.
    • In addition, requests to text-based files with the js, css, and txt extensions are automatically compressed using GZIP or Brotli according to the capabilities of the user agent.
    • All other requests are proxied to the origin servers without any caching, including the original request query parameters, and headers, except for the Host header that is rewritten to the origin domain name.
    • Responses to all requests include the following security headers: Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, and Referrer-Policy.

The WAF WebACL is configured with the following rules:

  • Two AWS managed rule groups (Common Rule Set and Known Bad Inputs) for a security baseline inspired by OWASP Top 10.
  • A rate limiting rule that blocks any IP with a request rate exceeding 10K requests in the last five minutes.
  • A rate limiting rule that blocks all requests coming from suspicious IPs identified by AWS, if the total request rate from these IPs exceeds 500 requests in the last five minutes.

Estimate the cost of serving your website

The cost of this acceleration and protection layer depends on your application and how much traffic it receives. Let’s do a simple calculation based on our example website. Suppose that this website is receiving 2 million page views per month, with an average page weight of 1.4Mb, including 40 HTTPS same-domain requests (e.g., for images, and css and js files). Most of the traffic is coming from North America and Europe.

First, there is a monthly fixed fee of 11.5$ that includes the cost of AWS WAF WebACL, rules in the WebACL, and the emitted metrics for each rule. Then, there is a variable monthly fee proportional to the received traffic. Both CloudFront and AWS WAF have a charge for every processed HTTP request, and additionally, CloudFront charges for the egressed bytes. These fees depend on the originating AWS Regions of users. For more details, read here about the pricing of CloudFront and AWS WAF.

In the case of our example website, the total cost of serving is as follows:

  • 250 thousand page views per month is 17.5$. At this level of traffic, you are only paying for AWS WAF, since all of the traffic is counted within the CloudFront always free tier.
  • 2 million page views per month is 281$. At this level of traffic, it’s recommended to consider a CoudFront security saving bundle, allowing you to reduce this cost to 193$ per month in exchange of a usage commitment.
  • For over 7.5 million page views per month, consider discussing with AWS teams about a private pricing with higher discounts in exchange of a usage commitment.

Cleaning up resources

If you do not need the deployed resources anymore, remove them to avoid incurring future charges. To do so, delete the deployed stack in CloudFormation, in the us-east-1 Region.

Conclusion

In this post, you learned how to quickly add Amazon CloudFront and AWS WAF to your dynamic website’s technology stack to gain in security and performance. This is only the starting point in your journey to use AWS edge services in an optimal and customized way for your specific application needs. We recommend the following next actions:

    • Customize the caching configuration of your deployed CloudFront distribution. For example, you can add granular caching for some of the dynamic content (e.g., some HTML pages can be cached across users for a couple of seconds). Read this post to understand the basics of configuring CloudFront and AWS WAF.
    • Customize the deployed rules in your AWS WAF WebACL. For example, update the thresholds of the rate limit rules, and add additional ones. Consider adding other advanced rules such as CAPTCHA or JavaScript challenge scoped to your most sensitive pages.
    • Subscribe to Shield Advanced to benefit from Automatic Application Layer DDoS Mitigation feature.
    • Enable logging of access logs in AWS WAF, and learn how to build a security dashboard, as well as detect false positives.

Get in touch with us, and share your feedback on the template page on Github.

Achraf Souk

Achraf Souk

Achraf Souk is leading the Edge Specialist Solutions Architects team in EMEA. This team helps companies and developers to secure and accelerate their web applications using AWS Edge Services.