All posts by Lee Atkinson

How to Help Achieve Mobile App Transport Security (ATS) Compliance by Using Amazon CloudFront and AWS Certificate Manager

Post Syndicated from Lee Atkinson original

Web and application users and organizations have expressed a growing desire to conduct most of their HTTP communication securely by using HTTPS. At its 2016 Worldwide Developers Conference, Apple announced that starting in January 2017, apps submitted to its App Store will be required to support App Transport Security (ATS). ATS requires all connections to web services to use HTTPS and TLS version 1.2. In addition, Google has announced that starting in January 2017, new versions of its Chrome web browser will mark HTTP websites as being “not secure.”

In this post, I show how you can generate Secure Sockets Layer (SSL) or Transport Layer Security (TLS) certificates by using AWS Certificate Manager (ACM), apply the certificates to your Amazon CloudFront distributions, and deliver your websites and APIs over HTTPS.


Hypertext Transfer Protocol (HTTP) was proposed originally without the need for security measures such as server authentication and transport encryption. As HTTP evolved from covering simple document retrieval to sophisticated web applications and APIs, security concerns emerged. For example, if someone were able to spoof a website’s DNS name (perhaps by altering the DNS resolver’s configuration), they could direct users to another web server. Users would be unaware of this because the URL displayed by the browser would appear just as the user expected. If someone were able to gain access to network traffic between a client and server, that individual could eavesdrop on HTTP communication and either read or modify the content, without the client or server being aware of such malicious activities.

Hypertext Transfer Protocol Secure (HTTPS) was introduced as a secure version of HTTP. It uses either SSL or TLS protocols to create a secure channel through which HTTP communication can be transported. Using SSL/TLS, servers can be authenticated by using digital certificates. These certificates can be digitally signed by one of the certificate authorities (CA) trusted by the web client. Certificates can mitigate website spoofing and these can be later revoked by the CA, providing additional security. These revoked certificates are published by the authority on a certificate revocation list, or their status is made available via an online certificate status protocol (OCSP) responder. The SSL/TLS “handshake” that initiates the secure channel exchanges encryption keys in order to encrypt the data sent over it.

To avoid warnings from client applications regarding untrusted certificates, a CA that is trusted by the application must sign the certificates. The process of obtaining a certificate from a CA begins with generating a key pair and a certificate signing request. The certificate authority uses various methods in order to verify that the certificate requester is the owner of the domain for which the certificate is requested. Many authorities charge for verification and generation of the certificate.

Use ACM and CloudFront to deliver HTTPS websites and APIs

The process of requesting and paying for certificates, storing and transporting them securely, and repeating the process at renewal time can be a burden for website owners. ACM enables you to easily provision, manage, and deploy SSL/TLS certificates for use with AWS services, including CloudFront. ACM removes the time-consuming manual process of purchasing, uploading, and renewing certificates. With ACM, you can quickly request a certificate, deploy it on your CloudFront distributions, and let ACM handle certificate renewals. In addition to requesting SSL/TLS certificates provided by ACM, you can import certificates that you obtained outside of AWS.

CloudFront is a global content delivery network (CDN) service that accelerates the delivery of your websites, APIs, video content, and other web assets. CloudFront’s proportion of traffic delivered via HTTPS continues to increase as more customers use the secure protocol to deliver their websites and APIs.

CloudFront supports Apple’s ATS requirements for TLS 1.2, Perfect Forward Secrecy, server certificates with 2048-bit Rivest-Shamir-Adleman (RSA) keys, and a choice of ciphers. See more details in Supported Protocols and Ciphers.

The following diagram illustrates an architecture with ACM, a CloudFront distribution and its origins, and how they integrate to provide HTTPS access to end users and applications.

Solution architecture diagram

  1. ACM automates the creation and renewal of SSL/TLS certificates and deploys them to AWS resources such as CloudFront distributions and Elastic Load Balancing load balancers at your instruction.
  2. Users communicate with CloudFront over HTTPS. CloudFront terminates the SSL/TLS connection at the edge location.
  3. You can configure CloudFront to communicate to the origin over HTTP or HTTPS.

