Nginx is currently a common choice when setting up reverse proxies for ruby web services. I currently serve all projects using unicorn, which creates a unix socket through which nginx talks to the application. The nginx configuration is pretty straightforward, you define a server with some rules and a location for your application. Whenever a location matches a path of your application, nginx will forward this request to the application through the unix socket.
The nginx config was something like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
This config always worked for setups without SSL so I was certain that it will just work with the SSL rewrite.
However I was getting
403 - Forbidden for all requests
errors also showed up in the log files:
attack reported by Rack::Protection::AuthenticityToken
I was puzzled since all requests had their proper authenticity token and nothing was different from my development configuration where everything worked, same ruby version, same gemset.
After some debugging I found the solution for the problem which is pretty simple and obvious.
rack-protection also checks the protocol which has been used for the
request - if nginx does not send this information correctly, there will be
a mismatch of the protocol (assumed http) and the referer (https) which
will result in a
Just add this line to your nginx config:
proxy_set_header X-Forwarded-Proto $scheme;
This will tell your application that the original request came in using
https even though the request from nginx to unicorn is
Update 2015/12/02: The rack module that is responsible for the error seems to be Rack::Protection::HttpOrigin. Thanks to @907th for the hint!