SOCKS协议版本5

Network Working Group M. Leech
Request for Comments: 1928 Bell-Northern Research Ltd
Category: Standards Track M. Ganis
International Business Machines
Y. Lee
NEC Systems Laboratory
R. Kuris
Unify Corporation
D. Koblas
Independent Consultant
L. Jones
Hewlett-Packard Company
March 1996

互联网上搜索到SOCKS5协议中文版有不少,但不太适应他们的行文习惯,因此自译一篇留存。基本按照原文直译,部分内容按自己的理解作出行文上的修改。

本备忘录的状态

本文档为互联网社区规定了一个标准的互联网跟踪协议,希望大家可以讨论和建议如何改进。请参考当前版本的《互联网标准》(STD 1),以了解本协议的状态与其中的标准化描述。本备忘录的发布是不受限制的。

致谢

本备忘录描述了本协议上一版本(SOCKS4)的演变。新的协议来自于活跃的讨论与原型实现。关键的贡献者有:Marcus Leech: Bell-Northern Research, David Koblas:Independent Consultant, Ying-Da Lee: NEC Systems Laboratory, LaMontJones: Hewlett-Packard Company, Ron Kuris: Unify Corporation, MattGanis: International Business Machines。

1.介绍

网络防火墙系统的使用日益流行,这种系统有效将公司的内部网络与外部网络(例如英特网)阻隔开来。这些防火墙系统一般在不同网络体之间充当着应用层网关的作用,由它们对TELNET,FTP,SMTP等网络服务提供授权。为了促进全球信息发现,一些更复杂的协议被设计出来,有必要提供一种通用框架,以帮助(使用)这些协议(的流量)安全而透明地穿过防火墙。而在实际工作中,由于服务端与客户端存在于不同的公司网络之间,这些对防火墙的穿透行为还需要控制手段与强力的认证机制。

本协议旨在为使用TCP和UDP的CS结构程序提供一个框架,以帮助他们方便而安全地使用网络防火墙的服务。在概念上,本协议是位于应用层和传输层之间的“垫片层”,因此不提供网络层网关服务,例如ICMP消息的转发。

2.现有做法

目前我们拥有SOCKS协议的版本4,它为基于TCP的CS结构程序(包括TELNET、FTP,以及流行的信息发现协议例如HTTP、WAIS、GOPHER等)提供了不安全的防火墙穿透方案。

新的协议(版本5)扩展了SOCKS4,以支持UDP、强力认证以及通过域名和IPV6寻址。

实现对SOCKS5协议的支持,通常需要重新编译和链接基于TCP的客户端,以使用封装在SOCKS库中的子程序。

注意

除非另有说明,出现在包格式图表中的十进制数字表示相应字段的长度(以八位字节为单位)。如果某个字节必须设置为指定的值,这个值会被以X’hh’ 这样的语法表示(两位十六进制数)。当使用了’Variable’这个词,说明相应字段的长度是变化的,字节数由开头的(一个或两个字节)字段表示,或者由一个数据类型字段表示。

3. 基于TCP的客户端程序

当一个基于TCP的客户端程序希望连接到一个只能透过防火墙访问的对象(由于工程实现的缘由),它必须通过TCP连接到SOCKS服务端监听的SOCKS端口。按照传统,端口号一般为1080。连接成功后,如果有认证方式被启用,客户端将进入认证协商流程,使用被选择的方式进行认证,然后发送一条中继请求。SOCKS服务端将评估认证请求,并决定是否同意建立SOCKS连接。

除非另有说明,出现在包格式图表中的十进制数字表示相应字段的长度(以八位字节为单位)。如果某个字节必须设置为指定的值,这个值会被以X’hh’ 这样的语法表示(两位十六进制数)。当使用了’Variable’这个词,说明相应字段的长度是变化的,字节数由开头的(一个或两个字节)字段表示,或者由一个数据类型字段表示。

客户端向服务端发起连接,并发送一条【版本号/认证方式】选择消息:

VER NMETHODS METHODS
1 1 1 to 255

在本协议中,VER字段需要被设定为X’05’。NMETHODS字段表明了出现在METHODS子弹中的字节数量。

译者注:

VER NMETHODS METHODS
协议版本号(0x05) 支持的认证方式数量 包含了所有支持的认证方式的编号的数组

服务端从METHODS中给出方式里选出一种,并发送一条METHOD(认证方式)选择消息:

VER METHOD
1 1

