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
Stracing the haproxy it looks like this:
bind(1, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(1, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(1, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 1
setsockopt(1, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(1, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(1, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(1, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(1, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
accept(4, {sa_family=AF_INET, sin_port=htons(49978),
sin_addr=inet_addr("10.1.0.2")}, [16]) = 1
setsockopt(1, SOL_TCP, TCP_NODELAY, [1], 4) = 0
accept(4, 0xbfdd75b0, [128]) = -1 EAGAIN (Resource
temporarily unavailable)
recv(1, "GET / HTTP/1.0\r\nUser-Agent: Wget"..., 8192, 0) = 122
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 2
setsockopt(2, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(2, SOL_IP, 0x13 /* IP_??? */, [1], 4) = 0
setsockopt(2, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(2, {sa_family=AF_UNSPEC, sa_data="\0\0^\3079\204\0\0\0\0\0\0\0\0"},
16) = 0
connect(2, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
send(2, "GET / HTTP/1.0\r\nUser-Agent: Wget"..., 98,
MSG_DONTWAIT|MSG_NOSIGNAL) = -1 EAGAIN (Resource temporarily unavailable)
recv(1, 0xa064822, 8192, 0) = -1 EAGAIN (Resource
temporarily unavailable)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 2
setsockopt(2, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(2, SOL_IP, 0x13 /* IP_??? */, [1], 4) = 0
setsockopt(2, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(2, {sa_family=AF_UNSPEC, sa_data="\0\0^\3079\204\0\0\0\0\0\0\0\0"},
16) = 0
connect(2, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
send(2, "GET / HTTP/1.0\r\nUser-Agent: Wget"..., 98,
MSG_DONTWAIT|MSG_NOSIGNAL) = -1 EAGAIN (Resource temporarily unavailable)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 2
setsockopt(2, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(2, SOL_IP, 0x13 /* IP_??? */, [1], 4) = 0
setsockopt(2, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(2, {sa_family=AF_UNSPEC, sa_data="\0\0^\3079\204\0\0\0\0\0\0\0\0"},
16) = 0
connect(2, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
send(2, "GET / HTTP/1.0\r\nUser-Agent: Wget"..., 98,
MSG_DONTWAIT|MSG_NOSIGNAL) = -1 EAGAIN (Resource temporarily unavailable)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 2
setsockopt(2, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(2, SOL_IP, 0x13 /* IP_??? */, [1], 4) = 0
setsockopt(2, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(2, {sa_family=AF_UNSPEC, sa_data="\0\0^\3079\204\0\0\0\0\0\0\0\0"},
16) = 0
connect(2, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
send(2, "GET / HTTP/1.0\r\nUser-Agent: Wget"..., 98,
MSG_DONTWAIT|MSG_NOSIGNAL) = -1 EAGAIN (Resource temporarily unavailable)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(0),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = -1 EINPROGRESS (Operation now in
progress)
connect(3, {sa_family=AF_INET, sin_port=htons(80),
sin_addr=inet_addr("10.1.0.2")}, 16) = 0
send(1, "HTTP/1.0 503 Service Unavailable"..., 212,
MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE) = 212
shutdown(1, 1 /* send */) = 0
Additional haproxy related info:
# haproxy -vv
HA-Proxy version 1.4.1 2010/03/04
Copyright 2000-2010 Willy Tarreau <[email protected]>
Build options :
TARGET = linux26
CPU = generic
CC = gcc
CFLAGS = -O2 -g
OPTIONS = USE_LINUX_TPROXY=1 USE_STATIC_PCRE=1
Default settings :
maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200
Encrypted password support via crypt(3): yes
Available polling systems :
sepoll : pref=400, test result OK
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 4 (4 usable), will use sepoll.
# uname -a
Linux proxy02 2.6.31.5-127.fc12.i686.PAE #1 SMP Sat Nov 7 21:25:57 EST
2009 i686 i686 i386 GNU/Linux
Thanks in advance,
Toni Mattila