skip to Main Content

I have an app hosted on AWS Elastic Beanstalk, which is assigned an environment URL as such:

<my-appname>.<aws-region>.elasticbeanstalk.com

I also have registered a domain name as such:

my-appname.com

In AWS Route 53, I have an A ALIAS pointing my-appname.com to the EB environment as such:

my-appname.com > A ALIAS <my-appname>.<aws-region>.elasticbeanstalk.com

From my registrar, I have Route 53 nameservers set up to manage DNS via Amazon.

Everything Works Fine

What I’d like to understand how to do is ensure any requests to the <my-appname>.<aws-region>.elasticbeanstalk.com> domain get 301‘d to the my-appname.com domain.

I’m using an Apache RewriteRule currently to redirect all non-www requests to the www version of the website using this in a .config file:

<If "'%{HTTP_HOST}' !~ /^www./">
    RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</If>

Would it be good practice to simply change the HTTP_HOST to my-appname.com?

EDIT: That approach doesn’t seem to work anyway. Not sure why?

2

Answers


  1. Chosen as BEST ANSWER

    My current understanding is the best approach for this is to use server-level re-writes to address the issue. An example (for an Apache server) is as follows:

    Rewrite Engine On
    
    # Catch requests to domains other than your primary (custom) domain
    Rewrite Cond %{HTTP_HOST} !~ appname.tld
    
    # Send those requests to the primary domain
    RewriteRule (.*) http://www.appname.tld%{REQUEST_URI} [R=301, L]
    

  2. When using Elastic Beanstalk (Amazon Linux 2) and Nginx you have two solutions:

    Extend Elastic Beanstalk default nginx.conf

    Create a file named .platform/nginx/conf.d/redirections.conf inside your source code that contains:

    server {
        server_name .elasticbeanstalk.com;
        return 301 https://example.com$request_uri;
    }
    

    Nginx documentation: https://www.nginx.com/blog/creating-nginx-rewrite-rules/

    (example.com being your own domain)

    Create your own nginx.conf that replaces the default one from Elastic Beanstalk

    • Copy the content from the original /etc/nginx/nginx.conf by connecting to your Elastic Beanstalk EC2 instance using SSH (*)
    • Create a file named .platform/nginx/nginx.conf inside your source code and paste the content
    • Modify it to your needs and add:
    server {
        server_name .elasticbeanstalk.com;
        return 301 https://example.com$request_uri;
    }
    

    You should end up with a /etc/nginx/nginx.conf (taken from Amazon Linux 2 as of 2022/05/08) that looks like this:

    # Elastic Beanstalk Nginx Configuration File
    
    user                    nginx;
    error_log               /var/log/nginx/error.log warn;
    pid                     /var/run/nginx.pid;
    worker_processes        auto;
    worker_rlimit_nofile    32136;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        include       conf.d/*.conf;
    
        map $http_upgrade $connection_upgrade {
            default     "upgrade";
        }
    
        server {
            listen        80 default_server;
            access_log    /var/log/nginx/access.log main;
    
            client_header_timeout 60;
            client_body_timeout   60;
            keepalive_timeout     60;
            gzip                  off;
            gzip_comp_level       4;
            gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    
            # Include the Elastic Beanstalk generated locations
            include conf.d/elasticbeanstalk/*.conf;
        }
    
        # ADDED
        server {
            server_name .elasticbeanstalk.com;
            return 301 https://example.com$request_uri;
        }
    }
    

    More on Nginx configuration

    While at it, I also recommend other modifications to your Nginx configuration.

    Redirect www to root

    Example with redirecting http://www.example.com to example.com.

    # .platform/nginx/conf.d/redirections.conf
    
    # https://stackoverflow.com/a/43089681
    # https://tribulant.com/docs/hosting-domains/hosting/9867/redirecting-to-www-or-non-www/
    # This can be done at the load balancer level but I prefer to do it here
    # Test this with `curl --head https://www.example.com` and `curl --head http://www.example.com`
    server {
        server_name www.example.com;
        return 301 https://example.com$request_uri;
    }
    

    Prerequisites:

    HTTP security headers

    I recommend to set these HTTP headers for security:

    # .platform/nginx/conf.d/security_headers.conf
    
    # Remove Nginx version in error page and header
    server_tokens off;
    
    # Security headers thanks to https://observatory.mozilla.org/ and https://webpagetest.org/
    # Inspired by https://www.mozilla.org/ HTTP headers
    # https://gist.github.com/plentz/6737338
    # https://github.com/GetPageSpeed/ngx_security_headers
    add_header Content-Security-Policy "default-src 'self';
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
    add_header X-XSS-Protection "1; mode=block";
    

    File compression (.js, .css, .html…)

    You can enable compression with gzip on;. Unfortunately you cannot extend the default nginx.conf to enable compression. You will have to copy-paste and modify the original nginx.conf (.platform/nginx/nginx.conf).

    Note: you can have your own .platform/nginx/nginx.conf and still use files inside .platform/nginx/conf.d/ directory.

    Redirect HTTP to HTTPS

    2 solutions: use the load balancer (Application Load Balancer) or a custom .platform/nginx/nginx.conf.

    # .platform/nginx/nginx.conf
    
    ...
    
        server {
            listen        80 default_server;
    
            ...
    
            # ADDED
            # [AWS documentation - Configuring HTTP to HTTPS redirection](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.html)
            # https://github.com/awsdocs/elastic-beanstalk-samples/blob/9720e38e9da155752dce132a31d8e13a27364b83/configuration-files/aws-provided/security-configuration/https-redirect/nodejs/https-redirect-nodejs.config#L61
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
            if ($http_x_forwarded_proto = "http") {
                return 301 https://example.com$request_uri;
            }
    
            ...
        }
    
    ...
    

    (*) Open port 22 in your EC2 instance security group (something like *AWSEBSecurityGroup*) then go to:

    EC2 > Instances > Connect > EC2 Instance Connect (browser-based SSH connection)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search