首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

SOCKS5 代理協議完整實作指南:從 RFC 到 C++ 程式碼

     編輯:關於C++

SOCKS5(RFC 1928)是廣泛部署的通用代理協議,支援無驗證、使用者名稱/密碼、GSSAPI 等多種認證機制,並提供 TCP 連線、BIND、UDP 轉發三種命令。本文依照 RFC 流程,逐步拆解協議封包格式、狀態機轉換,並提供可直接編譯的 C++ 實作範例,涵蓋連線建立、方法協商、認證處理、請求轉發、回應解析全流程。

一、協議流程總覽

  1. Client → Server:VER=0x05, NMETHODS, METHODS...
  2. Server → Client:VER=0x05, METHOD(0x00無驗證、0x02帳密、0xFF不支援)
  3. 若 METHOD=0x02:Client → Server 發送帳密子協商(VER=0x01, ULEN, UNAME, PLEN, PASS)
  4. Server → Client:VER=0x01, STATUS(0x00成功)
  5. Client → Server:發送請求命令(CMD=0x01 CONNECT、目標位址類型、位址、埠)
  6. Server → Client:回應結果(REP=0x00成功、綁定位址/埠)
  7. 後續資料透明轉發

二、關鍵封包結構定義

1. 方法協商(Client → Server)

+----+----------+----------+
|VER | NMETHODS | METHODS  |
+----+----------+----------+
| 1  |    1     | 1-255    |
+----+----------+----------+

METHODS 常見值:0x00 無驗證、0x02 帳密、0x80-0xFE 私有擴充。

2. 方法選擇回應(Server → Client)

+----+--------+
|VER | METHOD |
+----+--------+
| 1  |   1    |
+----+--------+

3. 使用者名稱/密碼認證(RFC 1929)

Client→Server: +----+------+----------+------+----------+
                |VER | ULEN | UNAME    | PLEN | PASS     |
                +----+------+----------+------+----------+
                | 1  |  1   | 1-255    |  1   | 1-255    |
                +----+------+----------+------+----------+
Server→Client: +----+--------+
                |VER | STATUS |
                +----+--------+
                | 1  |   1    |
                +----+--------+

注意:此處 VER=0x01,與主協議 0x05 不同。

4. 請求命令

+----+-----+-------+------+----------+----------+
|VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1  |  1  | 0x00  |  1   | Variable |    2     |
+----+-----+-------+------+----------+----------+
  • CMD:0x01 CONNECT、0x02 BIND、0x03 UDP ASSOCIATE
  • ATYP:0x01 IPv4(4 位元組)、0x03 Domain(首位元組長度+名稱)、0x04 IPv6(16 位元組)

5. 伺服器回應

+----+-----+-------+------+----------+----------+
|VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1  |  1  | 0x00  |  1   | Variable |    2     |
+----+-----+-------+------+----------+----------+

REP 常見碼:0x00 成功、0x01 一般失敗、0x02 規則不允許、0x03 網路不可達、0x04 主機不可達、0x05 連線被拒、0x07 指令不支援、0x08 位址類型不支援。

三、C++ 完整實作範例(同步阻塞)

bool CSocks5Proxy::Connect(LPCTSTR szServer, int nPort, LPCTSTR szUser, LPCTSTR szPass) {
    // 1. 建立 TCP 連線至代理伺服器
    if (!m_socket.Connect(szServer, nPort)) return false;

    // 2. 方法協商
    BYTE req[257] = {5}; // VER=5
    req[1] = (szUser && *szUser) ? 2 : 1; // NMETHODS
    req[2] = 0x00;                       // METHOD: NO AUTH
    if (req[1] == 2) req[3] = 0x02;      // METHOD: USER/PASS
    if (!SendPacket(req, 3 + (req[1]==2))) return false;

    BYTE rsp[2];
    if (!RecvPacket(rsp, 2) || rsp[0]!=5 || rsp[1]==0xFF) return false;

    // 3. 帳密認證
    if (rsp[1] == 0x02) {
        if (!szUser || !*szUser) return false;
        int ulen = strlen(szUser), plen = strlen(szPass);
        BYTE auth[513] = {1, (BYTE)ulen};
        memcpy(auth+2, szUser, ulen);
        auth[2+ulen] = (BYTE)plen;
        memcpy(auth+3+ulen, szPass, plen);
        if (!SendPacket(auth, 3+ulen+plen)) return false;
        if (!RecvPacket(rsp, 2) || rsp[0]!=1 || rsp[1]!=0) return false;
    }

    // 4. 發送 CONNECT 請求(這裡僅示範 IPv4)
    BYTE cmd[10] = {5, 1, 0, 1}; // VER=5, CMD=CONNECT, RSV=0, ATYP=IPv4
    DWORD dwIP = inet_addr(m_szTargetIP); // 目標 IP
    WORD  wPort = htons(m_nTargetPort);   // 目標埠
    memcpy(cmd+4, &dwIP, 4);
    memcpy(cmd+8, &wPort, 2);
    if (!SendPacket(cmd, 10)) return false;

    // 5. 解析回應
    BYTE resp[256];
    int n = RecvPacket(resp, 10); // 至少 10 位元組
    if (n < 10 || resp[0]!=5 || resp[1]!=0) return false;

    // 6. 連線成功,進入透明轉發迴圈...
    return true;
}

四、進階主題

  • 非同步 I/O:搭配 WSAAsyncSelect/IOCP 實作高併發代理用戶端。
  • UDP ASSOCIATE:處理 UDP 封包轉發需維護對應表,注意 NAT 穿透。
  • IPv6/域名支援:動態構建 ATYP=0x03/0x04 請求,解析 BND.ADDR 回應。
  • 錯誤重試與逾時:各階段設定 SO_RCVTIMEO/SO_SNDTIMEO,失敗按 REP 碼決定重試策略。

五、總結

SOCKS5 協議結構清晰、擴充性強,掌握其封包格式與狀態機即可實作健壯的代理用戶端。本文提供的同步阻塞範例可作為教學與輕量級應用基礎;生產環境建議採用非同步架構並完善異常處理、日誌記錄與單元測試。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved