vendredi 22 février 2019

Redirect all HTTP traffic to HTTPS seems to be impossible

I am posting the question because the previous attempts have proved to be futile.

I have a rails server using nginx, and I am trying to redirect all http traffic to https.

Here is my nginx.conf file:

upstream backend {
  server unix:PROJECT_PATH/tmp/thin1.sock;
  server unix:PROJECT_PATH/tmp/thin2.sock;
  server unix:PROJECT_PATH/tmp/thin3.sock;
  server unix:PROJECT_PATH/tmp/thin4.sock;
  server unix:PROJECT_PATH/tmp/thin5.sock;
  server unix:PROJECT_PATH/tmp/thin6.sock;
  server unix:PROJECT_PATH/tmp/thin7.sock;
  server unix:PROJECT_PATH/tmp/thin8.sock;
}  

server {
  listen 80 default_server;
  listen 443 default_server ssl;

  server_name app_name;
  ssl_certificate path_to_certificate_file.crt;
  ssl_certificate_key path_to_certificatefile.key;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

  root PATH_TO_PUBLIC_FOLDER;
  access_log path_to_project/log/access.log;
  error_log path_to_project/log/error.log;
  client_max_body_size 10m;
  large_client_header_buffers 4 16k;

  location /ping {
    echo "pong"
    return 200;
  }

  # Cache static content
  location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|swf|wav)$ {
    expires max;
    log_not_found off;
  }  

  # Status, local only (accessed via ssh+wget)
  location /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    deny all;
  }

  # double slash removal
  set $test_uri $host$request_uri;
  if ($test_uri != $host$uri$is_args$args)  {
    rewrite ^/(.*)$ /$1 break;
  }

  location / {
    if ($http_x_forwarded_proto = 'http') {
      return 301 https://$server_name$request_uri;   
    }
    try_files $uri @proxy;
  }

  location @proxy {    
    proxy_redirect off;  
    # Inform we are on SSL
    proxy_set_header X-Forwarded-Proto https;

    # force timeouts if one of backend is died
    proxy_next_upstream error timeout invalid_header http_502 http_503;

    # Set headers
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    

    proxy_pass http://backend;
  }

  error_page 500 502 503 504 /500.html;
}

The current configuration causes:

400 Bad Request The plain HTTP request was sent to HTTPS port

You may notice the /ping location. That's because I have the servers behind a GCE balancer that performs a health check, and this is THE ONLY one I do not want to redirect. Everything else should be redirected to HTTPS.

Previous attempts:

server {
  listen 80;

  server_name app_name;

  location /ping  {
    echo "pong";
    return 200;
  }

  location / {
    return 301 https://$server_name$request_uri;
  }
}

With the https server part like the current config (with listen 80 default_server commented). This causes a too many redirections error.

I tried to simply redirect ALL traffic to https, including the health check. GCE expects a 200 response and instead it gets a 301, thus marking the machine as unhealthy and rendering the application useless.

I also tried the ssl on; on the https server config, same result (400)

I also tried to toggle the config.force_ssl = true in the rails project to no avail. Every other solution I try fails too.

Did anyone stumble on this also?

Aucun commentaire:

Enregistrer un commentaire