Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx can not forward the request protocol correctly to upstream

I have a website in rails 4 beta. It is running on Nginx + Unicorn. I want nginx to forward the request protocol ( 'http' or 'https' ) to unicorn so that I can work with them. However I am not able to make it work.

I put <%= request.ssl? %> and <%= request.protocol %> in the view file for testing. My nginx server config file is as following:

upstream unicorn {
  server unix:/tmp/unicorn.blog.sock fail_timeout=0;
}

server {
  listen 80;
  listen 443;
  server_name example.com;
  root /home/example;

  ssl on;
  ssl_certificate /etc/nginx/ssl/server.crt;
  ssl_certificate_key /etc/nginx/ssl/server.key;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Forwarded-Proto https;  # <--- Line 1
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Ssl on;       # <--- Line 2
    proxy_redirect off;
    proxy_pass http://unicorn;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
}

I found that the 2 lines I marked are not acting right. Here is my test result:

=================

Line 1 commented out, Line 2 commented out too :

visit http://the.url

<%= request.ssl? %>     : false
<%= request.protocol %> : http

visit https://the.url

<%= request.ssl? %>     : false
<%= request.protocol %> : http

=================

Line 1 commented out, Line 2 is not OR Line 2 commented out, Line 1 is not OR Neither is comments out

visit http://the.url

<%= request.ssl? %>     : true
<%= request.protocol %> : https

visit https://the.url

<%= request.ssl? %>     : true
<%= request.protocol %> : https

=================

That is to say, if one of those two lines appears, nginx forward "https" to upstream no matter what the actual protocol is. But if none of those two lines appears, nginx forward "http" to upstream no matter what the actual protocol is.

Please can someone tell me how to write the nginx config file so that it can forward the protocol correctly? Thank you very much.

like image 385
blacktulip Avatar asked Apr 25 '13 19:04

blacktulip


People also ask

What does upstream mean in nginx?

upstream defines a cluster that you can proxy requests to. It's commonly used for defining either a web server cluster for load balancing, or an app server cluster for routing / load balancing.

What is nginx reverse proxy?

A reverse proxy server is a type of proxy server that typically sits behind the firewall in a private network and directs client requests to the appropriate backend server. A reverse proxy provides an additional level of abstraction and control to ensure the smooth flow of network traffic between clients and servers.

Does nginx support proxy protocol?

The PROXY protocol enables NGINX and NGINX Plus to receive client connection information passed through proxy servers and load balancers such as HAproxy and Amazon Elastic Load Balancer (ELB). With the PROXY protocol, NGINX can learn the originating IP address from HTTP, SSL, HTTP/2, SPDY, WebSocket, and TCP.


2 Answers

try:

proxy_set_header X-Forwarded-Proto $scheme;

OR

server {
    Listen 80
    ...
}
server {
    Listen 443
    ...
    location @unicorn {
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Ssl on;
    }
}
like image 141
yegle Avatar answered Oct 11 '22 18:10

yegle


You will need to configure two separate server blocks. One for HTTP and one for HTTPS. It will make configuring the two a whole lot easier. Parts that are identical you can include from a separate shared config file.

like image 38
Bart Avatar answered Oct 11 '22 18:10

Bart