Socks5


首先说一点, shadowsocks使用的就是 socks5协议

RFC文档

SOCKS Protocol Version 5

Username/Password Authentication for SOCKS V5

介绍

socks5 is designed to provide a framework for client-server applications in both the TCP and UDP domains to conveniently and securely use the services of a network firewall

socks5作为应用层和传输层的中间层不提供传输层以下的服务,比如网络层的ICMP报文是无法通过Socks5协议来进行转发的

当防火墙后的客户端要访问外部的服务器时,就跟socks代理服务器连接。该协议设计之初是为了让有权限的用户可以穿过过防火墙的限制,使得高权限用户可以访问外部资源

Socks5协议通信过程

When a TCP-based client wishes to establish a connection to an object that is reachable only via a firewall (such determination is left up to the implementation), it must open a TCP connection to the appropriate SOCKS port on the SOCKS server system.

现在我们的socks5服务位于TCP1080端口,Client成功与Server建立了TCP连接,这时Client便可以与Server协商认证方法,协商完成之后进行身份认证并发送转接请求,此时只有两种结果:认证成功拒绝请求

Client首先给Server发送的信息格式如下

+----+----------+----------+
|VER | NMETHODS | METHODS  |
+----+----------+----------+
| 1  |    1     | 1 to 255 |
+----+----------+----------+
						1 to 255 表示该字段长度的范围为1~255字节

VER:长度为1byte的版本号

NMETHODS:表示Client提供的认证方法的数量

METHODS:METHODS代号: X'hh'16进制表示

  • X’00’ NO AUTHENTICATION REQUIRED
  • X’01’ GSSAPI
  •         **X'02' USERNAME/PASSWORD**
    
  •         **X'03' to X'7F' IANA ASSIGNED**
    
  •         **X'80' to X'FE' RESERVED FOR PRIVATE METHODS**
    
  •         **X'FF' NO ACCEPTABLE METHODS**
    

Server接收到Client的信息后,返回如下格式的响应消息:

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

METHOD字段表示Server所选定的认证方法,若其值为X'FF',则表示Server什么认证方法都没有指定,此时ClientServer之间的连接会关闭

Socks5身份认证

The client and server then enter a method-specific sub-negotiation

现在我们来查阅Username/Password Authentication for SOCKS V5 RFC 1929

The protocol specification for SOCKS Version 5 specifies a generalized framework for the use of arbitrary authentication
protocols in the initial socks connection setup. This document
describes one of those protocols, as it fits into the SOCKS Version 5
authentication “subnegotiation”
.

Once the SOCKS V5 server has started, and the client has selected the
Username/Password Authentication protocol, the Username/Password
subnegotiation begins

This begins with the client producing a
Username/Password request
,请求报文格式如下:

+----+------+----------+------+----------+
|VER | ULEN |  UNAME   | PLEN |  PASSWD  |
+----+------+----------+------+----------+
| 1  |  1   | 1 to 255 |  1   | 1 to 255 |
+----+------+----------+------+----------+
						1 to 255 表示该字段长度的范围为1~255字节
  • VER:版本号
  • ULEN:用于表示UNAME字段的长度
  • UNAMEusername
  • PLEN:用于表示PASSWD字段的长度
  • PASSWDusername对应的password

The server verifies the supplied UNAME and PASSWD, and sends the
following response:

+----+--------+
|VER | STATUS |
+----+--------+
| 1  |   1    |
+----+--------+

STATUS字段值为X'00',则认证成功,除此之位的任何值均表示failure,此时ClientServer之间的连接将会关闭

这种认证方式是有安全隐患的,用户名和密码都是明文传输的,如果攻击者渗透到了内网,则很容易嗅探到用户名和密码

认证完成之后,ClientServer发送请求包,格式如下:

+----+-----+-------+------+----------+----------+
|VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1  |  1  | X'00' |  1   | Variable |    2     |
+----+-----+-------+------+----------+----------+
  • VER
  •    protocol version: X'05'
    
  •         **CMD**
    
    • CONNECT X’01’
    •           **BIND X'02'**
      
    •            **UDP ASSOCIATE X'03'**
      
  •         **RSV**   
    
    •          RESERVED,置零
      
  •       **ATYP**   (address type of following address)有以下三个值可以选择
    
    •            **IP V4 address: X'01'**
      
    •           **DOMAINNAME: X'03'**
      
    •          **IP V6 address: X'04'**
      
  •        **DST.ADDR**       
    
    •        desired destination address
      
  •        **DST.PORT** 
    
    •        desired destination port in network octet              order
      

稍微提一下上面ATYPDOMAINNAME,如果指定了该选项,则后面的DST.ADDR字段中存放的是FQDN,它的第一个字节表示后面的FQDN占用的字节数,there is no terminating NUL octet*(octet表示8位一组)*

