'Redirect Elastic Beanstalk URL to domain name
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?
Solution 1:[1]
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]
Solution 2:[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 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:
- AWS Certificate Manager (ACM): create one certificate for both example.com and www.example.com
- Route 53 : create A records for example.com and www.example.com that route to the load balancer
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)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | alphazwest |
Solution 2 |