Apparently Rails 2.1 has the nifty ability to throw a 500 Internal Server Error with the message “IP spoofing attack?!” under certain circumstances.
Unfortunately, those circumstances include a common Apache/Mongrel deployment and Yahoo’s crawler, Slurp, trying to index your site. It’s possible Apache/Mongrel isn’t required; I’m unsure.
The key is that Slurp includes both a Client-IP header (HTTP_CLIENT_IP by the time it hits Rails) and an X-Forwarded-For header (HTTP_X_FORWARDED_FOR). When both are present, Rails assumes something evil is happening and voluntarily dies. Neat.
Such a header can be relied on only if it was set by a trusted proxy. Otherwise, it’s hard to know if it was spoofed. The difficulty is for Rails to know which one, if any, was set by a trusted proxy.
I deploy Rails in a common Apache w/mod_proxy_balancer and Mongrel setup. Apache uses X-Forwarded-For natively, so that’s the one I want to trust. To make Rails happy, I’ve just told Apache to delete the Client-IP header if present.
Adding RequestHeader unset Client-IP to the virtual host configuration seems to do the trick.
This does require mod_headers to be enabled in Apache.
Today I needed to compile mod_xsendfile for OS X on Intel. The standard command for this,
apxs -cia mod_xsendfile.c
resulted in a module that was for i386 only.
Apache on Leopard (untested on Tiger) doesn’t appreciate this, throwing this error:
4/7/08 5:08:08 PM org.apache.httpd[ 15990] httpd: Syntax error on line 116 of /private/etc/apache2/httpd.conf: Cannot load /usr/libexec/apache2/mod_xsendfile.so into server: dlopen(/usr/libexec/apache2/mod_xsendfile.so, 10): no suitable image found. Did find:\n\t/usr/libexec/apache2/mod_xsendfile.so: mach-o, but wrong architecture
Turns out the solution is pretty simple. Just change the command to apxs to this:
a brief hint about setting up apache 2.2’s mod_proxy_balancer with a mongrel cluster.
if you receive a permission error, “client denied by server configuration” when accessing your apache install, check the proxy configuration. in this case that means the proxy balancer configuration. an example working config:
1<Proxybalancer://mongrel_cluster>2 BalancerMember http://127.0.0.1:8000
3 BalancerMember http://127.0.0.1:8001
4 Order deny,allow
5 Deny from all
6 Allow from all
the key is the last 3 lines, Order…, Deny…, and Allow….
this usually comes from a more general proxy permissions config:
1<Proxy*>2 Order deny,allow
3 Deny from all
this protects against other kinds of proxy support in apache being publicly accessible, and is a good thing. so leave that in place, and just specifically allow access to the balancer proxy.