5

I have a regular instance that works fine when not behind a load balancer. I set up an ELB with 80 forwarding to 80 and 443 forwarding to 443 and sticky sessions. Afterward I receive this error when going to any https page.

The plain HTTP request was sent to HTTPS port

I handle the process of forcing https on certain pages in my nginx configuration. What do I need to do to get this working? I'm putting in a barebones version of my nginx config below.

http {

  include               mime.types;
  default_type          application/octet-stream;

  # Directories
  client_body_temp_path tmp/client_body/  2 2;
  fastcgi_temp_path     tmp/fastcgi/;
  proxy_temp_path       tmp/proxy/;
  uwsgi_temp_path       tmp/uwsgi/;

  server {
    listen              443;
    ssl                 on;
    ssl_certificate     ssl.crt;
    ssl_certificate_key ssl.key;

    server_name www.shirtsby.me;
    if ($host ~* ^www\.(.*)) {
        set $host_without_www $1;
        rewrite ^/(.*) $scheme://$host_without_www/$1 permanent;
    }

    location ~ ^/(images|img|thumbs|js|css)/  {
          root /app/public;
    }
    if ($uri ~ ^/(images|img|thumbs|js|css)/) {
        set $ssltoggle 1;
    }
    if ($uri ~ "/nonsecure") {
        set $ssltoggle 1;
    }
    if ($ssltoggle != 1) {
        rewrite ^(.*)$ http://$server_name$1 permanent;
    }

    location / {
      uwsgi_pass  unix:/site/sock/uwsgi.sock;
      include     uwsgi_params;
    }

  }

  server {
    listen      80;
    server_name www.shirtsby.me;
    if ($host ~* ^www\.(.*)) {
        set $host_without_www $1;
        rewrite ^/(.*) $scheme://$host_without_www/$1 permanent;
    }

    if ($uri ~ "/secure") {
        set $ssltoggle 1;
    }
    if ($ssltoggle = 1) {
        rewrite ^(.*)$ https://$server_name$1 permanent;
    }

    location ~ ^/(images|img|thumbs|js|css)/  {
          root /app/public;
    }

    location / {
      uwsgi_pass  unix:/home/ubuntu/site/sock/uwsgi.sock;
      include     uwsgi_params;
    }
  }
}
jchysk
  • 319
  • 1
  • 5
  • 13
  • Looking around I found this:if ($http_x_forwarded_proto = "https") { set $my_https "on"; }. Don't know if that will help or not. I don't really want to switch it back to the load balancer and have the site not working until I'm confident I can fix it. – jchysk Mar 13 '12 at 06:38

3 Answers3

3

Ended up getting the answer from vandemar in the nginx IRC Channel. Seems pretty simple, but I struggled with figuring it out. The ELB was handling the SSL, I had already given it all the cert information. The problem was trying to handle it again on the individual instances or in the configuration file. The solution is to just eliminate all the SSL stuff from the config file. So removing these three lines fixed everything:

ssl                 on;
ssl_certificate     ssl.crt;
ssl_certificate_key ssl.key;
jchysk
  • 319
  • 1
  • 5
  • 13
  • I upvoted, but a couple comments. If you have the health checking for your loadbalancer running on the ssl port, as I did, this will take the listener out of service. Also, I think this doesn't solve the problem the way I wanted. Specifically, I'd like to have encrypted comm between the load balancer and the instance. The docs say there's away, but I don't see in on the options. – codenoob May 09 '15 at 13:11
  • It would depend on how you will configure communication between ELB and EC2 instance - http://i.imgur.com/4S4blzJ.png – ALex_hha Apr 27 '16 at 14:55
2

For me, I was using CloudFormation to set up my load balancer. InstanceProtocol defaults to HTTP, and I didn't have that parameter set. This was the fix:

  ElasticLoadBalancer:
    Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
    Properties:
      Listeners:
        - LoadBalancerPort: '443'
          Protocol: HTTPS
          InstancePort: '443'
          InstanceProtocol: HTTPS
tom
  • 121
  • 2
0

I had the same issue. But then I noticed that my elb-listener was configured incorrectly. I set up load-balancer protocol: https, load-balancer-port: 443, instance-port: 443, but forgot to change instance-protocol from http to https.