HAProxy, X-HTTP-Forwarded-For and exposed exceptions
A misconfiguration in your HAProxy + Rails setup can lead to some security concerns
(A german version is available at the kaupert media website)
We use HAProxy as the load balancing frontend to forward incoming requests to Apache+Passenger instances for a client’s web app.
Problems arose on the HAProxy machine itself which was also forwarding requests
to a locally running Apache as part of the available application backends:
despite using the forward_for
option for the configured backend, Rails
considered all incoming requests local as they were indeed coming from the
local machine. The result was exposed exceptions, even on something as trivial
as a RoutingError
which should trigger a normal 404 page.
Wesley Moxam described this problem in a blog
post,
but our setup is slightly different: HAProxy sends requests directly to
Passenger/mod_rails within Apache vhosts without Apache-side (double)proxying
involved. Removing the option forward_for
as described in said post was no
viable way to go for us as it confused the non-local nodes in the setup.
Heaving the formally locally running instance onto the external interface and
treating it just as any other node rid us of the first problem and adding your
HAProxy to the list of TRUSTED_PROXIES
fixes the second. Add the following line
as an initializer to your Rails 2.3.x app. The HAProxy backend uses option
httpclose
and option forward_for
.
# config/initializers/trusted_proxies.rb
# If your HAProxy is running at IPv4 address a.b.c.d, set:
ActionController::Request.const_set("TRUSTED_PROXIES", /^a\.b\.c\.d$|^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./i)
Granted, I don’t feel overly comfortable with coding that bit of network architecture into my Rails application. Moving servers and switching IPs is pain enough as it stands and thus I don’t like adding another dependency. It works, though, and here’s to hoping that our load balancer does not have to be exchanged anytime soon.
comments powered by Disqus