Home > Net >  How to have an AWS ELB forward the actual host name to the target group instead of the ELB's ho
How to have an AWS ELB forward the actual host name to the target group instead of the ELB's ho

Time:10-05

We have a Ruby/Rails website we're migrating from Heroku to AWS. The original dev is not available. I'm now trying to complete the migration. My background is in the Windows / .NET world. This Linux / Ruby/Rails environment is quite foreign to me...

Here's the current environment I've set-up:

Route 53

Record Name Record Type Alias Alias Route Traffic To
foo.example.com A yes cloudfront: xyz.cloudfront.net

CloudFront

Domain Name Alternate Domain Names Origin Domain Origin Protocol Behavior Protocol
xyz.cloudfront.net foo.example.com foo.us-west-2.elb.amazonaws.com HTTP only Redirect HTTP to HTTPS

The CloudFront distribution:

  • uses an AWS issued SSL cert
  • handles the http to https redirect
  • forwards the request to the ELB over http (not https)

Load Balancer

DNS Name Listener Rule Forward To
foo.us-west-2.elb.amazonaws.com HTTP 80: default action Target Group: foo-ec2

Target Group: foo-ec2 contains a single Ubuntu ec2 instance running nginx/1.18.0 Phusion Passenger 6.0.10 to serve up the Ruby/Rails site.

nginx config

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

    # SSL Config - we should NEVER receive 443/https traffic; 
    # CloudFront manages https traffic => AWS ELB => http to this server
    #listen 443 ssl default_server;
    #listen [::]:443 ssl default_server;

    server_name foo.example.com
                foo.us-west-2.elb.amazonaws.com;

    # Tell Nginx and Passenger where the app's 'public' directory is
    root /var/www/foo_example/public;

    # Turn on Passenger
    passenger_enabled on;
    passenger_app_env production;
    passenger_ruby /home/ubuntu/.rbenv/versions/2.6.8/bin/ruby;
}

Issue

The rails app starts up without error and is served over https. However, when a user attempts to log in / authenticate, the enter image description here

Once the new origin request policy has been created:

  • head back to the CloudFront distributions
  • click your distribution's Id so you can edit it
  • click the "Behaviors" tab
  • select your behavior and edit
  • scroll down to "Cache key and origin requests"
  • make sure the "Cache policy and origin request policy (recommended)" is selected
  • under the "Origin request policy - optional", select your new policy, i.e., "my origin request policy"
  • save changes

The behavior will look like this (I'm using no caching for now to verify the ec2 instance is getting all the requests): enter image description here

That's it. The host header is now correctly passed through to the ELB and ec2 instance. Nothing else needs to be done with the ELB.

I verified the host header was being used in all requests by modifying the nginx logging option to include the $host variable in the log file (and did a bit more customization to the OOB format):

# prefixed log with '[my-log]', but it's not needed; remove.
log_format my-log '[my-log] $http_x_forwarded_for - $remote_user [$time_local] '
                  '"$request_method $scheme://$host$request_uri $server_protocol" '
                  '$status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time';

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

    # SSL Config - we should NEVER receive 443/https traffic; 
    # CloudFront manages https traffic => AWS ELB => http to this server
    #listen 443 ssl default_server;
    #listen [::]:443 ssl default_server;

    server_name foo.example.com
                foo.us-west-2.elb.amazonaws.com;

    # create the our log file
    access_log /var/log/nginx/my-log.access.log my-log;

    # Tell Nginx and Passenger where the app's 'public' directory is
    root /var/www/foo_example/public;

    # Turn on Passenger
    passenger_enabled on;
    passenger_app_env production;
    passenger_ruby /home/ubuntu/.rbenv/versions/2.6.8/bin/ruby;
}

Surely this will help future me as well as others.

  • Related