出品|MS08067實驗室(www.ms08067.com)
本文作者:Spark(Ms08067內網安全小組成員)
1.概述
Haproxy是一個使用c語言開發的高效能負載均衡代理軟體,提供tcp和http的應用程式代理,免費、快速且可靠。
類似frp,使用一個配置檔案+一個server就可以執行。
優點:
- 大型業務領域應用廣泛
- 支援四層代理(傳輸層)以及七層代理(應用層)
- 支援acl(訪問控制列表),可靈活配置路由
- windows使用cygwin編譯後可執行(可跨平臺)
訪問控制列表(Access Control Lists,ACL)是應用在路由器介面的指令列表,這些指令列表用來告訴路由器哪些資料包可以接受,哪些資料包需要拒絕。
2.配置
官方配置手冊:
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中需要編寫具體的操作,就是轉達到哪個目標的哪個埠。
3.思路
(1) 思路一(通用)
編寫acl規則,在四層(傳輸層)進行負載,根據協議型別進行分發,例如:遇到http流量傳送給http服務,遇到rdp傳送給rdp服務等。
(2) 思路二
編寫acl規則,在七層(應用層)進行負載,判斷應用型別進行分發,例如,遇到http分發到http服務,否則傳送到xxx服務。
4.步驟
以思路一為例:
- 通過wireshark捕獲tpkt(應用層資料傳輸協議)資訊
- 編寫acl規則路由進行流量分發
- 新增後端server
- 原始介面接管
- 完成
4.1 捕獲tpkt
關於tpkt可百度或檢視參考連結
三次握手後,開始應用層資料傳輸。
使用wireshark抓包:
ssh協議:
前三個包為三次握手,第四個包的起始三位,便是我們需要的tpkt,例如ssh為535348。
rdp協議:030000
速查:
協議 | 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 |
4.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上。
5.實驗
- 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日誌:
6.埠重定向
為了不影響正常的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埠轉發規則。
7.參考連結
- https://www.cnblogs.com/readygood/p/9776403.html
- https://blog.csdn.net/qq_28710983/article/details/82194404
- https://wenku.baidu.com/view/9f509844e2bd960591c67723.html?fr=search-1-wk_seaincome
轉載請聯絡作者並註明出處!