3-4-13-HAProxy高级功能与配置之端口复用

熊 0 阅读 Linux集群服务

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. 实现步骤

  1. 通过wireshark捕获tpkt(应用层数据传输协议)信息

  2. 编写acl规则路由进行流量分发

  3. 添加后端server

  4. 原始接口接管

  5. 完成

1.1 捕获tpkt

  • ssh协议

    haproxy-multiport-ssh-1

    前三个包为三次握手 , 第四个包的起始三位 , 便是我们需要的tpkt, 例如ssh为535348。

  • rdp协议 :030000

    haproxy-multiport-rdp-1
  • 速查

    协议

    TPKT

    SSH

    535348

    RDP

    030000

    HTTP(GET)

    474554

    HTTP(POS)

    504f53

    HTTP(PUT)

    505554

    HTTP(DEL)

    44454c

    HTTP(OPT)

    4f5054

    HTTP(HEA)

    484541

    HTTP(CON)

    434f4e

    HTTP(TRA)

    545241

    HTTPS

    160301

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上。