此备忘录( memo )的状态
本文档为Internet社区指定了Internet标准跟踪协议,并请求讨论和改进建议。有关本协议的标准化状态和状态,请参阅当前版本的“互联网官方协议标准”(STD 1),这份备忘录的分发是无限的。
致谢
本备忘录描述了一个协议,该协议是该协议先前版本4[1]的演变。这个新协议源于积极的讨论和原型实现。主要贡献者是:马库斯•利奇:贝尔•北方研究公司,大卫•科布拉斯:独立顾问,英大•李:NEC系统实验室,拉蒙特•琼斯:惠普公司,罗恩•库里斯:联合公司,马特•甘尼斯:国际商业机器。
1. 介绍
网络防火墙的使用,有效地将组织内部网络结构与外部网络(如INTERNET)隔离的系统正变得越来越流行。这些防火墙系统通常充当网络之间的应用层网关,通常提供受控的TELNET、FTP和SMTP访问。随着更为复杂的应用层协议的出现,这些协议旨在促进全球信息发现,因此有必要为这些协议提供一个通用框架,以便透明、安全地穿越防火墙。
此外,还需要 以尽可能细粒度的方式对这种穿越( traversal )防火墙的行为进行强身份验证 。这一要求源于这样一种认识,即客户机-服务器关系出现在各种组织的网络之间,并且这种关系需要控制,并且通常需要进行强身份验证。
本文描述的协议旨在为TCP和UDP域中的客户机-服务器应用程序提供一个框架,以便方便、安全地使用网络防火墙的服务。协议在概念上是应用层和传输层之间的“填充层”,因此不提供网络层网关服务,例如ICMP消息的转发。
2. 现有的做法
目前有一个第4版的SOCKS协议,它为基于TCP的客户机服务器应用程序(包括TELNET、FTP和流行的信息发现协议,如HTTP、WAIS和GOPHER)提供了不安全的防火墙穿越。
这个新协议扩展了SOCKS版本4模型,使其包含UDP,扩展了框架,使其包含了广义强认证方案的规定,扩展了寻址方案,使其包含域名和IPv6地址。
SOCKS协议的实现通常涉及基于TCP的客户端应用程序的重新编译或重新链接,以使用SOCKS库中适当的封装例程。
注意:
- 除非另有说明,数据包格式图中出现的十进制数字表示相应字段的长度,单位为八位字节( Byte );
- 如果给定的八位字节必须具有特定的值,则语法
X'hh'
用于表示该字段中单个八位字节的值;- 当使用 Variable 一词时,它表示对应的字段具有由关联的(一个或两个八位字节)长度字段或数据类型字段定义的可变长度。
3. 基于TCP的客户端的过程
当基于TCP的客户端希望建立到只能通过防火墙访问的对象的连接时(这种确定由实现决定),它必须打开到SOCKS服务器系统上相应SOCKS端口的TCP连接。SOCKS服务通常位于TCP端口1080上。如果连接请求成功,则客户端输入要使用的身份验证方法的协商,使用所选方法进行身份验证,然后发送中继请求。SOCKS服务器评估请求,并建立适当的连接或拒绝它。
除非另有说明,数据包格式图中出现的十进制数字表示相应字段的长度,单位为八位字节( Byte )。如果给定的八位字节必须具有特定的值,则语法X'hh'
用于表示该字段中单个八位字节的值。当使用 Variable 一词时,它表示对应的字段具有由关联的(一个或两个八位字节)长度字段或数据类型字段定义的可变长度。
客户端连接到服务器,并发送版本标识符/方法选择消息:
VER | NMETHODS | METHODS |
---|---|---|
1 | 1 | 1 to 255 |
- 对于此版本的协议, VER 字段设置为
X'05'
; - NMETHODS 字段指示出现在METHODS字段中的方法标识符的数量,例如,NMETHODS 的值为2,表示 METHODS 字段有两个 Byte,每个 Byte 表示一个方法;
服务器从方法中给定的方法之一进行选择,并发送方法选择消息:
VER | METHOD |
---|---|
1 | 1 |
如果服务器选择的方法是X'FF'
,则客户端列出的任何方法都不可接受,并且客户端必须关闭连接。
当前为 METHOD 定义的值如下:
-
X'00'
=> 无需验证 -
X'01'
=> GSSAPI -
X'02'
=> 使用用户名/密码验证 -
X'03'
至X'7F'
=> IANA已分配 -
X'80'
到X'FE'
=> 为私有方法保留 -
X'FF'
=> 没有可接受的方法
然后客户机和服务器进行特定于方法的子协商,与方法相关的子协商的描述出现在单独的备忘录中,本备忘录不详细描述。
此协议的新方法支持的开发人员应联系IANA获取方法号。对于方法编号及其相应协议的当前列表,应参考分配编号文档。
兼容的实现必须支持GSSAPI,并且应该支持用户名/密码身份验证方法。
4. 请求( Requests )
依赖于方法的子协商完成后,客户端将发送请求详细信息。如果协商方法包含用于完整性检查和/或机密性的封装,则这些请求必须封装在依赖于方法的封装中。
SOCKS请求的格式如下:
VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
---|---|---|---|---|---|
1 | 1 | X'00' | 1 | Variable | 2 |
其中:
- 对于此版本的协议, VER 字段设置为
X'05'
; -
CMD:
-
CONNECT =>
X'01'
- BIND =>
X'02'
- UDP ASSOCIATE =>
X'03'
-
CONNECT =>
- RSV => 保留字段
-
ATYP => 表示地址类型,可能的取值如下:
- IPv4地址 =>
X'01'
- 域名 =>
X'03'
- IPv6地址 =>
X'04'
- IPv4地址 =>
- DST.ADDR => 目的地址
- DST.PORT => 目的端口
SOCKS服务器通常根据源地址和目标地址来评估请求,并根据请求类型返回一个或多个回复消息。
5. 寻址( Addressing )
在地址字段( DST.ADDR , BND.ADDR )中,ATYP字段指定该字段中包含的地址类型:
-
X'01'
=> 地址是第IPv4地址,长度为4个八位字节; -
X'03'
=> 地址字段包含完全限定的域名。地址字段的第一个八位字节包含后面名称的八位字节数,没有终止的NUL八位字节; -
X'04'
=> 地址是一个IPv6地址,长度为16个八位字节。
6. 应答( Replies )
SOCKS请求信息由客户机在与SOCKS服务器建立连接并完成身份验证协商后立即发送。服务器评估请求,并返回如下形式的答复:
VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
---|---|---|---|---|---|
1 | 1 | X'00' | 1 | Variable | 2 |
其中:
- 对于此版本的协议, VER 字段设置为
X'05'
; -
REP => 回复字段:
-
X'00'
=> 成功( succeeded ) -
X'01'
=> 一般的SOCKS服务器故障( general SOCKS server failure ) -
X'02'
=> 规则集( ruleset )不允许连接 ( connection not allowed by ruleset ) -
X'03'
=> 网络不可达( Network unreachable ) -
X'04'
=> 主机不可达( Host unreachable ) -
X'05'
=> 连接拒绝( Connection refused ) -
X'06'
=> TTL过期( TTL expired ) -
X'07'
=> 命令不支持( Command not supported ) -
X'08'
=> 不支持的地址类型( Address type not supported ) -
X'09'
~X'FF'
=> 未分配( unassigned )
-
- RSV => 保留字段
-
ATYP => 表示地址类型,可能的取值如下:
- IPv4地址 =>
X'01'
- 域名 =>
X'03'
- IPv6地址 =>
X'04'
- IPv4地址 =>
- BND.ADDR => 服务器绑定地址
- BND.PORT => 网络字节序表示的服务器绑定端口
标记为保留的字段( RSV )必须设置为X'00'
。
如果所选方法包含用于身份验证、完整性和/或机密性的封装,则响应将封装在依赖于方法的封装中。
6.1 CONNECT
在对 CONNECT 的答复中, BND.PORT 包含服务器分配给连接到目标主机的端口号,而 BND.ADDR 包含关联的IP地址。提供的 BND.ADDR 通常不同于客户端用来访问SOCKS服务器的IP地址,因为这些服务器通常是多宿主的。在评估连接请求时,SOCKS服务器将使用 DST.ADDR 和 DST.PORT 以及客户端源地址和端口。
6.2 BIND
绑定请求( BIND request )用于要求客户端接受来自服务器的连接的协议。FTP是一个众所周知的例子,它使用主客户机到服务器的连接来执行命令和状态报告,但是可以使用服务器到客户机的连接来按需传输数据(例如LS、GET、PUT)。
在使用CONNECT建立主连接之后,应用程序协议的客户端将只使用BIND请求来建立辅助连接。预计SOCKS服务器将在评估绑定请求时使用 DST.ADDR 和 DST.PORT 。
在绑定操作期间,SOCKS服务器将向客户端发送两个答复。第一个在服务器创建并绑定新套接字后发送。 BND.PORT 字段包含SOCKS服务器分配给侦听传入连接的端口号。 BND.ADDR 字段包含关联的IP地址。客户端通常使用这些信息通知(通过主连接或控制连接)应用服务器集合地址。第二个应答仅在预期的传入连接成功或失败后发生。
在第二个回复中, BND.PORT 和 BND.ADDR 字段包含连接主机的地址和端口号。
6.3 UDP ASSOCIATE
UDP关联请求用于在UDP中继进程内建立关联以处理UDP数据报。 DST.ADDR 和 DST.PORT 字段包含客户端用于发送关联的UDP数据报的地址和端口。服务器可以使用此信息来限制对关联的访问。如果在UDP关联时客户端不拥有信息,则客户端必须使用所有零的端口号和地址。
当UDP关联请求到达的TCP连接终止时,UDP关联终止。
在对UDP关联请求的答复中, BND.PORT 和 BND.ADDR 字段指示客户端必须在其中发送要中继的UDP请求消息的端口号/地址。
6.4 回复处理( Reply Processing )
当应答( REP 值不是X'00'
)指示失败时,SOCKS服务器必须在发送应答后立即终止TCP连接。检测到导致故障的条件后,此时间不得超过10秒。
如果应答代码( REP 值X'00'
)指示成功,并且请求是绑定或连接,则客户端现在可以开始传递数据。如果选定的身份验证方法出于完整性、身份验证和/或机密性的目的支持封装,则使用依赖于方法的封装来封装数据。类似地,当数据到达客户机的SOCKS服务器时,服务器必须根据使用的身份验证方法封装数据。
7. 基于UDP的客户端的过程
基于UDP的客户端必须将其数据报发送到UDP中继服务器,该服务器位于答复UDP关联请求时 BND.PORT 指示的UDP端口。如果选定的身份验证方法为真实性、完整性和/或机密性提供封装,则必须使用适当的封装来封装数据报。每个UDP数据报都带有一个UDP请求头:
RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
---|---|---|---|---|---|
2 | 1 | 1 | Variable | 2 | Variable |
UDP请求头中的字段含义为:
-
RSV => 保留字段,固定值为
X'0000'
; - FRAG => 当前分片号;
-
ATYP => 表示地址类型,可能的取值如下:
- IPv4地址 =>
X'01'
- 域名 =>
X'03'
- IPv6地址 =>
X'04'
- IPv4地址 =>
- DST.ADDR => 目的地址
- DST.PORT => 目的端口
- DATA => 用户数据
当UDP中继服务器决定中继UDP数据报时,它会以静默方式进行中继,而不会向请求客户端发出任何通知。类似地,它将丢弃不能或不会中继的数据报。当UDP中继服务器从远程主机接收到应答数据报时,它必须使用上述UDP请求头和任何依赖于身份验证方法的封装来封装该数据报。
UDP中继服务器必须从SOCKS服务器获取客户端的预期IP地址,该客户端将数据报发送到应答UDP ASSOCIATE中给定的 BND.PORT 。它必须删除从任何来源IP地址(为特定关联记录的IP地址除外)到达的任何数据报。
FRAG 字段指示此数据报是否是多个片段之一。如果实现,高阶位表示片段序列结束,而 X'00'
值表示此数据报是独立的。介于1和127之间的值表示片段序列中的片段位置。每个接收器都有一个重组队列和一个与这些片段相关联的重组计时器。每当重新组装计时器过期,或者新数据报到达时,如果携带的FRAG字段的值小于为此片段序列处理的最大FRAG值,则必须重新初始化重新组装队列并放弃关联的片段。重新装配计时器必须不少于5秒。建议应用程序尽可能避免碎片化。
碎片的实现是可选的;不支持碎片的实现必须删除碎片字段不是X'00'
的任何数据报。
支持SOCKS的UDP的编程接口必须报告UDP数据报的可用缓冲区空间小于操作系统提供的实际空间:
- 如果 ATYP 是
X'01'
-10+依赖于方法的八位字节更小; - 如果 ATYP 是
X'03'
-262+依赖于方法的八位字节更小; - 如果 ATYP 是
X'04'
-20+依赖于方法的八位字节更小。
8. 安全考虑
本文描述了IP网络防火墙的应用层穿越协议。这种穿越的安全性高度依赖于特定实现中提供的特定身份验证和封装方法,并在SOCKS客户端和SOCKS服务器之间的协商过程中进行选择。
管理员应仔细考虑认证方法的选择。
9. 引用
[1] Koblas, D., "SOCKS", Proceedings: 1992 Usenix Security Symposium.