如果被选择的方式为X’FF’,说明服务端不支持任何一种客户端提供的方式,客户端必须关闭连接。

METHOD字段的可选项如下:

METHOD值 含义
X’00’ 不需要任何认证
X’01’ GSSAPI
X’02’ 账户/密码
X’03’到X’7F’ IANA ASSIGNED
X’80’到X’FE’ 被保留的私人方法
X’FF’ 没有可接受的方法

接下来客户端与服务端将进入被选择的认证方式对应的子流程。

认证方法相关的子流程将会在独立备忘录中被描述。

为协议提供新认证方式支持的开发者应该联系IANA以获得METHOD号码。号码分配文档应该提到现有的METHOD号码列表和和它们相应的协议。

规范的实现必须支持GSSAPI,也应该支持账户/密码的认证方式。

4. 请求消息

一旦认证协商相关的子流程结束,客户端将发送具体的请求消息。如果协商方式包含了以完整性检查和(或)安全性为目的的封装,请求消息必须是以该方式指定的方法封装。

SOCKS请求遵循以下格式:

VER CMD RSV ATYP DST.ADDR DST.PORT
1 1 X’00’ 1 Variable 2

其中:

字段名 含义
VER 协议版本号:X’05’
CMD 指令(SOCKS连接方式)
RSV 保留(置0)
ATYP 地址类型
DST.ADDR 期望的目的地址
DST.PORT 期望的目的端口
指令 取值
CONNECT(连接,如TCP) X’01’
BIND(绑定,如FTP) X’02’
UDP ASSOCIATE X’03’
地址类型 取值
IP V4 X’01’
域名 X’03’
IP V6 X’04’

SOCKS服务端一般将会基于源地址和目的地址评估请求,然后以请求类型对应的回复方式,返回一条或几条回复消息。

5. 地址

ATYP字段指定了地址字段(DST.ADDR,BIND.ADDR)的数据类型:

X’01’

地址类型为IPV4,长度为4个字节。

X’03’

地址类型为完全合格的域名。第一个字节为接下来域名所占的字节数,注意是没有NULL字节作为结束符的。

X’04’

地址类型为IPV6,长度为16字节。

6. 回复

在客户端与SOCKS服务器建立连接之后,它会尽快发送SOCKS请求信息,以及结束认证协商。服务端评估请求,并按以下格式进行回复:

VER REP RSV ATYP BND.ADDR BND.PORT
1 1 X’00’ 1 Variable 2

其中:

字段名 含义
VER 协议版本号:X’05’
REP 回复内容
RSV 保留(置0)
ATYP 地址类型
BND.ADDR 服务器绑定地址
BND.PORT 服务器绑定端口
回复内容 含义
X’00’ 成功
X’01’ SOCKS服务端的一般错误
X’02’ 被连接规则所禁止
X’03’ 网络无法访问
X’04’ 主机无法访问
X’05’ 连接被拒绝
X’06’ TTL超时
X’07’ 指令不支持
X’08’ 地址类型不受支持
X’09’到X’FF’ 未定义
地址类型 取值
IP V4 X’01’
域名 X’03’
IP V6 X’04’

如果被选择的方式包含了目的为认证、完整性和(或)机密性的封装,回复需要被以该方式相应的封装方法进行封装。

CONNECT

当客户端选择CONNECT模式时,服务端的回复消息中,BND.PORT是服务端用来连接目的主机的端口号,同时BND.ADDR是相关的IP地址。被提供的BND.ADDR经常与客户端连接的SOCKS服务器IP不同,因为这些服务器经常是多宿主的(运行在不同的服务器上)。SOCKS服务端会在评估连接请求时综合考虑DST.ADDR、DST.PORT以及客户端的源地址与端口。

BIND

BIND请求被用于需要客户端接受来自服务端请求的协议中。FTP是一个常见的例子,在FTP中,由客户端到服务端的连接被用于指令和状态报告,而服务端到客户端的连接被用于按需求传输数据。

在应用层协议中,客户端侧最好只在已有主要连接使用CONNECT时,使用BIND请求建立次要连接。SOCKS服务器最好在评估BIND请求时考虑DST.ADDR和DST.PORT。

在一个BIND操作中,会有两条回复消息被SOCKS服务端发往客户端。第一条发送于服务端创建和绑定一个新socket之后。BND.PORT字段表示该socket监听的端口号。BND.ADDR表示该socket的IP。客户端一般会利用这些信息来通知(通过主连接或控制连接)服务端程序会合的地址。第二条回复消息只会在预期的连入请求成功或失败后发送。