CloudFront enables easy HTTPS adoption. It provides a default * wildcard certificate and supports custom certificates, which can be either created by a third-party CA, or created and managed by ACM. ACM automates the process of generating and associating certificates with your CloudFront distribution for the first time and on each renewal. CloudFront supports the Server Name Indication (SNI) TLS extension (enabling efficient use of IP addresses when hosting multiple HTTPS websites) and dedicated-IP SSL/TLS (for older browsers and legacy clients that do no support SNI).

Keeping that background information in mind, I will now show you how you can generate a certificate with ACM and associate it with your CloudFront distribution.

Generate a certificate with ACM and associate it with your CloudFront distribution

In order to help deliver websites and APIs that are compliant with Apple’s ATS requirements, you can generate a certificate in ACM and associate it with your CloudFront distribution.

To generate a certificate with ACM and associate it with your CloudFront distribution:

  1. Go to the ACM console and click Get started.
    ACM "Get started" page
  2. On the next page, type the website’s domain name for your certificate. If applicable, you can enter multiple domains here so that the same certificate can be used for multiple websites. In my case, I type * to create what is known as a wildcard certificate that can be used for any domain ending in (that is a domain I own). Click Review and request.
    Request a certificate page
  3. Click Confirm and request. You must now validate that you own the domain. ACM sends an email with a verification link to the domain registrant, technical contact, and administrative contact registered in the Whois record for the domain. ACM also sends the verification link to email addresses commonly associated with an administrator of a domain: administrator, hostmaster, postmaster, and webmaster. ACM sends the same verification email to all these addresses in the expectation that at least one address is monitored by the domain owner. The link in any of the emails can be used to verify the domain.
    List of email addresses to which the email with verification link will be sent
  4. Until the certificate has been validated, the status of the certificate remains Pending validation. When I went through this approval process for *, I received the verification email shown in the following screenshot. When you receive the verification email, click the link in the email to approve the request.
    Example verification email
  5. After you click I Approve on the landing page, you will then see a page that confirms that you have approved an SSL/TLS certificate for your domain name.
    SSL/TLS certificate confirmation page
  6. Return to the ACM console, and the certificate’s status should become Issued. You may need to refresh the webpage.
    ACM console showing the certificate has been issued
  7. Now that you have created your certificate, go to the CloudFront console and select the distribution with which you want to associate the certificate.
    Screenshot of associating the CloudFront distribution with which to associate the certificate
  8. Click Edit. Scroll down to SSL Certificate and select Custom SSL certificate. From the drop-down list, select the certificate provided by ACM. Select Only Clients that Support Server Name Indication (SNI). You could select All Clients if you want to support older clients that do not support SNI.
    Screenshot of choosing a custom SSL certificate
  9. Save the configuration by clicking Yes, Edit at the bottom of the page.
  10. Now, when you view the website in a browser (Firefox is shown in the following screenshot), you see a green padlock in the address bar, confirming that this page is secured with a certificate trusted by the browser.
    Screenshot showing green padlock in address bar

Configure CloudFront to redirect HTTP requests to HTTPS

We encourage you to use HTTPS to help make your websites and APIs more secure. Therefore, we recommend that you configure CloudFront to redirect HTTP requests to HTTPS.

To configure CloudFront to redirect HTTP requests to HTTPS:

  1. Go to the CloudFront console, select the distribution again, and then click Cache Behavior.
    Screenshot showing Cache Behavior button
  2. In my case, I only have one behavior in my distribution. (If I had more behaviors, I would repeat the process for each behavior that I wanted to have HTTP-to-HTTPS redirection) and click Edit.
  3. Next to Viewer Protocol Policy, choose Redirect HTTP to HTTPS, and click Yes, Edit at the bottom of the page.
    Screenshot of choosing Redirect HTTP to HTTPS

I could also consider employing an HTTP Strict Transport Security (HSTS) policy on my website. In this case, I would add a Strict-Transport-Security response header at my origin to instruct browsers and other applications to make only HTTPS requests to my website for a period of time specified in the header’s value. This ensures that if a user submits a URL to my website specifying only HTTP, the browser will make an HTTPS request anyway. This is also useful for websites that link to my website using HTTP URLs.


