正向代理 (Forward Proxy) 是一種網絡代理技術,通過它,客戶端的請求首先被發送到代理服務器,再由代理服務器轉發給目標服務器。使用正向代理的主要目的是突破局域網或防火墻的限制、隱藏真實 IP 地址、緩存訪問資源等。正向代理主要支持兩種協議:HTTP 和 HTTPS。
一、HTTP正向代理
1. 原理
HTTP 正向代理的工作流程如下:
- 客戶端發送請求到代理服務器。
- 代理服務器根據請求內容將其轉發到目標服務器。
- 目標服務器返回數據給代理服務器。
- 代理服務器將數據返回給客戶端。
在 HTTP 代理中,數據傳輸是明文的,客戶端和代理服務器之間、代理服務器和目標服務器之間的通訊都沒有加密。這種代理適合于訪問公開的數據資源,但不適用于敏感數據的傳輸。
2. 圖示
Client --> HTTP Proxy Server --> Target Server
3. 示例代碼
以下是一個使用 Golang 實現的簡單 HTTP 正向代理的示例:
package main
import (
"fmt"
"io"
"net/http"
)
func handleRequestAndRedirect(res http.ResponseWriter, req *http.Request) {
// 復制客戶端請求,設置目標 URL
request, err := http.NewRequest(req.Method, req.RequestURI, req.Body)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
request.Header = req.Header
// 發送請求到目標服務器
client := &http.Client{}
resp, err := client.Do(request)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
// 將目標服務器的響應返回給客戶端
for k, v := range resp.Header {
res.Header()[k] = v
}
res.WriteHeader(resp.StatusCode)
io.Copy(res, resp.Body)
}
func main() {
fmt.Println("Starting HTTP Proxy server on :8080")
http.HandleFunc("/", handleRequestAndRedirect)
http.ListenAndServe(":8080", nil)
}
二、HTTPS正向代理
1. 原理
HTTPS 正向代理使用的是 CONNECT 方法來處理加密流量:
- 客戶端發送
CONNECT請求到代理服務器,請求建立一個到目標服務器的 TCP 連接。 - 代理服務器創建到目標服務器的連接并返回連接成功消息。
- 客戶端和目標服務器之間通過代理服務器傳輸加密的數據。
這種方式讓代理服務器無法讀取實際內容,只充當中轉站。
2. 圖示
Client --(CONNECT Tunnel)-- HTTPS Proxy Server --(SSL/TLS Encrypted)-- Target Server
3. 示例代碼
以下是一個支持 HTTPS 的 Golang 正向代理示例:
package main
import (
"crypto/tls"
"fmt"
"io"
"log"
"net"
"net/http"
)
// HTTPS 代理實現的函數
func handleHTTPS(res http.ResponseWriter, req *http.Request) {
// 代理接收到客戶端的 CONNECT 請求
destConn, err := net.Dial("tcp", req.Host)
if err != nil {
http.Error(res, "連接目標服務器失敗", http.StatusServiceUnavailable)
return
}
res.WriteHeader(http.StatusOK)
// 獲取客戶端連接的 TCP 套接字
clientConn, _, err := res.(http.Hijacker).Hijack()
if err != nil {
http.Error(res, "無法劫持連接", http.StatusInternalServerError)
return
}
go transfer(clientConn, destConn)
go transfer(destConn, clientConn)
}
func transfer(destination io.WriteCloser, source io.ReadCloser) {
defer destination.Close()
defer source.Close()
io.Copy(destination, source)
}
func main() {
fmt.Println("Starting HTTPS Proxy server on :8080")
// 設置代理的 HTTPS 處理函數
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodConnect {
handleHTTPS(w, r)
} else {
http.Error(w, "僅支持 CONNECT 請求", http.StatusMethodNotAllowed)
}
})
// 開始監聽并啟動代理服務器
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal("代理啟動失敗:", err)
}
}
三、HTTP 與 HTTPS 正向代理的區別
| 特性 | HTTP 正向代理 | HTTPS 正向代理 |
|---|---|---|
| 通信協議 | HTTP | HTTPS |
| 安全性 | 明文傳輸,數據不加密 | 數據加密傳輸 |
| 數據隱私 | 代理服務器能看到請求內容 | 代理服務器無法看到加密內容 |
| 使用場景 | 用于一般網絡訪問,內容不涉及敏感數據 | 用于敏感信息的訪問,如在線支付和機密數據傳輸 |
| 操作方法 | 直接轉發請求并處理響應 | 使用 CONNECT 方法建立安全隧道 |
在使用正向代理時,特別是涉及敏感信息時,建議優先使用 HTTPS 代理,以確保數據的安全性和隱私性。