Welcome

首页 / 软件开发 / C++ / Socks5代理服务

Socks5代理服务2009-11-08假期的时候把socks5代理的RFC全部读完了,有些体会不敢独享,在这里写出来大家一起评论评论,如有错误敬请提出。

下面假设使用TCP连接方式。首先需要和代理服务器之间建立连接,这里没什么复杂的,简单的connect(serverIP, serverPort)就可以了。连接成功之后,需要使用send()发送命令字,以便确定是否需要验证,下面是RFC里面的命令字格式:

项目版本方式数目连接方式
项目长度111-255
首先"版本"这一项固定是 X"05"(socks version 5),方式数目告诉server究竟提交了几种连接方式的请求,至于连接方式则可以有多个。下面就是方式列表:

连接方式含义
X’00’无需验证,直接继续
X’01’GSSAPI
X’02’需要用户名/密码
X’03’ to X’7F’IANA ASSIGNED
X’80’ to X’FE’保留方式,可以自己灵活选用
X’FF’未包含符合要求的方式
接下来是server的回应:

项目版本允许的连接方式
项目长度11
版本不必说,仍然固定是 X"05",允许的连接方式则是在你提交的众多连接方式中,由server选出一个可以接受的,然后返回来;如果没有,那么返回就是 X"FF"。其中一般用到的就是 X"00"和 X"02"了。它们之间的区别就在于 X"02"方式需要发送用户名/密码,验证通过后的过程则和 X"00"方式没有任何区别。

客户端识别到server返回 X"02"之后,发送下列格式验证字串:

项目VER用户名长度用户名密码长度密码
项目长度111-25511-255
注意:这里的VER有别于上边,固定是 X"01"。用户名/密码最大长度是255。

server端验证完毕后返回结果:

项目VER验证结果
项目长度11
验证结果是 X"00"的话,就表示验证通过,否则都是不过…

接下来的过程一样,就是发送请求命令字了:

项目版本命令字保留地址类型地址端口
项目长度11X"00"1不固定2
版本固定 X"05";命令字分三种: CONNECT X"01",BIND X"02",UDP X"03"。CONNECT就是普通的TCP连接;BIND要求你的client支持接受server的连接请求(FTP协议就是一个典型的例子);UDP则是一个特例,我还没有完全理解… 保留项固定是 X"00"。

地址类型有三种:X"01"、X"03"、X"04",分别对应IP-V4、DOMAINNAME、IP-V6,而接下来的地址长度也根据地址类型的不同而变化。IP-V4的长度是4位,DOMAINNAME的长度则根据实际情况变化,但是地址的第一位的内容要设成域名字符串的长度,IP-V6就是16位。

端口长度固定两位,没什么可说的。

而server返回的内容格式也大致相同

项目版本返回值保留地址类型地址(BND)端口
项目长度11X"00"1不固定2
返回值可能是下列值中的一个:

连接方式含义
X’00’成功
X’01’general SOCKS server failure
X’02’连接不符合server规格
X’03’目标网络无法到达
X’04’目标主机无法到达
X’05’连接拒绝
X’06’TTL expired
X’07’命令不支持
X’08’地址格式不支持
X’09 to X’FF’保留