Server对请求进行基于源和目的地址的审核之后会向Client发送一个或者多个响应报文,报文格式如下:

+----+-----+-------+------+----------+----------+
|VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1  |  1  | X'00' |  1   | Variable |    2     |
+----+-----+-------+------+----------+----------+
  • VER
  • protocol version: X’05’
  •        **REP(应答结果)**:
    
    •           X'00' succeeded 
      
      •           X'01' general SOCKS server failure
        
      •           X'02' connection not allowed by ruleset
        
      •           X'03' Network unreachable
        
      •           X'04' Host unreachable
        
      •           X'05' Connection refused
        
      •           X'06' TTL expired
        
      •           X'07' Command not supported
        
      •           X'08' Address type not supported
        
      •           X'09' to X'FF' unassigned
        
  •        **RSV**    **(RESERVED)保留,置零**
    
  • ATYP (address type of following address)
    •           IP V4 address: X'01'
      
    •           DOMAINNAME: X'03'
      
    •           IP V6 address: X'04'
      
  •        **BND.ADDR**       **(server bound address)**
    
  •        **BND.PORT**      **(server bound port in network octet order)**
    

下面我们按照Client请求中CMD的三个值来对响应报文进行讲解:

CONNECT

BND.PORTBND.ADDR的值与Client发给Server的报文中的DST.ADDRDST.PORT字段的值是相等的

Client的源地址和目的地址用来进行请求审核

BIND

The BIND request is used in protocols which require the client to
accept connections from the server. FTP is a well-known example,
which uses the primary client-to-server connection for commands and
status reports, but may use a server-to-client connection for
transferring data
on demand (e.g. LS, GET, PUT)

It is expected that the client side of an application protocol will
use the BIND request only to establish secondary connections after a
primary connection is established using CONNECT

意思是,我们认为Client使用BIND命令的原因只有一个,那就是在使用CONNECT命令建立了第一个连接之后,需要建立第二个连接,就像FTP服务,第一个connection用于命令交互,第二个connection用于传输数据,这时SERVER使用DST.ADDR字段和DST.PORT字段来进行请求的审核

socks服务器作为一个中间人

一头连接Client,这时Server会创建和绑定一个新的socket,并向Client发送第一个响应

另一头连接Client让它去连接的ADDRPORT,当另一头的连接建立成功后,第二个响应会被发送给Client

UDP ASSOCIATE

UDP ASSOCIATE命令通常是要求建立一个UDP中继来处理到来的UDP数据包,数据包中的DST.ADDRDST.PORT字段包含了Client希望用来发送UDP报文的地址和端口号,这样一来,Server就能通过ADDRPORT来限制连接(相对于Server的另一端,就是Client委托Server访问的那一端,不是来自指定地址和端口的报文将不被转发),如果主机没有指定这两个字段的值,将会被填充为0

TCP连接中断的时候,UDP association也会中断,因为它本来就是建立在ClientServerTCP连接之上的

响应过程

X'00'之外的所有响应码都表明了请求失败,发送完响应报文之后Server会中断连接,This must be no more than 10 seconds after detecting the
condition that caused a failure

如果响应报文的REP字段为X'00',则开始转发报文

UDP服务的处理过程

意思就是Client希望Server能帮自己去和远程服务器进行UDP连接

Each UDP datagram carries a UDP request
header with it**(首部格式)**:

+----+------+------+----------+----------+----------+
|RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
+----+------+------+----------+----------+----------+
| 2  |  1   |  1   | Variable |    2     | Variable |
+----+------+------+----------+----------+----------+
  • RSV
    • Reserved X’0000’
  •        **FRAG**    
    
    • X’00’表示没有其余分片,1-127表示它在所有分片中的编号
  •        **ATYP**    **(address type of following addresses)**
    
    •           IP V4 address: X'01'
      
    •           DOMAINNAME: X'03'
      
    •           IP V6 address: X'04'
      
  •        **DST.ADDR**       
    
    • Client委托Server转发的报文的目的地址
  •        **DST.PORT**
    
    • Client委托Server转发的报文的目的端口
  •        **DATA**
    
    •             user data
      

远程UDP服务器需要从SOCKS服务器获得ClientIP,来自其他IP的报文将会被丢弃

每个Client都有一个组装队列,用于组装被分片的UDP报文,同时拥有一个超时定时器,组装工作需要在此时间内完成,否则重装队列会被初始化分片将会被丢弃,or when a new datagram arrives carrying a FRAG field whose value is less
than the highest FRAG value processed for this fragment sequence
.

The reassembly timer MUST be no less than 5 seconds. It is
recommended that fragmentation be avoided by applications wherever
possible.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值