CloudFront and ACM enable more secure communication between your users and your websites. CloudFront allows you to adopt HTTPS for your websites and APIs. ACM provides a simple way to request, manage, and renew your SSL/TLS certificates, and deploy those to AWS services such as CloudFront. Mobile application developers and API providers can more easily meet Apple’s ATS requirements now using CloudFront, in time for the January 2017 deadline.

If you have comments about this post, submit them in the “Comments” section below. If you have implementation questions, please start a new thread on the CloudFront forum.

– Lee

How to Import IP Address Reputation Lists to Automatically Update AWS WAF IP Blacklists

Post Syndicated from Lee Atkinson original

You can use AWS WAF (a web application firewall) to help protect your web applications from exploits that originate from groups of IP addresses that are known to be operated by bad actors such as spammers, malware distributors, and botnets. The IP addresses used may change over time as these bad actors attempt to avoid detection. In this post, I will show how to synchronize AWS WAF Rules with reputation lists.

A number of organizations maintain reputation lists of IP addresses used by bad actors. Their goal is to help legitimate companies block access from specific IP addresses and protect their web applications from abuse. These downloadable, plaintext reputation lists include Spamhaus’s Don’t Route Or Peer (DROP) List and Extended Drop (EDROP) List, and Proofpoint’s Emerging Threats IP list. Similarly, the Tor project’s Tor exit node list provides a list of IP addresses currently used by Tor users to access the Internet. Tor is a web proxy that anonymizes web requests and is sometimes used by malicious users to probe or exploit websites.

Solution overview

The described solution uses AWS Lambda to synchronize AWS WAF Rules with available reputation lists. Lambda automates the parsing of text-based IP reputation lists, the extracting of IP addresses contained within those lists, and updating the AWS WAF IP Sets in order to create a blacklist that blocks those addresses. Amazon CloudWatch Events executes the Lambda function on a regular schedule. To simplify the deployment, I will show you how to deploy this solution by using AWS CloudFormation.

The following diagram illustrates the process covered in this post.   

Here is how the process works:

  1. Amazon CloudWatch Events execute the Lambda function on a scheduled basis.
  2. The function downloads third-party reputation lists and processes them.
  3. To create a blacklist, the function then updates AWS WAF IP Sets with the latest IP addresses and ranges defined in the reputation lists.
  4. AWS WAF then denies requests from the IP addresses that appear in the blacklist.

In addition to the reputation lists mentioned previously, you might want to include other lists maintained by a third party or by your organization. This post’s example Lambda function, written in Node.js JavaScript, supports the downloading of multiple lists and updating AWS WAF in a single Lambda execution. The Lambda function supports text-based lists with a single IP address or range specified per line. The function uses regular expressions to extract the IP address in either a.b.c.d dotted-decimal notation or a.b.c.d/n Classless Inter-Domain Routing (CIDR) notation, and supports an optional regular expression to match text that is present in the line before the address range. The function also consolidates ranges duplicated across multiple reputation lists and ranges that are contained within larger ranges. As an example, suppose we have two address ranges, and The second range is contained within the first, and therefore is not required in the combined list.

AWS WAF lets you apply a web access control list (web ACL) to a CloudFront distribution. A web ACL gives you fine-grained control over the web requests that your AWS resources respond to, and it can contain up to 10 rules. Each rule can specify multiple conditions that are logically ANDed to get a match in order to either Allow, Deny, or Count the incoming request. One of the conditions these rules can refer to is an AWS WAF IP Set. An IP Set defines up to 1,000 IP descriptors, which define the IP addresses and ranges in CIDR notation. Therefore, a single AWS WAF web ACL can block up to 10,000 IP address ranges in total.

