一文打盡端口複用 VS Haproxy埠複用
阿新 • • 發佈:2021-02-01
__出品|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.步驟
以思路一為例:
1. 通過wireshark捕獲tpkt(應用層資料傳輸協議)資訊
2. 編寫acl規則路由進行流量分發
3. 新增後端server
4. 原始介面接管
5. 完成
###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
**轉載請聯絡作者並註明出