本文作者:Spark(Ms08067內網安全小組成員)
Haproxy是使用c語言開發的高效能負載平衡代理軟體,提供tcp和http的應用程式代理,免費、快速且可靠。
類似frp,使用一個設定檔 一個server就可以運作。
優點:
大型業務領域應用廣泛
支援四層代理程式(傳輸層)以及七層代理程式(應用層)
支援acl(存取控制清單),可靈活設定路由
windows使用cygwin編譯後可執行(可跨平台)
存取控制清單(Access Control Lists,ACL)是套用在路由器介面的指令列表,這些指令列表用來告訴路由器哪些封包可以接受,哪些封包需要拒絕。
官方設定手冊:https://cbonte.github.io/haproxy-dconv/2.2/configuration.html
設定檔由全域設定和代理程式設定組成:
全域設定(global):定義haproxy程式管理安全性與效能相關的參數
代理程式設定(proxies) :
defaults:為其他組態段提供預設參數,預設組態參數可由下一個"defaults"重新設定
frontend:定義一系列監聽的套接字,這些套接字可接受客戶端請求並與之建立連線
backend:定義"後端"伺服器,前端代理伺服器將會把哭護短的請求調度至這些伺服器
listen:定義監聽的套接字和後端的伺服器,類似於將frontend和backend段放在一起
範例:
global defaults log global mode tcp option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 frontend main mode tcp bind *:8888 option forwardfor except 127.0.0.1 option forwardfor header X‐Real‐IP # 配置acl规则 acl is‐proxy‐now urlp_reg(proxy) ^(http|https|socks5)$ # 分发到对应的backend use_backend socks5 if is‐proxy‐now use_backend http 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
專注於frontend和backend。
Frontend中需要寫acl規則,配置轉送。例如,當http流量來的時候,轉送給web服務;當rdp流量來的時候,轉給rdp服務。
Backend中需要寫具體的操作,就是轉達到哪個目標的哪個連接埠。
寫acl規則,在四層(傳輸層)進行負載,根據協定類型進行分發,例如:遇到http流量傳送給http服務,遇到rdp發送給rdp服務等。
寫acl規則,在七層(應用層)進行負載,判斷應用類型進行分發,例如,遇到http分發到http服務,否則發送到xxx服務。
以思路一為例:
透過wireshark擷取tpkt(應用層資料傳輸協定)資訊
編寫acl規則路由進行流量分發
新增後端server
原始介面接管
完成
三次握手後,開始應用層資料傳輸。
使用wireshark抓包:
ssh協定:
rdp協定:030000
速查:
##TPKT | |
---|---|
#SSH | 535348 |
#RDP | 030000 |
474554 | |
#504f53 | |
505554 | |
44454c | |
4f5054 | |
#484541 |
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上。
Target1:Ubuntu 16.04 x64
IP:192.168.213.128
开启22端口、80端口
Target2:Win7 x64
IP:192.168.213.129
开启3389端口
启动haproxy,-f 指定配置文件,开启8888端口表示启动成功。-d:调试模式,可不加。
HTTP协议:访问靶机的8888端口,流量被haproxy分发至本机的80。
RDP协议:访问靶机的8888端口,流量被haproxy分发至192.168.213.129的3389。
SSH协议:访问靶机的8888端口,流量被haproxy分发至本机的22。
haproxy日志:
为了不影响常规的80端口访问,将输入的80端口流量重定向到8888端口。当用户以正常方式访问80端口时,流量将转发到8888端口,然后由haproxy再次转发回80端口。
Linux:iptables(不需要重启服务)
iptables ‐t nat ‐A PREROUTING ‐i eth0 ‐p tcp ‐‐dport 80 ‐j REDIRECT ‐‐to‐port 8888
访问80可以正常访问:
Haproxy日志有记录,说明流量由80先到8888,再回到80。
Windows:netsh(需要重启web服务)
netsh interface portproxy add v4tov4 listenport=80 connectport=8888 connectaddress=127.0.0.1
注意:如果在windows下启用端口重定向,需要在端口启动前添加netsh端口转发规则。
以上是如何分析Haproxy連接埠復用的詳細內容。更多資訊請關注PHP中文網其他相關文章!