在第二条回复消息中,BND.PORT和BND.ADDR字段是连接的主机的地址和端口号。

UDP ASSOCIATE

UDP ASSOCIATE请求被用于建立一个会话(以及与之相关的UDP中继过程)用来处理UDP数据报。DST.ADDR和DST.PORT字段指的是客户端期望UDP数据报发往的地址和端口。服务端可能会用这些信息来限定该会话的权限。如果客户端不再需要维持这个UDP会话,客户端必须使用全零的地址和端口号(来告知)。

当请求UDP会话的TCP连接被终止,该UDP会话也会终止。

在针对UDP ASSOCIATE请求的回复中,BND.PORT和BND.ADDR字段标明客户端发送需要被转发的UDP请求时使用的目标地址与端口。

Reply Processing(回复处理)

当一条回复消息表示出错(指REP字段不是X’00’时),SOCKS服务端必须在发送这条消息之后马上关闭该TCP连接。以检测出错误时为基准,不能超过10秒。

如果回复消息表示成功(指REP字段为X’00’时),且请求不是BIND或CONNECT,客户端可以马上开始发送数据。如果认证方式支持以完整性认证保密为目的的封装,数据必须先以指定的方式进行封装。近似地,当发往客户端的数据到达SOCKS服务端,服务端也必须按照指定的方式进行封装。

7. UDP客户端的流程

一个基于UDP的客户端必须将需要被转发的UDP数据报发往指定的端口,该端口由UDP ASSOCIATE请求的回复消息中的BND.PORT告知。如果认证方式提供以认证完整性和(或)保密为目的的封装方法,数据报必须以该方法封装。每个UDP数据报携带一个如下所示的UDP请求头:

RSV FRAG ATYP DST.ADDR DST.PORT DATA
2 1 1 Variable 2 Variable

请求头中字段的含义如下:

字段 含义
RSV 保留(置0)
FRAG 当前帧号
ATYP 地址类型
DST.ADDR 目的地址
DST.PORT 目的端口
DATA 用户数据
地址类型 取值
IP V4 X’01’
域名 X’03’
IP V6 X’04’

当一个UDP中继服务决定转发一个UDP数据报,他不会向请求客户端发送任何通知。近似地,当它不会或不能转发时,它会丢弃数据报。当一个UDP中继服务从远端收到一条转发数据报,它必须按照以上UDP请求头的格式封装该数据报,以及按照认证方式指定的方法封装。

UDP中继服务必须从SOCKS服务端获得将向BND.PORT(来自UDP ASSOCIATE回复消息)发送数据的客户端的IP地址。来自除这个IP地址之外的数据报都必须被丢弃。

FRAG字段表示的是这个数据报是否是某个数据帧中的一部分。在实现中,高位的一个bit表示在帧中的序号,X’00’标明这个数据报是独立的。1到127表示这个帧在帧序列中的位置。每个接收者会建立关于这些帧的重组队列和重组计时器。当计时器超时,重组队列必须丢弃所有帧且重置。正常情况下,一个新的数据报到达,它的FRAG字段会小于该帧序列处理的最高FRAG值。客户端应该尽量避免碎片帧的出现。

实现对碎片帧的支持是一个选项;不支持对碎片帧的支持的实现必须丢弃所有FRAG字段非零的数据报。

SOCKS-aware UDP的程序接口必须报告给UDP数据报一个可用的缓冲区,这个缓冲区应小于操作系统实际给出的空间大小:

ATYP的值 空间大小
X’01’ 10+method_dependent octets smaller
X’03’ 262+method_dependent octets smaller
X’04’ 20+method_dependent octets smaller

8. 安全注意事项

这篇文档阐述了一个穿透IP网络防火墙的应用层协议。这些穿透行为的安全性高度依赖特定实现提供的,在SOCKS客户端服务端协商中选定的,特定的认证方式与封装方法。

认证方式的选择应该由管理员认真考虑后设定。

9. 参考

[1] Koblas, D., “SOCKS”, Proceedings: 1992 Usenix Security Symposium.

Author’s Address

Marcus Leech
Bell-Northern Research Ltd
P.O. Box 3511, Stn. C,
Ottawa, ON
CANADA K1Y 4H7

Phone: (613) 763-9145
EMail: mleech@bnr.ca

发表评论

电子邮件地址不会被公开。 必填项已用*标注