Nginx – CNAME to CloudFront: Read actual browser URL server-side

amazon ec2domain-namenginxnode.js

I'm trying to read the actual browser URL server-side (Node.js), but is getting the EC2 instance url.

I have a setup consisting of a Node.js application running on EC2 with a Cloudfront distribution.

My domain, example.com points to the Cloudfront distribution:

Type: CNAME Record
Host: stg (points to a staging server on a subdomain)
Value: xxxxxxxxxxxxxxxx.cloudfront.net

It all works great, just one little snag. My application needs to read the actual url in the browser, but everything in the request object points to the EC2 instance ec2-xx-xx-xxx-xxx.ap-southeast-2.compute.amazonaws.com.

E.g console.log(req.host) // c2-xx-xx-xxx-xxx.ap-southeast-2.compute.amazonaws.com

This is my Nginx setup:

upstream node {
  server 127.0.0.1:3000;
  keepalive 64;
}

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  server_name example.com *.example.com;

  location / {
    proxy_pass $scheme://node$request_uri;
    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Proto-Version $http2;
    proxy_set_header X-Forwarded-Host $host:$server_port;
    proxy_set_header Host $http_host;
    proxy_set_header domain https://stg.example.com; # Temp fix
  }
}

I have hardcoded a header in Nginx proxy_set_header domain https://stg.example.com; which I can read on the application level, however it doesn't seem quite right.

Is there a better way?

Best Answer

Add the Host header to the whitelist of headers to forward to the origin server in the CloudFront cache behavior settings.

By default CloudFront rewrites this header.

Host

Behavior If You Don't Configure CloudFront to Cache Based on Header Values... CloudFront sets the value to the domain name of the origin that is associated with the requested object.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#request-custom-headers-behavior

Adding Host to the whitelist should remedy your issue.

But it will also create new issues depending on how you have configured your origin and how/whether you are using SSL on the backend. If the origin is accessed over SSL then the dzzzexample.cloudfront.net can't be used to access your distribution from the browser's address bar, unless the back-end certificate matches the configured Origin Domain Name. There is a reason for this behavior change, and it is correct behavior on the part of CloudFront, but possibly beyond the scope of this question. See HTTP 502 Status Code Bad Gateway in the CloudFront Developer Guide for a thorough explanation of this condition.

Related Topic