Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rewrite cloudfront origin host with lambda@edge, how?

I see people talking about how to rewrite a URI based on various information. But I'd like to normalize the domain name that is being requested. Here's what I've tried:

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;

    if (request.method.toUpperCase() != 'GET') {
        callback(null, request);
        return;
    }

    request.origin = {
        custom: {
            domainName: 'slashdot.org',
            port: 443,
            protocol: 'https',
            path: request.uri
        }
    };
    request.headers.host = {
        "key": "Host",
        "value": request.origin.custom.domainName
    };

    console.log("returning req:", request);

    callback(null, request);
}

I was hoping that would pull up the request and that cloudfront would then make a request against my canonicalized domain. (for the example and testing, I'm using slashdot, since it's obvious it isn't my content).

Ultimately, I'm trying to canonicalize a request without doing redirects, but instead rewriting the request before hit hits the origin.

like image 820
tedder42 Avatar asked Jun 21 '18 06:06

tedder42


People also ask

How do I add edge lambda to CloudFront?

In the Designer section of the page, choose CloudFront, as shown in the following image. Scroll down to the Configure triggers section of the page, then choose Deploy to Lambda@Edge. On the Deploy to Lambda@Edge page, under Configure CloudFront trigger, enter the following information: Distribution.

How does Lambda edge work with CloudFront?

Lambda@Edge lets you run Node. js and Python Lambda functions to customize content that CloudFront delivers, executing the functions in AWS locations closer to the viewer. The functions run in response to CloudFront events, without provisioning or managing servers.

Can Lambda be CloudFront origin?

The CloudFormation template creates a CloudFront distribution with the Lambda Function as origin. The origin points to the Lambda Function URL endpoint and is associated with a default cache behavior to serve all requests.

How do I change origin CloudFront?

To update a CloudFront distribution To edit settings for a distribution, choose the Distribution Settings tab. To update general settings, choose Edit. Otherwise, choose the tab for the settings that you want to update: Origins or Behaviors. Make the updates, and then, to save your changes, choose Yes, Edit.


1 Answers

Oh, neat. I finally figured out how to do this. First, some restrictions:

  • With https this only works for domains under your certificate. So I can't use mydomain.com and slashdot.org unless I'm CmdrTaco. That's fine, my AWS ACM cert includes three domains, one of which is my actual domain. I'll call that actualdomain.com below.
  • This cannot be done on the viewer request, only the origin request, as host is read-only for the viewer request.

Given that, I used "Example: Using an Origin-Request Trigger to Change From an Amazon S3 Origin to a Custom Origin" with some minor modifications. Here's the full Lambda code.

'use strict';

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const destDomain = 'actualdomain.com';


    /* Set custom origin fields*/
    request.origin = {
        custom: {
            domainName: destDomain,
            port: 443,
            protocol: 'https',
            path: '',
            sslProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2'],
            readTimeout: 5,
            keepaliveTimeout: 5,
            customHeaders: {}
        }
    };
    request.headers['host'] = [{ key: 'host', value: destDomain}];

    callback(null, request);
};

So, similar to the example given in the docs, destDomain is the actual domain, and any legitimate domain in my certificate is proxied to that dest, without the end user actually seeing actualdomain.com.

like image 70
tedder42 Avatar answered Oct 19 '22 16:10

tedder42