4

I want a redirect from HTTP request to HTTPS on Elastic Beanstalk with nginx as proxy system.

I've found a lot of advices on Google but no one helped, it doesn't redirect.

That is my current test.config file in .ebexentions directory:

files:
"/etc/nginx/conf.d/proxy.conf" :
    mode: "000644"
    owner: root
    group: root
    content: |
        server{
            if ($http_x_forwarded_proto = "http") {
                return 301 https://$host$request_uri;
            }
        }

I've also tried countless other settings, none of them worked.

That are my load balancer settings: enter image description here

I hope you can help me. :)

Vincent Hoch-Drei
  • 603
  • 2
  • 7
  • 21
  • Is your EB setup with a load balancer? Did you review everything at this SO article? https://stackoverflow.com/questions/24297375/how-to-get-elastic-beanstalk-nginx-backed-proxy-server-to-auto-redirect-from-htt – Taterhead Aug 20 '18 at 08:58

5 Answers5

3

Some considerations:

1 - New Amazon Elastic Beanstalk platform versions running Amazon Linux 2 have a different path of reverse proxy configuration:

~/workspace/my-app/
|-- .platform
|   `-- nginx
|      `-- conf.d
|         `-- elasticbeanstalk
|            `-- 00_application.conf
`-- other source files

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html

2 - The AWS ELB Health Checker appears to be unable to check HTTPS endpoints. Surely, if you are using a custom certificate for your domain, is unable to act a check in what he considers an "untrusted site". https://your-eb-app.eu-west-3.elasticbeanstalk.com published with a certificate registered for your organization with this DNS alias https://your-eb-app.your-organization.com causes ELB Health Checker error (certificate domain mismatch).

3 - The configuration suggested exposes all locations to ANY client which shows up with "ELB-HealthChecker*" user-agent on the standard HTTP port (80); not quite what we want :-)

You can configure ELB Health Checker to accept the HTTP 301 status, but it doesn't have much use; a simple redirect response does not mean that our web application is in good health :-)

A more secure solution is a dedicated health check endpoint configuration:

location / {
    set $redirect 0;
    if ($http_x_forwarded_proto != "https") {
        set $redirect 1;
    }
    if ($redirect = 1) {
        return 301 https://$host$request_uri;
    }   

    proxy_pass        http://127.0.0.1:5000;
    proxy_http_version  1.1;

    proxy_set_header    Connection         $connection_upgrade;
    proxy_set_header    Upgrade            $http_upgrade;
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
}

location = /health-check.html {
    set $redirect 0;
    if ($http_x_forwarded_proto != "https") {
        set $redirect 1;
    }
    if ($http_user_agent ~* "ELB-HealthChecker") {
        set $redirect 0;
    }
    if ($redirect = 1) {
        return 301 https://$host$request_uri;
    }   

    proxy_pass        http://127.0.0.1:5000;
    proxy_http_version  1.1;

    proxy_set_header    Connection         $connection_upgrade;
    proxy_set_header    Upgrade            $http_upgrade;
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
}
aritstack
  • 83
  • 8
  • I tried this but, if I put the 00_application.conf inside elasticbeanstalk, it is ignored completed. If I put it one level up, it is read, but it expects something different. For instance if I include "location" I get "location" directive is not allowed here in /var/proxy/staging/nginx/conf.d/00_application.conf:1. If I only include the server directive, then I get conflicting server name "" on 0.0.0.0:80, ignored (I suppose because the server is already configured in the main nginx config). – Marco Nov 18 '21 at 15:02
  • 1
    Are you using Amazon Linux 2 platform? These are my machine nginx file configuration paths: [root@ip-172-99-99-55 ~]# find / -name 00_application.conf /etc/nginx/conf.d/elasticbeanstalk/00_application.conf /var/app/current/.platform/nginx/conf.d/elasticbeanstalk/00_application.conf /var/proxy/staging/nginx/conf.d/elasticbeanstalk/00_application.conf – aritstack Nov 18 '21 at 17:21
2

I faced a similar problem when I was trying to redirect all HTTP traffic to HTTPS in my AWS Elastic Beanstalk Go environment using Nginx. This is the solution, I was provided by the AWS Support team:

Create a file in the below directory structure at the root of the application code.

.ebextensions/nginx/conf.d/elasticbeanstalk/00_application.conf

with the content

location / {
    set $redirect 0;
    if ($http_x_forwarded_proto != "https") {
        set $redirect 1;
    }
    if ($http_user_agent ~* "ELB-HealthChecker") {
        set $redirect 0;
    }
    if ($redirect = 1) {
        return 301 https://$host$request_uri;
    }

    proxy_pass          http://127.0.0.1:5000;
    proxy_http_version  1.1;

    proxy_set_header    Connection          $connection_upgrade;
    proxy_set_header    Upgrade             $http_upgrade;
    proxy_set_header    Host                $host;
    proxy_set_header    X-Real-IP           $remote_addr;
    proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
}

For a complete list of AWS provided config files, you should check out this link.

Mehvix
  • 296
  • 3
  • 12
Samkit Jain
  • 1,560
  • 2
  • 16
  • 33
  • This solution did'nt work for me, after successful deployment elasticbeanstalk folder only contains two files healthd.conf php.conf – Ali Abbas May 26 '20 at 23:49
  • @AliAbbas PHP reference is at https://github.com/awsdocs/elastic-beanstalk-samples/blob/master/configuration-files/aws-provided/security-configuration/https-redirect/php/https-redirect-php.config – Samkit Jain May 27 '20 at 11:58
  • Thank you it tried too many things , What i only need inside nginx/conf.d/elasticbeanstalk/custom.conf location /blog { try_files $uri $uri/ /blog/index.php?$args; gzip_static on; } location /blogs { return 301 $scheme://site.com/blog; } location /blogs.html { return 301 $scheme://site.com/blog; } location ~ ^/blogs/(.*) { return 301 $scheme://site.com/blog; } but I am not sure why this folder is not adding any file – Ali Abbas May 27 '20 at 12:06
2

This is the only solution that worked.

It's necessary to overwrite the default nginx file after AWS created it. So there has to be two more files:

  1. Write the nginx file.
  2. Create a script that overwrites the default nginx file.
  3. Run the script after AWS created the default file.
slfan
  • 8,950
  • 115
  • 65
  • 78
Vincent Hoch-Drei
  • 603
  • 2
  • 7
  • 21
0

What I did to achieve , I completely override original nginx.conf with my custom given nginx.conf along with some custom configuration for location directives

.plateform -- nginx -- nginx.conf -- conf.d -- elasticbeanstalk --custom.conf

Here is my nginx.conf

user  nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    32153;
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;
}

}

Following line will helped me to safely over-ride the configuration

include conf.d/elasticbeanstalk/*.conf;

Ali Abbas
  • 498
  • 7
  • 20
0

AWS Beanstalk environment Load balancer

Make sure that under the load balancer settings of Beanstalk environment both the ports(80,443) enable. If the port 80 is disable you will get the error of 503 "Service Temporarily Unavailable"