haproxy机器准备安装源:
root@ubuntu-haproxy:~# cat /etc/apt/sources.list
deb http://mirrors.163.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ trusty-backports main restricted universe multiverse
root@ubuntu-haproxy:~# apt update
haproxy机器安装依赖
apt install make wget -y
apt-get install build-essential -y
apt-get install libssl-dev -y
apt-get install libpcre++-dev -y
wget http://www.haproxy.org/download/1.8/src/devel/haproxy-1.8-dev1.tar.gz
tar -zxf haproxy-1.8-dev1.tar.gz
cd haproxy-1.8-dev1
make TARGET=linux26 USE_STATIC_PCRE=1 USE_LINUX_TPROXY=1
cp haproxy /usr/bin/haproxy
mkdir -p /etc/haproxy/errors
cp examples/haproxy.cfg /etc/haproxy/haproxy.cfg
mv errorfiles/ /etc/haproxy/errors/
haproxy机器编辑/etc/haproxy/haproxy.cfg
root@ubuntu-haproxy:~#cat /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local0 info
maxconn 40000
daemon
nbproc 2
stats socket /var/run/haproxy.1 process 1
defaults
log global
option dontlognull
option redispatch
retries 3
maxconn 5000
timeout connect 5s
timeout client 50s
timeout server 50s
timeout tunnel 1h
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
listen lbl-m0hn6a07
bind *:80
mode tcp
option tcplog
maxconn 5000
timeout client 50s
default_backend lbl-m0hn6a07_default
backend lbl-m0hn6a07_default
mode tcp
option tcplog
balance roundrobin
timeout server 50s
timeout check 5000
server lbb-sg5j2sr5 192.168.10.244:80 check inter 10000 fall 2 rise 5 weight 1
source 0.0.0.0 usesrc clientip
haproxy机器执行iptables mark及转发表查找(假设对外的SLB或者说vip 为1.1.1.1)
root@ubuntu-haproxy:~#cat test.sh
iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 111
iptables -t mangle -A DIVERT -j ACCEPT
ip rule add fwmark 111 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
ip link show dev dummy || ip link add dummy type dummy
ip link set dev dummy up
ip addr replace 1.1.1.1/32 dev dummy
haproxy开启转发,重定向,及关闭rp_filter
root@ubuntu-haproxy:~#vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.lo.send_redirects = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.lo.rp_filter = 0
net.ipv4.conf.eth0.rp_filter = 0
net.ipv4.conf.eth1.rp_filter = 0
net.ipv4.conf.eth2.rp_filter = 0
net.ipv4.conf.eth3.rp_filter = 0
执行test.sh及haproxy
root@ubuntu-haproxy:~# sh test.sh
Device "dummy" does not exist.
root@ubuntu-haproxy:~# /usr/bin//haproxy -d -f /etc/haproxy/haproxy.cfg
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result FAILED
Total: 3 (2 usable), will use epoll.
Available filters :
[SPOE] spoe
[COMP] compression
[TRACE] trace
Using epoll() as the polling mechanism.
后端web机器的安装
web机器的默认路由要指向haproxy
开始测试
测试机器的ip为10.5.39.64,在测试机器上增加一条经haproxy ip到1.1.1.1/32的路由
root@kickseed:~#ip add li eno3
10.5.39.64
root@kickseed:~# ip route add 1.1.1.1/32 via 10.5.39.241
root@kickseed:~# telnet 1.1.1.1 80
Trying 1.1.1.1...
Connected to 1.1.1.1.
Escape character is '^]'.
iptables -t mangle -L -v
tcpdump观察
client连接的是vip 1.1.1.1
root@kickseed:~# tcpdump -i eno3 port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno3, link-type EN10MB (Ethernet), capture size 262144 bytes
16:30:34.273433 IP 10.5.39.64.33064 > 1.1.1.1.http: Flags [S], seq 1331799978, win 29200, options [mss 1460,sackOK,TS val 256939645 ecr 0,nop,wscale 7], length 0
16:30:34.275458 IP 1.1.1.1.http > 10.5.39.64.33064: Flags [S.], seq 240490277, ack 1331799979, win 28960, options [mss 1460,sackOK,TS val 1676723 ecr 256939645,nop,wscale 7], length 0
16:30:34.275504 IP 10.5.39.64.33064 > 1.1.1.1.http: Flags [.], ack 1, win 229, options [nop,nop,TS val 256939646 ecr 1676723], length 0
16:34:24.765216 IP 1.1.1.1.http > 10.5.39.64.33064: Flags [F.], seq 1, ack 1, win 227, options [nop,nop,TS val 1734345 ecr 256939646], length 0
16:34:24.765293 IP 10.5.39.64.33064 > 1.1.1.1.http: Flags [F.], seq 1, ack 2, win 229, options [nop,nop,TS val 256997268 ecr 1734345], length 0
16:34:24.771567 IP 1.1.1.1.http > 10.5.39.64.33064: Flags [.], ack 2, win 227, options [nop,nop,TS val 1734347 ecr 256997268], length 0
在web机器上看到的source ip确实是client的原生ip,即实现了透明代理(注意是haproxy在发起向后端的web连接时,使用的是非本地的ip,即原生的client ip)
REF:
https://www.kernel.org/doc/Documentation/networking/tproxy.txt
http://blog.csdn.net/dog250/article/details/7518054
https://www.haproxy.org/download/1.8/doc/configuration.txt