一文打盡埠複用 VS Haproxy埠複用

Ms08067安全實驗室發表於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協議:

一文打盡埠複用 VS Haproxy埠複用

  前三個包為三次握手,第四個包的起始三位,便是我們需要的tpkt,例如ssh為535348。
rdp協議:030000

一文打盡埠複用 VS Haproxy埠複用

速查:

協議 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埠
一文打盡埠複用 VS Haproxy埠複用 一文打盡埠複用 VS Haproxy埠複用
  • Target2:Win7 x64
  • IP:192.168.213.129
  • 開啟3389埠
一文打盡埠複用 VS Haproxy埠複用

  啟動haproxy,-f 指定配置檔案,開啟8888埠表示啟動成功。-d:除錯模式,可不加。

一文打盡埠複用 VS Haproxy埠複用

  HTTP協議:訪問靶機的8888埠,流量被haproxy分發至本機的80。

一文打盡埠複用 VS Haproxy埠複用

  RDP協議:訪問靶機的8888埠,流量被haproxy分發至192.168.213.129的3389。

一文打盡埠複用 VS Haproxy埠複用

  SSH協議:訪問靶機的8888埠,流量被haproxy分發至本機的22。

一文打盡埠複用 VS Haproxy埠複用

  haproxy日誌:

一文打盡埠複用 VS 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可以正常訪問:

一文打盡埠複用 VS Haproxy埠複用

  Haproxy日誌有記錄,說明流量由80先到8888,再回到80。

一文打盡埠複用 VS Haproxy埠複用

  Windows:netsh(需要重啟web服務)

netsh interface portproxy add v4tov4 listenport=80 connectport=8888 connectaddress=127.0.0.1

注意:如果在windows下啟用埠重定向,需要在埠啟動前新增netsh埠轉發規則。

7.參考連結

轉載請聯絡作者並註明出處!

相關文章