Socks5代理协议详解:从握手到数据传输的全过程
代理百科
<p style="line-height: 2;"><a href="https://www.bitudaili.com/" target="_blank"><span style="color: rgb(9, 109, 217); font-size: 16px;">Socks5代理</span></a><span style="font-size: 16px;">协议由RFC 1928定义,是一种工作在会话层的标准代理协议,通常监听1080端口。它支持TCP与UDP代理、灵活的地址解析以及可扩展的认证机制,被广泛用于内网访问、安全通信等场景。以下将从握手协商开始,逐步剖析其完整工作流程。</span></p><p style="line-height: 2;"><br></p><p style="line-height: 2;"><span style="font-size: 24px;"><strong>版本协商与认证方法选择</strong></span></p><p style="line-height: 2;"><span style="font-size: 16px;">客户端与Socks5服务器建立TCP连接后,首先发送握手报文:1字节版本号(固定0x05),1字节方法数量(n),随后紧接n个字节列出客户端支持的认证方法。常见方法包括0x00(无需认证)、0x02(用户名/密码认证)、0xFF(无可接受方法)。服务器从中选择一种方法,回应2字节:版本号0x05和选定的方法。若返回0xFF,表示协商失败,连接立即关闭;否则进入下一阶段。这一步完成了双方认证方式的统一。</span></p><p style="line-height: 2;"><br></p><p style="line-height: 2;"><span style="font-size: 24px;"><strong>可选的子协商:用户名/密码认证</strong></span></p><p style="line-height: 2;"><span style="font-size: 16px;">若服务器选择0x02,则触发基于RFC 1929的子协商。客户端发送版本0x01,随后依次发送用户名长度(1字节)、用户名、密码长度(1字节)、密码。服务器回复版本0x01和状态码,0x00代表认证成功,其余值均表示失败。认证通过后方可继续。若握手阶段选定0x00,则直接跳过此阶段,转入代理请求。</span></p><p style="line-height: 2;"><br></p><p style="line-height: 2;"><span style="font-size: 24px;"><strong>代理请求:指定目标与命令</strong></span></p><p style="line-height: 2;"><span style="font-size: 16px;">认证完成后,客户端构造详细的请求报文:1字节版本0x05,1字节命令码CMD(0x01为CONNECT建立TCP隧道;0x02为BIND,用于FTP等需要反向连接的场景;0x03为UDP ASSOCIATE建立UDP中继),1字节保留字段RSV(必须为0x00),1字节地址类型ATYP(0x01=IPv4,0x03=域名,0x04=IPv6),其后是变长的目标地址以及2字节的网络字节序目标端口。</span></p><p style="line-height: 2;"><span style="font-size: 16px;">服务器收到后,解析并尝试连接目标,随即回复:版本0x05,应答码REP(0x00成功;其他如0x01一般错误、0x05连接拒绝等),RSV,ATYP,随后是服务器绑定地址BND.ADDR和端口BND.PORT。对于CONNECT命令,客户端可忽略绑定地址,后续直接复用现有TCP连接进行数据收发。若命令为UDP ASSOCIATE,BND.ADDR和BND.PORT则指示UDP中继的实际入口。</span></p><p style="line-height: 2;"><br></p><p style="line-height: 2;"><span style="font-size: 24px;"><strong>数据中继传输</strong></span></p><p style="line-height: 2;"><br></p><p style="line-height: 2;"><span style="font-size: 19px;"><strong>1. TCP CONNECT透明转发</strong></span></p><p style="line-height: 2;"><span style="font-size: 16px;">命令为CONNECT且返回成功后,Socks5服务器在客户端与目标服务器之间建立双向数据管道。此时双方间的TCP流变为纯透明通道,服务器将客户端发来的字节流原样转发至目标,并将目标返回的数据无修改地送回。整个过程无任何额外协议头,直到任一端关闭连接,中继随之终止。</span></p><p style="line-height: 2;"><br></p><p style="line-height: 2;"><span style="font-size: 19px;"><strong>2. UDP ASSOCIATE中继</strong></span></p><p style="line-height: 2;"><span style="font-size: 16px;">若命令为UDP ASSOCIATE,客户端后续发送UDP数据报到服务器分配的UDP端口时,每个报文必须添加Socks5封装头:2字节保留(0x0000)、1字节分片号(当前只允许0x00)、ATYP、目的地址、目的端口,最后携带真正的UDP载荷。服务器解封装后,将裸数据发往指定目标;从目标返回的UDP包,也会被加上相同格式的封装头后转发给客户端,从而完成UDP双向代理。</span></p><p style="line-height: 2;"><span style="font-size: 16px;">BIND命令较为特殊:当客户端需要接受来自目标的连接(如主动模式FTP)时,首先通过BIND让服务器监听一个端口,等目标连接到来时,服务器会发送第二个包含目标实际地址的响应,进而开始中继。</span></p><p style="line-height: 2;"><br></p><p style="line-height: 2;"><span style="font-size: 24px;"><strong>结语</strong></span></p><p style="line-height: 2;"><a href="https://www.bitudaili.com/" target="_blank"><span style="color: rgb(9, 109, 217); font-size: 16px;">Socks5协议</span></a><span style="font-size: 16px;">凭借清晰的握手协商、可选的多重认证、灵活的地址类型以及对TCP/UDP的完整支持,在保证透明中继的同时,还能通过域名解析避免客户端DNS泄露。理解其精确的报文交互过程,对于网络应用开发、安全审计和内网服务代理都有重要价值。</span></p>