Hi Toni,
On Wed, Apr 07, 2010 at 04:51:36PM +0300, Toni Mattila wrote:
> Hi,
>
> Has anyone solved the issue where you have haproxy compiled with TPROXY
> support and use "source 0.0.0.0 usesrc clientip" configuration when
> client is behind the tproxied server.
>
> Scenario:
> Haproxy server with:
> 10.0.0.1/24 IP address this is the "public" side
> 10.1.0.1/24 IP address this is the tproxy side
>
> Web server with:
> 10.1.0.2/24 IP address (using 10.1.0.1 as default gateway)
>
> Configuration:
> listen www 10.0.0.1:80
> mode http
> option http-server-close
> option abortonclose
> mode http
> balance leastconn
> source 0.0.0.0 usesrc clientip
> server server1 10.1.0.2:80 weight 1 check maxconn 270
> option redispatch
>
> Let's say www.example.com is mapped to 10.0.0.1 and you try to access
> www.example.com from webserver using lynx/links/wget you just get:
> HTTP/1.0 503 Service Unavailable
> Cache-Control: no-cache
> Connection: close
> Content-Type: text/html
This is expected, it cannot work because your webserver would have to
reply to itself directly without going back through haproxy, so the
connection does not match at all. It's amusing, because 10 years ago,
people had this issue with NAT-based load balancers. So editors have
added a "proxy" feature so that the LB could translate the source
address to put theirs when reaching the server. Now you have a proxy
which works in this proxy mode by default, and you're trying to make
it work like those old NAT-based LBs and are encountering the same
routing issues.
Since you're using HTTP, it's a real waste of simplicity and performance
to try to work in transparent mode. You'd better work in a normal proxy
mode and configure your web server to report the client's IP address in
the logs instead of relying on haproxy and your kernel to spoof the client.
If for any reason you absolutely want to do that anyway, here are two
possibilities :
1) use two different backends, one for local connections, and another one
for external ones. The local one must not do transparent proxying :
listen www 10.0.0.1:80
mode http
option http-server-close
option abortonclose
use_backend from-lan if { src 10.1.0.0/24 }
balance leastconn
source 0.0.0.0 usesrc clientip
server server1 10.1.0.2:80 weight 1 check maxconn 270
option redispatch
backend from-lan
mode http
option http-server-close
option abortonclose
balance leastconn
server server1 10.1.0.2:80 weight 1 maxconn 270 track www/server1
option redispatch
2) The second option is very dirty. Since 1.4.4 you can make haproxy bind to
a source address presented in an HTTP header. You just have to enable the
x-forwarded-for header except from the LAN. It will then bind to the client's
IP when it comes from outside the LAN and not do any specific binding when
it comes from the LAN :
listen www 10.0.0.1:80
mode http
option http-server-close
option abortonclose
reqidel ^X-Forwarded-For # just in case your servers would set one
option forwardfor except 10.1.0.0/24
balance leastconn
source 0.0.0.0 usesrc hdr_ip(x-forwarded-for)
server server1 10.1.0.2:80 weight 1 check maxconn 270
option redispatch
Hoping this helps,
Willy