由淺入深寫代理(3) -socks5 代理

本文講的是如何寫一個 socks5 代理,其實 shadowsocks 的代理也是 socks5 協議的,所以 socks5 代理也是本系列教程的一個重點。

首先放出 socks5 協議的 [rfc](ietf.org/rfc/rfc1928.tx),socks5 協議很簡單,SOCKS5 協議並不負責代理伺服器的數據傳輸環節,此協議只是在 C/S 兩端真實交互之間,建立起一條從客戶端到代理伺服器的授信連接。

0x01 sock5 代理結構圖

0x02 socks5 協議分析

認證階段

首先客戶端需要和服務端有個握手認證的過程,可以採用 用戶名/密碼 認證或者無需認證方式。

格式如下 (數字表示位數

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

  • VER 欄位是當前協議的版本號,也就是 5;
  • NMETHODS 欄位是 METHODS 欄位佔用的位元組數;
  • METHODS 欄位的每一個位元組表示一種認證方式,表示客戶端支持的全部認證方式。

0x00: NO AUTHENTICATION REQUIREDn 0x01: GSSAPIn 0x02: USERNAME/PASSWORDn 0x03: to X』7F』 IANA ASSIGNEDn 0x80: to X』FE』 RESERVED FOR PRIVATE METHODSn 0xFF: NO ACCEPTABLE METHODSn

服務端返回格式

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

一般情況下服務端返回兩種情況

0x05 0x00:告訴客戶端採用無認證的方式建立連接;

0x05 0xff:客戶端的任意一種認證方式伺服器都不支持。

舉個例子, 伺服器無需認證的情況如下

client -> server: 0x05 0x01 0x00n server -> client: 0x05 0x00n

連接階段

認證完成,客戶端向服務端發送請求:

+----+-----+-------+------+----------+----------+n |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |n +----+-----+-------+------+----------+----------+n | 1 | 1 | 1 | 1 | Variable | 2 |n +----+-----+-------+------+----------+----------+n

  • CMD 欄位 command 的縮寫:

* 0x01:CONNECT 建立 TCP 連接n * 0x02: BIND 上報反向連接地址n * 0x03:關聯 UDP 請求n

  • RSV 欄位:保留欄位,值為 0x00
  • ATYP 欄位:address type 的縮寫,取值為:

* 0x01:IPv4 n * 0x03:域名n * 0x04:IPv6n

  • DST.ADDR 欄位:destination address 的縮寫,取值隨 ATYP 變化:

* ATYP == 0x01:4 個位元組的 IPv4 地址n * ATYP == 0x03:1 個位元組表示域名長度,緊隨其後的是對應的域名n * ATYP == 0x04:16 個位元組的 IPv6 地址n * DST.PORT 欄位:目的伺服器的埠n

服務端返回格式

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

  • REP 欄位

* X00 succeededn * X01 general SOCKS server failuren * X02 connection not allowed by rulesetn * X03 Network unreachablen * X04 Host unreachablen * X05 Connection refusedn * X06 TTL expiredn * X07 Command not supportedn * X08 Address type not supportedn * X09 to XFF unassignedn

舉個例子,客戶端通過 127.0.0.1:8000 的代理髮送請求

# request: VER CMD RSV ATYP DST.ADDR DST.PORTn client -> server: 0x05 0x01 0x00 0x01 0x7f 0x00 0x00 0x01 0x1f 0x40n # response: VER REP RSV ATYP BND.ADDR BND.PORTn server -> client: 0x05 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x10 0x10n

傳輸階段

接下來就開始傳輸數據,socks5 伺服器只做單純的轉發功能

整個過程如下

# 認證階段n client -> server: 0x05 0x01 0x00n server -> client: 0x05 0x00n # 連接階段n client -> server: 0x05 0x01 0x00 0x03 0x0a bgoogle.com 0x00 0x50n server -> client: 0x05 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x10 0x10n # 傳輸階段n client -> server -> remoten remote -> server -> clientn ... n

下篇教程用代碼實現下 socks5 代理

參考鏈接:

* Shadowsocks 源碼分析--協議與結構

* ietf.org/rfc/rfc1928.tx

* SOCKS5 協議解析 - 莫邪


推薦閱讀:

Python數據分析及可視化實例之文本處理文本相似度(29)
玩點好玩的--知乎全部話題關係可視化(Docker+Flask+Bootstrap+echarts+uWSGI+Nginx)
Python安全工具開發(一) :分散式爬蟲初探

TAG:计算机网络 | socks代理 | Python |