AWS WAF supports IP addresses and ranges in the CIDR format a.b.c.d/n where n, the mask, must be on the octet boundaries of 8, 16, 24, or 32. Some of the reputation lists may include address ranges that have masks other than the ones supported by AWS WAF. For those address ranges, the Lambda function will “split” the range into multiple, smaller ranges that have one of the supported masks. For example, suppose we have a range defined, which specifies a range with two IP addresses. AWS WAF does not support a network mask of 31, so the function will split into two ranges, each specifying a single address, and, covering the range of

The example Lambda function shards your reputation lists across multiple AWS WAF IP Sets that are made available to it, and prioritizes the list of IP addresses by size of ranges such that it blocks as many individual IP addresses as possible.

Deploy the solution using AWS CloudFormation

Now that I have explained how the Lambda function will process reputation lists, I will show how to use CloudFormation to create a stack consisting of the AWS WAF web ACL, Rules, and IP Sets, as well as the Lambda function, CloudWatch Events Rule, and supporting resources. The sample CloudFormation template defines two AWS WAF Rules and two IP Sets. You can modify the template to include more Rules and IP Sets in order to support a larger blacklist. The template also defines a CloudWatch Events Rule, which will execute the Lambda function every hour. You can alter the rate to a different value, but please respect the wishes of the reputation lists owners and do not request the lists too often.

First, I go to the CloudFormation console, click Create Stack, and specify one of the URLs for the CloudFormation templates listed at the end of this post.

Click Next and type a name for the stack.

The template defines the parameter ReputationLists that, by default, includes the following JSON parameter value that defines the Spamhaus DROP, Tor exit node list, Emerging Threats IP list, and associated regular expression prefixes. You can edit the JSON parameter value to specify other lists.

     { "url": "" },
     { "url": "","prefix":"ExitAddress "},
     { "url": "" }

I click Next and Next again. On the next page, I select the I acknowledge that this template might cause AWS CloudFormation to create IAM resources check box in order for the stack to create the IAM role assumed by the Lambda function. I click Create to create the stack.

After the CloudFormation stack is created, I select the stack in the CloudFormation console and click the Resources tab.

I make a note of the physical ID for the Lambda function. In my example, it is called WAFReputationLists-LambdaFunction-PM6D5GNW6EDD, but yours may have a different ID. I will use this physical ID later to find the function in the Lambda console.

Monitor using CloudWatch

I then go to the Lambda console and select the Lambda function created by CloudFormation with the name mentioned in the previous paragraph. I click the Monitoring tab, and from here, I can monitor the execution of the function on an hourly basis. Note that it may take an hour for the first scheduled event to execute the function.

On the Monitoring tab, I click View logs in CloudWatch, which takes me to the CloudWatch console. Here, I can view the logs generated by the function using CloudWatch Logs, as shown in the following screenshot.

Attach the AWS WAF web ACL to a CloudFront distribution

To use the blacklist defined in my web ACL to protect my web application, I must attach the web ACL to a CloudFront distribution used to deliver the website via the CloudFront CDN.

I open the CloudFront console and click Distributions. I click my CloudFront distribution’s ID.

I then click Edit. I select the web ACL to attach (I choose the web ACL I created with the stack earlier in this post), scroll to the bottom of the page, and click Yes, Edit to save changes.

Screenshot showing the Edit button

I have attached the appropriate web ACL to the CloudFront distribution, which will allow me to use the blacklist to protect my web application.


In this post, I demonstrated how you can use AWS WAF to block the IP addresses used by bad actors. I did this by creating a Lambda function that imports IP addresses and ranges from multiple third-party IP reputation lists into AWS WAF, and scheduled the import using CloudWatch Events.The function processes the addresses defined in the lists into a format suitable for AWS WAF, removing duplicates and prioritizing the list to include as many IP addresses as possible. Subsequent requests to your web application (delivered by CloudFront) from IP addresses defined in this blacklist will be denied by AWS WAF.

The CloudFormation template and Lambda function package are available in the following S3 buckets that are located in the AWS regions that currently support Lambda:

The code and other WAF samples also are available in our GitHub aws-waf-sample repository.

If you have comments about this blog post, please submit them in the “Comments” section below. If you have questions about this solution or its implementation, please start a new thread on the AWS WAF forum.

– Lee