3-4-13-HAProxy高级功能与配置之端口复用
TCP协议中 , 主机的IP地址加上端口号作为TCP连接的端点 , 这种端点就叫做套接字(socket)。一般情况下 , 一个socket同一时刻只能由一个应用监听 , 对于只有单个公网IP的主机来说 , 一个对外的端口就是一个socket , 例如常用端口约定的服务:
22:SSH服务
80:HTTP服务
443:HTTPS服务 ...
在某些特殊需求的情况下 , 我们可能需要一个端口同时提供多个服务。
总的来说 , 实现端口共用的思路就好比是Nginx的SNI : 用某个前端程序(类比:Nginx)监听需要共用的对外端口A(类似 : 域名) , 将需要共用的程序(例如:php-fpm、uwsgi)分别监听环路上的不同端口A2、A3(类似于:本地套接字) , 前端程序通过区分特定的包格式(类似 : 域名)将外部发往端口A的数据分别发给端口A2、A3再根据后端响应发回。
因为Nginx提供的Web服务工作在应用层 , 所以反向代理时可以直接通过URI来确定使用哪个后端 ; 而一般工作在传输层的端口复用 , 实际上要解决最主要问题是如何区分复用数据并正确发给处理后端。
如果haproxy实现复用功能 , 有以下两种思路:
编写
acl规则 , 在四层(传输层)进行负载 , 根据协议类型进行分发 , 例如 : 遇到http流量发送给http服务 , 遇到rdp发送给rdp服务等。编写
acl规则 , 在七层(应用层)进行负载 , 判断应用类型进行分发 , 例如 , 遇到http分发到http服务 , 否则发送到xxx服务。
1. 实现步骤
通过
wireshark捕获tpkt(应用层数据传输协议)信息编写
acl规则路由进行流量分发添加后端
server原始接口接管
完成
1.1 捕获tpkt
ssh协议
前三个包为三次握手 , 第四个包的起始三位 , 便是我们需要的
tpkt, 例如ssh为535348。rdp协议 :030000
速查
1.2 ACL规则
global
defaults
timeout connect 5000
timeout client 50000
timeout server 50000
frontend main
mode tcp
bind *:8888
# 重点:编写acl规则进行转发
tcp‐request inspect‐delay 3s
acl is_http req.payload(0,3) ‐m bin 474554 504f53 505554 44454c 4f5054 484541 434f4e 545241
acl is_ssh req.payload(0,3) ‐m bin 535348
acl is_rdp req.payload(0,3) ‐m bin 030000
# 设置四层允许通过
tcp‐request content accept if is_http
tcp‐request content accept if is_ssh
tcp‐request content accept if is_rdp
tcp‐request content accept
# 分发到对应的backend
use_backend http if is_http
use_backend ssh if is_ssh
use_backend rdp if is_rdp
use_backend socks5
backend socks5
mode tcp
timeout server 1h
server ss 127.0.0.1:50000
backend http
mode tcp
server http 127.0.0.1:80
backend ssh
mode tcp
server ssh 127.0.0.1:22
backend rdp
mode tcp
server rdp 192.168.213.129:3389该配置文件的功能是监听8888端口 , 将http流量(速查表中http协议的8种tpkt)转发到本地的80上 , 将ssh流量转发到本地的22端口上 , 将rdp流量转发到另一主机的3389上。