用tproxy+haproxy实现透明代理



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

你可能感兴趣的:(用tproxy+haproxy实现透明代理)