4层代理haproxy
一. 简介
最近发现了haproxy,工作在7层协议第4层,感觉非常牛逼!!!
之前一直用的nginx,是工作在7层,虽然现在也可以进行4层代理了,但是可配置的参数太少,远不如haproxy操作空间那么大。
二. 安装
install_haproxy.sh
wget http://www.haproxy.org/download/1.8/src/haproxy-1.8.3.tar.gz
tar zxvf haproxy-1.8.3.tar.gz
cd haproxy-1.8.3
make TARGET=linux415 ARCH=x86_64 PREFIX=/usr/local/haproxy USE_LINUX_TPROXY=1
make install PREFIX=/usr/local/haproxy
// 创建conf配置文件夹
mkdir -p /usr/local/haproxy/conf
其中TARGET=linux415,415标识内核版本,可以使用uname -r
查看,如:4.15.14-1.el7.elrepo.x86_64,此时该参数就为linux415
如果返回结果是2.6.28,可以用:TARGET=linux2628
三. 配置
/usr/local/haproxy/conf/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
daemon
defaults
log global
mode tcp
option tcplog
option dontlognull
maxconn 2000
timeout connect 5000
timeout client 500000
timeout server 500000
frontend ssl
mode tcp
bind 0.0.0.0:443
tcp-request inspect-delay 3s
tcp-request content accept if { req.ssl_hello_type 1 }
acl tls req.ssl_hello_type 1
acl has_sni req.ssl_sni -m found
use_backend nginx if tls has_sni
acl ssh_payload payload(0,7) -m bin 5353482d322e30
use_backend openssh if ssh_payload
use_backend openssh if !{ req.ssl_hello_type 1 } { req.len 0 }
backend nginx
mode tcp
server webserver 127.0.0.1:50443
backend openssh
mode tcp
timeout server 3h
server openssh 127.0.0.1:50022
其中
frontend ssl
mode tcp
bind 0.0.0.0:443
监听本地443端口tcp协议
backend nginx
backend openssh
后端有nginx和openssh, nginx工作在本地50443端口tcp协议上,openssh工作在本地50022端口tcp协议上。
那是怎么判断请求是该转发nginx还是openssh的呢?
后端nginx
acl tls req.ssl_hello_type 1
根据请求中ssl_hello_type,判断请求是否是tls
acl has_sni req.ssl_sni -m found
根据请求中ssl_sni,判断请求是否有SNI扩展,SNI(Server Name Indication)是为了解决一个服务器使用多个域名和证书的SSL/TLS扩展。
use_backend nginx if tls has_sni
如果请求同时是tls,且有sni扩展,那么转发后端nginx。
后端openssh
acl ssh_payload payload(0,7) -m bin 5353482d322e30
利用payload来进行判断是否是ssh
use_backend openssh if ssh_payload
use_backend openssh if !{ req.ssl_hello_type 1 } { req.len 0 }
openssh请求的len不会是0
其他判断参数
acl is_http req.payload(0,3) -m bin 474554 504f53 505554 44454c
acl is_ssh req.payload(0,3) -m bin 535348
acl is_rdp req.payload(0,3) -m bin 030000
四. 命令
启动
/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg
五. 结尾
这种转发nginx有个弊端,就是nginx的所有日志获取的ip都是127.0.0.1了,不过可以解决,就是用上面编译带上的tproxy做透明代理,但是很麻烦的样子,目前我还没弄好。
不过4层代理haproxy,还是很牛逼的!!!
参考: