SSH中文文档
SSH 一项创建在应用层和传输层基础上的安全协议,用于替代安全性差的TELNET,加密安全登陆用。
SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。通过SSH可以对所有传输的数据进行加密,也能够防止DNS欺骗和IP欺骗。
SSH之另一项优点为其传输的数据可以是经过压缩的,所以可以加快传输的速度。SSH有很多功能,它既可以代替Telnet,又可以为FTP、POP、甚至为PPP提供一个安全的“通道”。…
这个文件规定了互联网社区的Internet标准跟踪协议,并请求讨论和建议以得到改进。请参考“Internet正式协议标准”(STD1)本协议的标准化程度和状态的当前版本。本文档的发布是不断更新的。
摘要
安全外壳(SSH)协议是在不安全网络上提供安全的远程登录和其他网络服务的协议,这个文档描述了SSH协议的体系结构, 以及在SSH协议文件中使用的符号和术语. 它还讨论了SSH算法的命名系统,支持本地扩展(比如用户自定义算法、客户自定义密钥规则、高层扩展功能性应用协议). SSH协议包括三个主要组件:传输层协议
提供服务器认证,数据机密性,信息完整性等的支持。用户认证协议
为服务器提供客户端的身份鉴别。连接协议
将加密的信息隧道复用成若干个逻辑通道,提供给更高层的应用协议使用。 这些协议的细节被描述在单独的文件中。
简介
SSH(Security Shell)是在不安全的网络上进行安全远程登录和其他安全网络服务的协议。
它由三个主要部分组成:
○ 传输层协议[SSH-TRANS]提供服务器验证、保密性和完整性。它也可选的提供压缩。传输
层一般运行在一个TCP/IP连接上,但也可能被用在任何其他可靠的数据流上。
○ 验证协议[SSH-USERAUTH]向服务器验证客户端用户。它运行在传输层协议上。
○ 连接协议[SSH-CONNECT]将加密隧道复用为若干逻辑信道。它运行在验证协议上。
在一个安全的传输层连接被建立后,客户端发送一个服务请求。在用户验证完成后,第二个服务请求被发出。这允许新的协议被定义并与上述协议共存。
连接协议提供的信道可被用于广泛的目的。提供了标准方法用于建立安全的交互式shell 进程以及转发(隧道)任意TCP/IP 端口和X11 连接。
本文中的惯用约定
所有与SSH协议相关的文档都应使用关键词“必须”、“禁止(绝不能)”、“必须的”、“应”、“不应”、“推荐”、“可(能)”、“可选的”来描述要求。这些关键词的含义符合[RFC2119]的描述。
本文中用于描述命名空间分配的关键词”PRIVATE USE”、”HIERARCHICAL ALLOCATION”、
“FIRST COME FIRST SERVED”、 “EXPERT REVIEW”、”SPECIFICATION REQUIRED”、
“IESG APPROVAL”、”IETF CONSENSUS”以及”STANDARDS ACTION”的含义符合[RFC2434]
的描述。
协议文档中定义了协议域和可能的取值。协议域将在消息定义中定义。例如,
SSH_MSG_CHANNEL_DATA 的定义如下:
byte SSH_MSG_CHANNEL_DATA
uint32 recipient channel
string data
在整套协议文档中,当引用域时,域的名称出现在单引号中。当引用域的值时,它们出现在双引号中。例如,’data’的可能取值是”foo”和”bar”。
架构
主机密钥
每一个服务器主机应有一个主机密钥。主机可有多个使用不同算法的主机密钥。多个主机可共享相同的主机密钥。如果主机具有密钥,那么对每一种必须的公钥算法(DSS)必须有至少一个密钥。
服务器主机密钥在密钥交换中用于检验客户端真的是在和正确的服务器对话。为使之可能,客户端必须事先知道服务器主机密钥的公钥。
两个不同的信任模型可被使用:
○ 客户端有一个本地的数据库,将每个主机名(与用户输入相同)与对应的主机密钥公钥关联起来。这种方法不需要集中管理的基础架构或第三方的配合。缺点是主机名-密钥关联数据库的维护可能成为一个负担。
○ 主机名-密钥关联由一个可信的认证机构(CA)证明。客户端只知道CA 根密钥,并且能够检验所有由CA 认证的主机密钥的有效性。第二种方式消除了维护问题,因为理想的只有一个CA 密钥需要被安全的保存在客户端。但另一方面,在进行验证前,每个主机密钥必须被一个中心机构以适当的方式认证。同时,中心基础架构被寄予了极大的信任。
协议提供提供了这种选项:在第一次连接到主机时不检查服务器名-主机密钥的关联。这允许在事先不知道主机密钥或证书的情况下进行通信。连接仍然提供对被动侦听(passive listening)的保护;但是,它容易受到主动的中间人攻击(active man-in-the-middle attacks)。系统实现正常情况不应默认的允许这种连接,因其造成潜在的安全问题。但是,
由于在撰写本文时互联网上没有一个被广泛部署的密钥基础架构,这一选项使协议在这种基础架构出现前的过渡时期内的可用性大幅提高,同时仍然提供了比旧的解决方案(如 telnet 和rlogin)高得多的安全性。
系统实现应尽量检查主机密钥。一个可能的策略是:只有当第一次连接到一个主机时才不经检查的接受主机密钥,把密钥保存到本地数据库,在将来所有的到该主机的连接中都以此为基准进行对比。
系统实现可提供附加的方法来检验主机密钥的正确性,例如,通过SHA-1 哈希从公钥产生一个十六进制的数字指纹。这种数字指纹能够很容易的用电话或其他外部通信通道来检验。
所有系统实现应提供一个选项:不接受不能被检验的主机密钥。
本工作组的成员相信“易用”是终端用户接受安全解决方案的关键,如果新的解决方案没有并采用,就不会带来任何安全性的提高。因此,提供不检查服务器主机密钥的选项提高了Internet整体的安全性,尽管在允许该选项的设置中它降低了协议的安全性。
扩展性
我们相信协议将会随时间演化,一些组织将希望使用它们自己的加密、验证及/或密钥交互方法。
对所有扩展进行集中注册是繁琐的,特别对于试验性或保密的特性。另一方面,没有集中注册会导致方法标识符冲突,影响互操作性。
我们选择通过特定格式的名称来标识算法、方法、格式和扩展协议。DNS 名称被用于创建本地命名空间,在其中可定义试验性或保密的扩展而不用担心与其他系统实现相冲突。
一个设计目标是保持基础协议尽可能简单,并且要求尽可能少的算法。但是,所有系统实现必须支持一个昀小的算法集合以保证互操作性(这不表示所有主机上的本地策略要允许这些算法)。
强制性的算法在相关协议文档中规定。
附加的算法、方法、格式和扩展协议可在单独的文档中定义。参见第6 节,算法命名。
策略问题
协议允许对加密、完整性、密钥交换、压缩以及公钥算法和格式进行完整的协商。两个传输方向的加密、完整性、公钥和压缩算法可以不同。
下列策略问题应在系统实现的配置机制中被解决:
○ 每个传输方向的加密、完整性和压缩算法。策略必须规定哪一个是优选算法(例如,在每个类别下列出的第一个算法)。
○ 主机验证使用的公钥算法和密钥交换方法。已存在的使用不同算法的受信任的主机密钥也影响这一选择。
○ 服务器对每个用户要求的验证方法。服务器的策略可对一些或所有用户要求多重认证,要求的算法可依赖于用户试图获得授权时所在的位置。
○ 用户被允许使用连接协议进行的操作。一些问题与安全性有关;例如,策略不应允许服务器在客户机上启动进程或运行命令,并且必须不允许连接到验证代理,除非被要求转发这
样的连接。另一些问题,例如谁能够转发那个 TCP/IP 端口,非常明显是本地策略。很多
这样的问题可能涉及穿越或绕过防火墙,并且与本地安全策略互相联系。
安全特性
SSH 协议的主要目的是改善Internet 的安全性。它尝试通过一种容易部署的方式实现该目的,为此,甚至不惜牺牲绝对安全。
○ 所使用的所有加密、完整性,以及公钥算法都是广为人知的、成熟的算法。
○ 所有算法都使用从密码学看来合理的密钥长度,即密钥长度被认为能在几十年内提供对昀强的密钥解析攻击的保护。
○ 所有算法都透过协商,在某些算法失效的情况下,可以容易的切换到其他算法而不需要修改基础协议。
为了使大范围、快速的部署容易实现,协议做了特定的妥协。具体而言,在验证服务器主机密钥确实属于目标主机方面,协议允许不进行验证,但这是不推荐的。这被认为在短期内能够显著的改善协议的可用性,直到出现普及的Internet 公钥基础架构。
本地化和字符集支持
在大多数情况下,SSH协议不直接传递会显示给用户的文本。但是,有些情况下这种数据可能被传递。当可应用时,数据的字符集必须被显式的规定。在绝大多数情况下,使用的是ISO-10646 UTF-8 编码[RFC3629]。当可应用时,也供了一个字段用于语言标志。
一个重要的问题是交互式进程的字符集。这个问题没有清晰的解决方案,因为不同的应用软件可能用不同的格式显示数据。客户端也可能使用不同类型的终端仿真,所要使用的字符集实际上是由终端仿真决定的。其结果是,没有为直接规定终端进程数据的字符集或编码提供位置。但是,终端仿真类型(例如,”vt100”)被传送到远端,它隐式的规定了字符集和编码。应用软件通常使用终端类型来决定使用什么字符集,或者字符集由一些外部方法来决定。终端仿真也可能允许设置缺省字符集。在任何情况下,终端进程的字符集被认为主要是一个客户端本地问题。
用于识别算法或协议的内部名称一般不会显示给用户,而且必须采用US-ASCII。
客户端和服务器用户名固有的受到服务器可接受名称的约束。它们可能有时出现在日志、报告等位置。它们必须使用ISO-10646 UTF-8 编码,但在一些情况下可能要求其他编码。由服务器决定如何将用户名称与已接受的用户名称对应起来。推荐使用直接的比特式、二进制比较。
为了本地化,协议尝试尽量减少传送的文本消息的数量。当出现时,这些消息通常与错误、除错信息或一些外部配置数据相关。对一般情况下需显示出来的数据,应使用一个数字编码使得用一个本地化的消息代替被传送的消息成为可能。文本消息应可配置。
SSH 协议使用的数据类型表示法
byte
byte 标识任意一个8 位值(8 位字节)。固定长度的数据有时被表示为一个字节数组,写
作byte[n],其中n 是数组中字节的数量。
boolean
一个布尔值作为一个字节存储。0 表示FALSE,1 表示TRUE。所有非零的值必须被解释为
TRUE;但是,应用软件禁止储存除0和1 以外的值。
uint32
表示一个 32 位无符号整数。按重要性降序(网络字节顺序)储存为 4 个字节。例如,
uint64
表示一个64位无符号整数。按重要性降序(网络字节顺序)储存为8 个字节。
string
任意长度二进制字符串。字符串用于装载任意二进制数据,包括空字符和 8 位字符。字符
串被储存为1个包含其长度(后续字节数量)的uint32 以及0(=空字符串)或作为字符
串的值的更多的字节。不使用终结符(空字符)。
字符串也被用来存储文本。在这种情况下,内部名称使用 US-ASCII,可能显示给用户的
文本使用 ISO-10646 UTF-8。终结符(空字符)一般不应被保存在字符串中。例如,
US-ASCII 字符串”testing”被表示为00 00 00 07 t e s t i n g。UTF-8 映射不
改变US-ASCII 字符的编码。
mpint
表示二进制补码(two’s complement)格式的多精度整数,存储为一个字符串,每字节
8 位,从高位到低位(MSB first)。负数的数据区的首字节的昀高位( the most
significant bit)的值为1。对于正数,如果昀高位将被置为 1,则必须在前面加一个
值为0 的字节。禁止包含值为0 或255 的非必要的前导字节(leading bytes)。零必
须被存储为具有0 个字节的数据的字符串。
例:
value (hex) representation (hex)
----------- -------------------
0 00 00 00 00
9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7
80 00 00 00 02 00 80
-1234 00 00 00 02 ed cc
-deadbeef 00 00 00 05 ff 21 52 41 11
name-list
一个包含逗号分隔的名称列表的字符串。名称列表表示为一个含有其长度(后续字节数量)
的uint32,加上一个包含0 或多个逗号分隔的名称的列表。名称的长度禁止为0,并且禁
止包含逗号(“,”)。由于这是一个名称列表,所有被包含的元素都是名称并且必须使用
US-ASCII。上下文可能对名称有附加的限制。例如,名称列表中的名称可能必须是一系列
有效的算法标识,或一系列[RFC3066]语言标识。名称列表中名称的顺序可能有也可能没
有意义。这取决于使用列表时的上下文。对单个名称或整个列表都禁止使用终结字符(空
字符)。
例:
value representation (hex)
----- -------------------
(),空名称列表 00 00 00 00
("zlib") 00 00 00 04 7a 6c 69 62
("zlib,none") 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65
算法和方法命名
SSH 协议使用名称引用特定的哈希、加密、完整性、压缩和密钥交换算法或方法。有一些标准算法和方法是所有系统实现都必须支持的。也有一些算法和方法在协议规定中定义了,但是是可选的。此外,预期有一些组织将希望使用它们自有的算法或方法。
在本协议中,所有算法和方法的标识必须是由可打印的 US-ASCII 字符组成的非空字符串,长度不大于64字符。名称必须是大小写敏感的。
算法和方法名称有两种格式:
○ 不含at 符号(“@”)的名称为了等待IETF CONSENSUS(Internet 工程任务组指派)而
保留。例如”3des-cbc”、 “sha-1”、”hmac-sha1”和”zlib”(双引号不是名称的一部
分)。这种格式的名称必须在IANA (Internet 号码分配局)注册后才有效。注册的名称
禁止包含at符号(“@”)、逗号(“,”)、空格、控制字符(ASCII码32 及以下)或ASCII
码127(DEL)。名称是大小写敏感的,并且长度禁止超过64字符。
○ 任何人都可以使用符合 [email protected] 格式的名称定义附加的算法或方法,例如,
“[email protected]”。at 符号前的部分的格式没有规定,但必须是可打印
的ASCII 字符串,而且禁止包含逗号(“,”)、空格、控制字符(ASCII 码32 及以下)或
ASCII 码127(DEL) 。它必须仅有一个at 符号。at 符号后的部分必须是一个由定义该名
称的人或组织控制的有效的、完全合格的域名[RFC1034]。名称是大小写敏感的,并且长
度禁止超过64 字符。如何管理本地命名空间取决于各个域。应说明的是,这里的名称看起
来与 email 地址 STD 11 [RFC0822]一样。这纯属巧合,并且与 STD 11 [RFC0822]
没有任何关系。
消息编号
SSH 数据包的消息编号从1到255。这些编号的分配如下:
传输层协议:
1 to 19 传输层通用(例如,断开连接、忽略、除错等)
20 to 29 算法协商
30 to 49 密钥交换方法规定(编号可被重用于不同的交换方法)
验证协议:
50 to 59 用户验证通用
60 to 79 用户验证方法规定(编号可被重用于不同的验证方法)
连接协议:
80 to 89 连接协议通用
90 to 127 信道相关消息
为客户端协议保留:
128 to 191 保留
本地扩展::
192 to 255 本地扩展
IANA 考虑
对[SSH-ARCH]、[SSH-TRANS]、[SSH-USERAUTH]和[SSH-CONNECT]定义的SSH协议的IANA指引详见[SSH-NUMBERS]。以下是一个简单的总结,但注意[SSH-NUMBERS]包含对IANA的实际指引,该指引将来可能被新的内容取代。
在SSH协议中,对下列类型的名称的分配由IETF CONSENSUS指定:
○ 服务名称
* 验证方法
* 连接协议信道名称
* 连接协议全局请求名称
* 连接协议信道请求名称
○ 密钥交换方法名称
○ 指定的算法名称
* 加密算法名称
* MAC算法名称
* 公钥算法名称
* 压缩算法名称
这些名称必须为可打印的US-ASCII字串,而且禁止包含at符号(”@”)、逗号(”,”)、空格、控制字符(ASCII码32及以下)或ASCII码127(DEL)。名称是大小写敏感的,而且长度禁止超过64字符。
含有at符号(”@”)的名称是本地定义的扩展,不由IANA控制。
上面列出的每一个名称类别具有一个独立的命名空间。但是,应避免在多个类别中使用相同的名称以尽量避免混淆。
0至191范围内的消息编号(见第7节)是通过IETF CONSENSUS分配的,见[RFC2434]。191至255范围内的消息编号(本地扩展)为PRIVATE USE预留,同样见[RFC2434]。
安全性考虑
为了让全部的安全性考虑更加易懂,在这里集中了传输、验证和连接文档的安全性考虑。
传输层协议[SSH-TRANS]提供了一个在不安全的网络上的机密的信道。它执行服务器主机验证、密钥交换、加密,以及完整性保护。它也形成一个唯一的会话id,可被更上层协议使用。
认证协议[SSH-USERAUTH]提供了一套可用于向服务器验证客户端用户的机制。验证协议规定的各个机制使用传输层协议提供的会话id,并/或依赖传输层协议的安全性和完整性保障。
连接协议[SSH-CONNECT]规定了一种多路复用机制,用于在机密的、已验证的传输上实现多个数据流(信道)。它也规定了使用交互式命令解释程序(shell)的信道、通过端口转发在安全传输上实现各种外部协议(包括任意 TCP/IP 协议)的信道,以及使用服务器主机上的安全子系统的信道。
伪随机数生成
本协议在用于产生会话密钥的哈希值中包含随机的、对应特定会话的数据,从而将每个会话密钥
与会话绑定。应特别注意保证所有随机数具有良好的质量。如果这里的随机数据(例如,
DiffieHellman 参数)是伪随机的,那么伪随机数发生器应是密码学上安全的(例如,它的下
一个输出不能被轻易的猜测出来,即使知道之前所有的输出),而且,适当的熵需要被加入伪随机数发生器。[RFC4086]提供了随机数和熵来源的建议。实现者(Implementers)应注意到对熵的重要性和对正确实现伪随机数生成公式的困难程度的善意的警告。
能够提供给客户端或服务器的熵可能有时达不到需要的量。在这种情况下,必须在熵不足的情况下继续使用伪随机数发生器,或者拒绝运行协议。后者是更值得推荐的做法。
控制字符筛选
当向用户显示文本时,例如错误或除错消息,客户端软件应将任何控制字符(除制表符、回车、换行以外)替换为安全的序列以避免通过发送终端控制字符的攻击。
传输
机密性
分析或推荐除已经成熟并被业界接受的加密器之外的特定的加密器,超出了本文和本工作组的范围。在撰写本文时,普遍使用的加密器包括3DES、ARCFOUR、twofish、serpent 和blowfish。
AES 已由美国联邦信息处理标准发布为[FIPS-197],并且密码学界也已接受 AES。像通常一样,实现者和用户应查阅当前的文献以保证产品使用的加密器中没有被发现新的脆弱点。实现者也应检查哪些加密器被认为相对较强,并应向用户推荐使用这些较强的加密器。当选择了一个较弱的加密器时,产品可以礼貌的、不突兀的告知用户一个更强的算法是有效的并应被使用,这应被视为一种良好的特性。
“无”这种加密器被提供用于除错并且不应被用于其他用途。它的密码学特性在[RFC2410]中
得到了充分的描述,显示出它不符合本协议的目的。
在当前的文献中也可以找到这些和其他加密器的优缺点。[SCHNEIER]和[KAUFMAN]这两个参
考文献可以提供该主题的信息。这两个参考文献都描述了特定加密器的加密块链接模式
以及该模式的弱点。实质上,由于数据序列的开头的高可预测性,这种模式理论上对选
择密文攻击(chosen cipher-text attack)是脆弱的。但是,这种攻击被认为是困难和并
非完全可预测的,特别是当使用的数据块大小相对较大时。
此外,另一种 CBC 模式攻击可以使用插入包含 SSH_MSG_IGNORE 的数据包的方法来缓和。不使用这种技巧,一种特定的攻击可能成功。这种攻击(通常称为 Rogaway 攻[ROGAWAY]、 [DAI]、[BELLARE])要生效,攻击者需要知道将被加密的下一个数据块的初始向量(IV)。在CBC 模式下,它就是对上一个数据块加密的输出。如果攻击者还没有任何办法查看数据包(即,它是在 SSH 系统实现的内部缓冲区甚至内核中),那么这种攻击不会生效。如果上一个数据包已经被发送到网络(即,攻击者可获取它),那么他能够使用这种攻击。
在理想的情况下,实现者仅当数据包被发送到网络并且没有其他数据包等待传送时,才需要添加一个额外的数据包。实现者可能希望检查还有没有等待发送的数据包;不幸的是,从内核或缓冲区中获取该信息一般并不容易。如果没有未发送的数据包,那么一个包含SSH_MSG_IGNORE 的数据包应被发送。如果每次攻击者知道下一个数据包假定使用的IV时,都向数据流中添加一个新的数据包,那么攻击者将不能猜到正确的IV,这样攻击永远不会成功。
作为一个例子,考虑以下情况:
Client Server
------ ------
TCP(seq=x, len=500) ---->
contains Record 1
[500 ms passes, no ACK]
TCP(seq=x, len=1000) ---->
contains Records 1,2
ACK
1. 发包优化算法(Nagle algorithm)+TCP 重发意味着两个记录被合并为一个TCP 片段。
2. 记录2 不在TCP 片段的开头,而且永远也不会,因为它获得了应答(ACK)。
3. 然而,攻击是可能的,因为记录1 已经被发出了。
这个例子指出,用 TCP 缓冲区中是否存在未清除的数据作为是否需要一个空数据包的条件是不
安全的,因为当第二个write()被执行时,缓冲区将包含没有获得应答的记录1。
另一方面,如下情况是完全安全的:
Client Server
------ ------
TCP(seq=x, len=500) ---->
contains SSH_MSG_IGNORE
TCP(seq=y, len=500) ---->
contains Data
假定第二个SSH 记录的IV 在数据包的数据确定下来时就固定了,那么应执行以下步骤:
读取用户输入(read from user)
加密空数据包(encrypt null packet)
加密数据包(encrypt data packet)
数据完整性
本协议确实允许数据完整性机制被禁用。实现者为除错之外的目的使用这个特性时应特别谨慎。
当”none”类型的MAC(数据校验码)被启用时,应向用户和管理员显式的发出警告。
只要”none”类型的MAC没有被使用,本协议提供数据完整性。
由于MAC 使用一个32 位的序号(sequence number),它在发送了2**32 个数据包后可能
开始泄漏信息。但是,根据推荐来更新密钥应可防止这种攻击。传输协议[SSH-TRANS]推荐在1G 字节的数据后更新密钥,可能的昀小的数据包是 16 字节。因此,昀多在 2**28 个数据包后就应更新密钥。
重放
使用除”none”之外的MAC提供了完整性和验证。此外,传输协议提供一个唯一的会话标识(部分与参与算法和密钥交换过程的伪随机数据绑定),它可被高层协议用于将数据与特定的会话绑定,防止之前会话数据的重放。例如,验证协议[SSH-USERAUTH]使用它来防止重放之前会话的签名。由于公钥验证交换是密码学上与会话绑定的(即,绑定到初始密钥交换),它不能在其他会话中被成功的重放。注意,会话id可以被公开而不会损害协议的安全性。
如果两个会话有同样的会话 id(密钥交换的哈希值),那么其中一个会话的数据包能被用于对另一个会话的重放攻击。需要强调,发生这种情况的几率,毋庸置疑的,在使用现代密码学方法时是极小的。在规定较大的哈希函数输出和DH 参数时,更是如此。
在[RFC2085]、[RFC2246]、[RFC2743]、[RFC1964]、[RFC2025]和[RFC4120]中,对
在一些情况下使用单增的序号作为MAC或HMAC 的输入来检测重放进行了描述。[RFC2104]讨论了底层的构造。基本上,每个数据包中的一个不同的序号保证了 MAC 函数的输入中至少该序号是不相同的,从而提供了攻击者无法预测的不重现的 MAC 输出。但是,如果会话保持活动的时间足够长,这个序号将在到达昀大值后从头开始。这可能给攻击者提供了重放一个之前记录的序号相同的数据包的机会,但仅当通讯各方在传输使用该序号的上一个数据包后没有更新密钥的情况下才成立。如果通讯各方更新了密钥,那么重放将由于MAC校验失败而被检测出来。为此,必须强调,通讯各方必须在序号从头开始前更新密钥。自然的,如果攻击者确实尝试在通讯各方更新密钥之前重放一个捕获的数据包,那么这个重复数据包的接收者将不能验证 MAC 的合法性并丢弃该数据包。MAC 失败的原因是,接收者将根据数据包的内容、共享秘密(shared secret)和预期的序号计算一个MAC。由于重放的数据包使用的不是预期的序号(重放的数据包的序号在接受者一方已经过去了),计算得到的MAC 将与从数据包接收到的MAC 不符。
中间人
T本协议对分配主机公钥的基础架构或方法未做假设或规定。预期在某些时候使用本协议时,将不对服务器主机密钥和服务器主机名称的关联进行检验。这种用法对中间人攻击是脆弱的。本节对此进行描述,并劝告管理员和用户理解在初始化任何会话前检验这种关联的重要性。
有三种中间人攻击的情况要考虑。第一种是攻击者在会话初始化之前已将一个设备放置在客户端和服务器之间。在这种情况下,攻击设备试图模仿合法的服务器并会在客户端初始化会话时向客户端提供它的公钥。如果它提供的是服务器的公钥,那么它将无法对合法的服务器和客户端之间的传输进行解密或签名,除非它也获取了主机的私钥。同时,攻击设备也将冒充客户端初始化一个与合法的服务器的会话。如果服务器的公钥在会话初始化之前已被安全的分配给客户端,攻击设备提供给客户端的密钥将与客户端保存的密钥不符。在这种情况下,应警告用户提供的主机密钥与客户端暂存的主机密钥不一致。像 4.1 中描述的一样,用户可被允许接受新的密钥并继续会话。推荐上述警告包含有关客户端设备的足够的信息,以使用户能够做出有根据的决定。如果用户选择使用存储的服务器公钥(而不是在会话开始时提供的公钥)来继续会话,那么由于上面讨论的随机性,客户端-攻击者的会话与攻击者-服务器的会话中会话特有数据将不同。从这一点出发,由于攻击者没有服务器私钥,攻击者将无法对服务器发出的包含会话特有数据的数据包进行正确的签名,因此攻击无法成功。
要考虑的第二种情况与第一种情况相似,也发生在连接时,但这种情况指出需要安全的分配服务器公钥。如果服务器公钥没有被安全的分配,那么客户端无法知道自己是否在与目标服务器对话。攻击者可能使用社会工程(social engineering)技巧将让不知情的用户接受冒充的服务器密钥,然后在合法的服务器和客户端之间放置中间人攻击设备。如果发生这种情况,那么客户端将产生客户端-攻击者会话,攻击者将产生攻击者-服务器会话,攻击者将能够监控和操纵客户端和合法服务器之间的所有传输。服务器管理员昀好提供检查主机密钥指纹的方法,这种方法的安全性不依赖于实际主机密钥的完整性。可能的机制除 4.1 中讨论的之外,还可能包括安全的网页、物理的纸张等。实现者应对如何以昀佳的方式在其系统实现中提供这种机制给出建议。由于本协议是可扩展的,将来对本协议的扩展可能提供更好的机制来解决需要在连接前知道服务器的主机密钥的问题。例如,可能在安全的 DNS 查找(DNS lookup)中提供主机密钥指纹,或在密钥交换中使用GSS-API([RFC1964])上的Kerberos([RFC4120])来验证服务器。
在第三种中间人攻击的情况中,攻击者可能试图在会话建立之后操纵在通讯各方之间传输的数据包。像 9.3.3 描述的那样,以这种方式成功攻击是不大可能的。9.3.3 的推理确实假定 MAC是安全的,并且不可能构造MAC 算法的输入以获得已知的特定的输出。在[RFC2104]的第6 节对此进行了详细得多的讨论。如果 MAC 算法有脆弱性或足够弱,那么攻击者可能指定特定的输入以产生已知的MAC。通过这样,攻击者可能修改传输中的数据包的内容。或者,攻击者可能检阅捕获的数据包的MAC,利用算法的脆弱性或弱点找到共享秘密。在上面的任何一种情况下,攻击者能够构造一个或多个数据包并插入一个 SSH 数据流。为防止这种情况,实现者昀好使用普遍接受的 MAC 算法,管理员昀好关注当前的密码学文献和讨论,以保证没有使用昀近被发现脆弱性或弱点的MAC 算法。
总而言之,在没有对主机和主机密钥建立可靠的绑定的情况下使用本协议在本质上是不安全的,而且是不推荐的。但是,在安全性不是非常关键的环境下,本协议的这种使用可能是必要的,并且仍将提供对被动攻击的保护。本协议和运行在本协议之上的应用程序的实现者应记住这种可能性。
拒绝服务
本协议设计为基于可靠的传输。如果发生传输错误或消息操纵(message manipulation),连接将被断开。如果发生这种情况,应重新建立连接。类似断线器(wire cutter)这种拒绝服务攻击几乎无法避免。
此外,本协议对拒绝服务攻击是脆弱的,因为攻击者能够在不通过验证的情况下迫使服务执行消耗大量 CPU 和内存的连接建立和密钥交换任务。实现者应提供使这种攻击更加困难的特性,例如,只允许有合法用户的那一部分客户端子集的连接。
隐蔽信道
本协议未被设计用于消除隐蔽信道。例如,填充(padding)、SSH_MSG_IGNORE 消息,以及协议中的几个其他位置能被用于传递隐蔽信息,而且接受方没有可靠的方法来检验是否有这种信息正被发送。
前向安全性
需要注意的是,Diffie-Hellman 密钥交换能提供完全前向安全性(PFS)。本质上,PFS 是
一个密钥建立协议的密码学属性,表示会话密钥或长期私钥在一个特定的会话之后泄密,不会造成更早的会话的泄密[ANSI-T1.523-2001]。使用在[SSH-TRANS]中 Diffie-Hellman 密
钥交换一节描述的 Diffie-Hellman 方法(包括”diffie-hellman-group1-sha1”和”diffie-hellman-group14-sha1”)创建的 SSH 会话,即使在私钥/验证资料后来被透露的情况下仍然是安全的,但如果会话密钥被透露则不再安全。因此,对于上述PFS 的定义,SSH确实具备PFS。但是,这个属性不会传递给(commuted to)任何使用SSH作为传输的应用程序或协议。SSH 的传输层提供依赖于秘密数据的密码验证和其他方法。
当然,如果客户端和服务器的DH 私密参数被透露,那么会话密钥被透露了,但是这些内容在密钥交换完成后可被抛弃。值得指出,不应使这些内容昀后处于交换空间,它们应在密钥交换完成后立即被从内存中擦除。
密钥交换方法的顺序
像[SSH-TRANS]中的算法协商一节中陈述的一样,每一个设备将发送一个优先密钥交换方法的列表。首选的方法是列表中的第一个。推荐按密码学强度对算法进行排序,昀强的第一。在[RFC3766]中给出了对此问题的一些额外的指引。
通信量分析
对任何协议的被动侦听可能给攻击者有关会话、用户或协议指定信息的一些通过其他途径无法收集的信息。例如,已显示对SSH 会话的通信量分析能产生有关密码长度的信息—[Openwall]和 [USENIX]。实现者应使用 SSH_MSG_IGNORE 数据包和包含随机长度的填充,以阻止通信量分析的企图。其他方法也可能被发现和实现。
验证协议
本协议的目的是执行客户端用户验证。它假定运行在一个安全的传输层协议上,传输层协议已经验证了服务器、建立了加密的通信信道,并且为会话计算了一个唯一的会话标识。
允许几种具有不同安全特征的验证方法。对每个用户,服务器能接受哪种方法(或方法组合),由服务器的本地策略决定。验证强度不会高于所允许的昀弱的组合。
服务器可在重复多次的不成功的验证尝试后进入一个睡眠期,使关键字检索对攻击者更加困难。应小心使这种机制不会导向自我拒绝服务(selfdenial of service)。
弱连接
如果传输层不提供机密性,依赖秘密数据的验证方法应被禁用。如果传输层不提供强完整性保护,修改验证数据(例如,修改密码)的请求应被禁用,以防止攻击者在不被注意的情况下修改密文,或使新的验证数据不可用(拒绝服务)。
上述假定——验证协议仅在事先验证了服务器的安全的传输上运行——非常重要。提醒部署SSH的人员,如果客户端对于服务器和服务器主机密钥之间没有一个非常强的先验(priori)关联,后果将导致中间人攻击。特别的,对验证协议的情况,客户端可能生成一个到中间人攻击设备的会话并泄漏用户凭证,如用户名和密码。即使在没有用户凭证被泄露的验证中,攻击者还可能通过捕获击键来获取不应有的信息,与蜜罐(honeypot)程序工作的方法基本相同。
除错消息
在设计除错消息时应特别小心。如果设计得不合理,这些消息可能透露的有关主机的信息多得惊人。如果需要高安全性,可在用户验证阶段禁用除错消息。主机管理员应尝试各种方法来划分所有事件通知消息并保护它们不受未经授权的查看。开发人员应对一些正常事件和除错消息本质上的敏感性保持警惕,也可能希望为管理员提供如何防止未授权人员接触这些信息的指引。开发人员应考虑使用户在验证阶段能获得的敏感信息昀小化,与本地策略致。由于这个原因,推荐在部署时禁用除错消息,需要管理员主动进行启用。同时,在管理员启用除错信息时,推荐向其显示一条有关上述内容的消息。
本地安全策略
实现者必须保证提供的凭证验证用户有效,而且必须保证服务器的本地策略允许该用户的访问请求。特别的,由于SSH连接协议的灵活性,在验证时可能无法决定应当应用哪些(如果有的话)本地安全策略,因为在这个时候用户所请求的服务还不确定。例如,本地策略可能允许用户访问服务器上的文件,但不允许启动交互式命令解释程序。但是,在验证协议中,并不知道用户将要访问文件、尝试使用交互式命令解释程序,或两者。在任何事件中,当服务器主机的本地安全策略存在时,它必须被正确的应用和强制实施。
实现者昀好提供一个默认的本地策略,并将其参数告知管理员和用户。实现者可自行决定,默认的策略是顺着“什么都行(anything-goes)”路线,对用户不加任何限制,还是顺着“极端
限制(excessively-restrictive)”路线,让管理员不得不主动对初始默认参数进行修改
以满足他们的需要。或者,也可以尝试为管理员提供实用和立即可用的策略,使他们不必太费力就能让SSH运转起来。无论做出哪种选择,必须按上面的要求应用和强制实施。
公钥验证
使用公钥验证假定客户端主机没有失密。它也假定服务器主机的私钥没有失密。
该风险可以通过在私钥上使用口令句(passphrases)来降低;但是,这不是一个能强制执行的策略。建议使用智能卡或其他技术使口令句成为一个可强制执行的策略。
服务器可同时要求密码和公钥验证;但是,这要求客户端向服务器暴露它的密码(见下一节的密码验证)。
密码验证
密码机制,像验证协议规定的那样,假定服务器没有失密。如果服务器失密,使用密码验证将会把有效的用户名/密码组合显示给攻击者,可能导致进一步的泄密。
该脆弱性可通过使用其他验证方式来减轻。例如,公钥验证并不假定服务器的安全性
基于主机的验证
基于主机的验证假定客户端没有失密。除了组合使用另一种验证方法外,没有降低风险的策略。
连接协议
末端安全性
E连接协议假定了末端安全性。如果服务器失密,在该主机上的任何终端会话、端口转发或系统访问都会失密。对此没有降低风险的因素。
如果客户端已经失密,而且服务器在验证协议中未能阻止攻击者,所有暴露的服务(无论是子系统还是通过映射)对攻击都是脆弱的。实现者应提供机制让管理员可控制暴露哪些服务,以限制其他服务的脆弱性。上述控制可能包括控制哪个机器和端口能在端口转发中作为目标,哪些用户被允许使用交互式命令解释程序,或哪些用户被允许使用暴露的子系统。
代理转发
SSH 连接协议允许对其他协议的代理转发,如SMTP、POP3 和HTTP。对于希望控制物理上外部的用户访问特定应用程序的网络管理员来所,这可能是一个需要考虑的问题。本质上,对这些协议的转发可能违反属于特定位置的(site-specific)安全策略,因为它们可能以探测不到的方式贯通防火墙。实现者应提供一种管理机制来控制代理转发功能,使属于特定位置的安全策略可能维持。
此外,可以使用反向代理转发功能,它也可以被用于绕开防火墙控制。
像上面指出的一样,在代理转发操作中假定了末端安全性。末端安全性失效将使所有经代理转发传递的数据失密
X11 转发
SSH 连接协议提供的另一种形式的代理转发是对 X11 协议的转发。如果末端安全性失效,X11转发可能允许对X11 服务器的攻击。用户和管理员应,理所当然的,使用合理的X11 安全机制来防止未经授权的使用X11 服务器。希望进一步探索X11 的安全机制的实现者、管理员和用户,可参阅[SCHEIFLER]和分析CERT之前报告的SSH转发与X11之间交互的问题VU#363181 和VU#118892[CERT]。
使用SSH的X11 远程显示(display forwarding),就其自身,不足以解决众所周知的X11
安全性问题[VENEMA]。但是,SSH(或其他安全协议)的X11 远程显示,与只接受由许可或访问控制列表(ACL)授权的通过本地进程间通信(IPC)机制连接的实际和虚拟显(actual and pseudo-display)组合,确实解决了很多X11安全性问题,只要没有使用”none”这种MAC。 推荐X11 显示的系统实现默认只允许在本地IPC 上开启显示。推荐支持X11 转发的SSH 服务器的系统实现默认只允许在本地 IPC 上开启显示。在单用户系统上,可能默认允许在 TCP/IP上开启本地显示是合理的。
X11 转发协议的实现者应实现[SSH-CONNECT]中描述的防cookie欺骗机制,作为一种附加机制用于防止在未经授权的情况下使用代理