Hi Nick,<br>&nbsp;&nbsp;&nbsp;&nbsp; Why don&#39;t you simplify your setup. You can have your Rails App running on your big server without needing nginx on it at all. All you do is open up the rails instances to allow access from your nginx frontends and then proxy the requests to it. Instead of having to proxy to nginx and then proxying again. <br>
<br>&nbsp;&nbsp;&nbsp;&nbsp; Or the other option you can do is on your nginx server that proxy&#39;s to your rails app. Have 2 server directives that listen on two different ports. Then when non-ssl traffic comes into your frontend server and redirect it to server 1, which has your standard proxy_pass. Then on your frontends have your ssl portion of the server redirect to the 2nd server port on the backend that sets the&nbsp; X_FORWARDED_PROTO to https manually.<br>
<br>Rob<br><br><div class="gmail_quote">On Wed, Oct 29, 2008 at 3:14 PM, Nick Pearson <span dir="ltr">&lt;<a href="mailto:nick.pearson@gmail.com">nick.pearson@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi,<br>
<br>
I have what I think is an obscure problem to which I cannot find a<br>
solution in the nginx docs. &nbsp;Here&#39;s a summary of the problem:<br>
<br>
I have a content management system that I wrote (using Rails), and it<br>
hosts several sites. &nbsp;Each site has SSL, and due to a policy limit by<br>
my hosting provider, each virtual server (&quot;slice&quot;) can only have five<br>
external IP addresses. &nbsp;This creates a problem in that the CMS that<br>
was built to host lots of sites is limited to hosting only five. &nbsp;My<br>
solution was to set up smaller slices in front of the main server, and<br>
the small slices would run nothing but nginx. &nbsp;As such, the<br>
&quot;front-end&quot; nginx instances would proxy requests to the &quot;back-end&quot;<br>
nginx, and the &quot;back-end&quot; nginx would proxy requests through to the<br>
Rails app server instances.<br>
<br>
I saw a recent post on SSL pass-through, but this is not what I&#39;m<br>
looking for. &nbsp;As the slices are on the same network at my hosting<br>
provider, I don&#39;t care that the slice-to-slice communications are<br>
encrypted. &nbsp;This is not an issue.<br>
<br>
What is an issue is that the application (and thus the Rails app<br>
server instances) need to be able to determine whether a request came<br>
in using SSL or not. &nbsp;Because requests are proxied through two<br>
instances of nginx running on separate slices, the back-end nginx<br>
cannot see whether a request came in over http or https -- because<br>
either way, the request arrived at the back-end nginx over http (not<br>
https). &nbsp;Here is a simple depiction of two requests -- one over http<br>
and one over https:<br>
<br>
 &nbsp; &nbsp;client ---http---&gt; nginx ---http---&gt; nginx ---&gt; rails<br>
 &nbsp; &nbsp;client ---https--&gt; nginx ---http---&gt; nginx ---&gt; rails<br>
<br>
As you can see, it is the second (back-end) nginx instance in the<br>
chain that tells the Rails app server instances whether the request<br>
made to nginx was over http or https. &nbsp;And since all requests to the<br>
second nginx instance are made over http, it passes this on to the<br>
Rails app, which thinks all requests are made over http even if the<br>
communication between the client and the first (front-end) nginx is<br>
over https.<br>
<br>
Also worth noting is that there are no SSL errors. &nbsp;If the request is<br>
made over http, it works. &nbsp;And if the request is made over https, it<br>
works. &nbsp;The app server just doesn&#39;t know whether a request was made<br>
over http or https.<br>
<br>
I attempted to set the following on the back-end nginx:<br>
<br>
 &nbsp; &nbsp;proxy_set_header &nbsp;X_FORWARDED_PROTO &nbsp;$scheme;<br>
<br>
but not surprisingly, it doesn&#39;t work. &nbsp;($scheme is either &quot;http&quot; or<br>
&quot;https&quot;, taken directly from the request.) &nbsp;I may have a solution to<br>
the problem, but it will require some extra plumbing work in Rails to<br>
make it functional. &nbsp;What I am able to do is to set a custom header<br>
and then read the value of that header in the Rails code. &nbsp;Here is<br>
what I&#39;ve tried:<br>
<br>
 &nbsp; &nbsp;proxy_set_header &nbsp;HTTPS &nbsp;on;<br>
<br>
Then, in the Rails code, I can look for the HTTP_HTTPS environment<br>
variable. &nbsp;(nginx apparently prepends anything sent to<br>
proxy_set_header with &quot;HTTP_&quot;.) &nbsp;While this solution will probably<br>
work, I would prefer to have nginx pass the request scheme to the app<br>
servers without having to change the internals of Rails (by rewriting<br>
the request.ssl? method).<br>
<br>
This could be accomplished if nginx would let me conditionally set a<br>
header based on the value of another header. &nbsp;I just can&#39;t figure out<br>
how to read a header. &nbsp;Here&#39;s what I would like to do -- keep the<br>
&quot;proxy_set_header HTTPS on;&quot; (above) on the front-end nginx and use<br>
the header on the back-end nginx -- like this:<br>
<br>
 &nbsp; &nbsp;if ($HTTP_HTTPS = on) {<br>
 &nbsp; &nbsp; &nbsp; &nbsp;proxy_set_header &nbsp;X_FORWARDED_PROTO &nbsp;https;<br>
 &nbsp; &nbsp;}<br>
<br>
I realize that this means that anyone could arbitrarily add this<br>
header to a request and trick the Rails server into thinking the<br>
request was secure when it was not, but I would solve this by setting<br>
&quot;ignore_invalid_headers on;&quot; or similar on the front-end nginx.<br>
<br>
Can anyone tell me whether it is possible to read custom headers and<br>
to act on them as in my example above? &nbsp;If not, I think this would be<br>
a great addition.<br>
<br>
Thanks in advance.<br>
<font color="#888888"><br>
Nick Pearson<br>
<br>
</font></blockquote></div><br>