DEV Community

Rajesh Murali Nair
Rajesh Murali Nair

Posted on

Mastering Custom Responses in Amazon CloudFront to Block Behavior — Default(*)

Introduction

When deploying an e-commerce application on Amazon Web Services (AWS), ensuring robust security measures is paramount. However, traditional setups with Amazon CloudFront might present challenges, especially when attempting to disable default behaviors for specific paths. In this blog post, we’ll explore how Lambda@Edge, coupled with CloudFront’s Origin Request events, can be leveraged to create custom responses and enhance security for e-commerce applications

Challenges with Default Behaviors in CloudFront

In many cases, e-commerce applications require tailored responses for certain paths, such as restricting access to sensitive areas or redirecting users to specific pages. However, CloudFront’s default behaviors (*) lack the option to disable them, necessitating alternative solutions for custom responses.

Introducing Lambda@Edge for Custom Responses:

Lambda@Edge offers a powerful solution to this challenge by enabling the execution of custom code at CloudFront’s edge locations. By leveraging CloudFront’s Origin Request events, we can intercept incoming requests before they reach the origin server, such as an S3 bucket or an EC2 instance. This interception point provides the perfect opportunity to generate custom responses based on specific criteria.

When you associate a CloudFront distribution with a Lambda@Edge function, CloudFront intercepts requests and responses at CloudFront edge locations. You can execute Lambda functions when the following CloudFront events occur:

  • When CloudFront receives a request from a viewer (viewer request)
  • Before CloudFront forwards a request to the origin (origin request)
  • When CloudFront receives a response from the origin (origin response)
  • Before CloudFront returns the response to the viewer (viewer response)

In this blog, we will be using CloudFront event origin request to provide a custom response generated from Lambda@Edge function.

Prerequisites

  • S3 bucket
  • CloudFront Distribution

Implementation Steps

  1. Create a Lambda Function as per the below screenshot with the name Block_CF_Default_Behavior_Access

Image description

Image description

Note : Lambda function needs to be created in us-east-1 region

  1. Create an IAM policy CF_Lambda_Edge_Policy with below permission
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "cloudfront:GetDistribution",
                "iam:CreateServiceLinkedRole",
                "lambda:GetFunction",
                "cloudfront:UpdateDistribution",
                "cloudfront:CreateDistribution",
                "lambda:EnableReplication*",
                "lambda:DisableReplication*"
            ],
            "Resource": [
                "arn:aws:cloudfront::853602029602:distribution/*",
                "arn:aws:lambda:us-east-1:853602029602:function:*",
                "arn:aws:iam::853602029602:role/*"
            ]
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Navigate to IAM → Roles → select Block_CF_Default_Behavior_Access_Role → Click on Add permission button on the right hand corner and select Attach policies

Image description

Select IAM policy CF_Lambda_Edge_Policy created above and click Add permissions

Image description

Image description

  1. Modify the Lambda function with the below code

  2. Open the Functions page of the Lambda console.

  3. Choose Block_CF_Default_Behavior_Access function and then choose Code tab. In the console’s built-in code editor, you should see the function code that Lambda created.

  4. Paste the below code into the _lambda_function.py _tab, replacing the code that Lambda created.

  5. Select Deploy to update your function’s code. When Lambda has deployed the changes, the console displays a banner letting you know that it’s successfully updated your function.

import json

def lambda_handler(event, context):
    ### Fetch Cloudfront Domain Name
    cf_domain_name = event['Records'][0]['cf']['config']['distributionDomainName']
    ### Fetch Cloudfront URI (/test1/jpeg)
    cf_uri = event['Records'][0]['cf']['request']['uri']
    ### Combining Domain Name and URI to form an URL
    cf_url = cf_domain_name+cf_uri
    ### Custom response 
    response = {
      'status': '200',
      'statusDescription': 'OK',
      'headers': {
          'Content-Type': [
            {
              'key': 'Content-Type',
              'value': 'application/json'
            }
          ]
      },
      'body': "Access to the URL " + cf_url + " not allowed"
    }
    return response
Enter fullscreen mode Exit fullscreen mode

Image description
Image description

  1. Publish a new version for Lambda@Edge

  2. Open the Functions page of the Lambda console.

  3. Choose Block_CF_Default_Behavior_Access function and then choose Versions tab

  4. On the versions configuration page, choose Publish new version.

  5. (Optional) Enter a version description.

  6. Choose Publish.

Image description

Image description

  1. Add a CloudFront trigger to run the function
  • In the Lambda console, on the Function overview page for your function, choose Add trigger
  • For Trigger configuration, choose CloudFront.
  • Choose Deploy to Lambda@Edge.
  • In the Deploy to Lambda@Edge pane, under Configure CloudFront trigger select the following information:
    1. Distribution
    2. Cache Behavior — ‘*’
    3. CloudFront event — ‘Origin Request’
  • Select the Confirm deploy to Lambda@Edge check box
  • Choose Deploy to add the trigger and replicate the function to AWS locations worldwide.

Image description

Note: The function executes only when CloudFront forwards a request to your origin. When the requested object is in the CloudFront cache, the function doesn’t execute

  1. Add a trigger by using the CloudFront console
  • Get the ARN of the Lambda function that was created above.
  • Open the CloudFront console
  • In the list of distributions, choose the ID of the distribution that you want to add triggers to.
  • Choose the Behaviors tab
  • Select the Default (*) cache behavior to add triggers to, and then choose Edit.
  • For Function associations, in the Function type list, choose Lambda@Edge for origin responses.
  • In the Function ARN / Name text box, paste the ARN of the Lambda function which should include the version at the end.
  • Choose Save changes

Testing the Custom Response for CloudFront Default Behaviour

To test the custom response functionality in CloudFront, you can follow these steps to access a CloudFront URL:

  1. Upload an Image to the S3 Bucket:

First, upload an image to the root of the S3 bucket or to a prefix that wasn’t explicitly defined in the CloudFront behavior. This step ensures that the image won’t be served through CloudFront’s default behavior, allowing us to trigger the custom response logic.
2.** Access the Image Using CloudFront URL:**

Once the image is uploaded, obtain the CloudFront URL associated with the image. This URL is typically in the format of https://[CloudFront_Distribution_ID].cloudfront.net/[image_name.jpg].

  1. Testing the Custom Response:

Use a web browser or any HTTP client to access the image via the CloudFront URL. This action will trigger a request to CloudFront, which will then invoke the custom response logic implemented using Lambda@Edge.

  1. Observing the Response:

After accessing the image through the CloudFront URL, observe the response returned by CloudFront. If the custom response logic is correctly configured, CloudFront will execute the Lambda@Edge function associated with the Origin Request event and return the customized response specified in the Lambda function.

  1. Verification and Troubleshooting:

Verify that the custom response behaves as expected. This may involve checking for redirections, error messages, or any other customized behavior defined in the Lambda@Edge function. If the response doesn’t match the expected behavior, review the Lambda function code and CloudFront configuration for any potential issues.

  1. Adjustments and Iteration:

If necessary, make adjustments to the Lambda@Edge function or CloudFront configuration based on the observed behavior. Iterate on the testing process until the desired custom response is consistently returned for requests made through the CloudFront URL.

By following these steps, you can effectively test the custom response functionality in CloudFront and ensure that it behaves as intended when accessing resources via CloudFront URLs.

Top comments (0)