9. Security Considerations (安全注意事项)
9. Security Considerations (安全注意事项)
为了使整个安全注意事项更易于访问, 传输,认证和连接文档的安全注意事项已在此处汇集.
传输协议 [SSH-TRANS] 在不安全的网络上提供机密通道.它执行服务器主机认证,密钥交换,加密和完整性保护.它还派生可以由更高级别协议使用的唯一会话 ID (session id).
认证协议 [SSH-USERAUTH] 提供了一套可用于将客户端用户认证到服务器的机制.认证协议中指定的各个机制使用传输协议提供的会话 ID 和/或依赖于传输协议的安全性和完整性保证.
连接协议 [SSH-CONNECT] 指定了一种机制, 用于在机密和已认证的传输上复用多个数据流 (通道, channels).它还指定了用于访问交互式 shell,通过安全传输代理转发各种外部协议 (包括任意 TCP/IP 协议) 以及访问服务器主机上的安全子系统的通道.
9.1 Pseudo-Random Number Generation (伪随机数生成)
此协议通过在用于生成会话密钥的哈希中包含随机的,特定于会话的数据, 将每个会话密钥绑定到会话.应特别注意确保所有随机数都具有良好的质量.如果这里的随机数据 (例如, Diffie-Hellman (DH) 参数) 是伪随机的, 那么伪随机数生成器应该是密码学安全的 (即, 即使知道所有先前的输出, 其下一个输出也不容易猜测), 并且, 此外, 需要向伪随机数生成器添加适当的熵 (entropy).[RFC4086] 提供了关于随机数和熵来源的建议.实现者应该注意熵的重要性以及关于正确实现伪随机数生成函数的难度的善意的,轶事性警告.
给定客户端或服务器可用的熵量有时可能少于所需的量.在这种情况下, 必须要么不顾熵不足而求助于伪随机数生成, 要么拒绝运行协议.后者是更可取的.
9.2 Control Character Filtering (控制字符过滤)
向用户显示文本时, 例如错误或调试消息, 客户端软件应该用安全序列替换任何控制字符 (除了制表符,回车和换行符), 以避免通过发送终端控制字符进行攻击.
9.3 Transport (传输)
9.3.1 Confidentiality (机密性)
分析或推荐特定密码超出了本文档和安全外壳工作组的范围, 除了那些已在行业内建立和接受的密码.在撰写本文时, 常用的密码包括 3DES,ARCFOUR,twofish,serpent 和 blowfish.AES 已由美国联邦信息处理标准作为 [FIPS-197] 发布, 密码学社区也接受了 AES.一如既往, 实现者和用户应该检查当前文献, 以确保在产品中使用的密码没有发现最近的漏洞.实现者还应该检查哪些密码被认为比其他密码相对更强, 并应该向用户推荐它们的使用而不是相对较弱的密码.当主动选择较弱的密码时, 实现礼貌地和不引人注目地通知用户有更强的密码可用并应该使用, 将被视为良好的形式.
"none" 密码是为调试提供的, 不应该用于该目的之外.其密码学属性在 [RFC2410] 中有充分描述, 这将表明其使用不符合此协议的意图.
这些和其他密码的相对优点也可以在当前文献中找到.可能提供有关该主题信息的两个参考资料是 [SCHNEIER] 和 [KAUFMAN].两者都描述了某些密码的 CBC 模式操作以及此方案的弱点.本质上, 由于数据包序列开始的高可预测性, 此模式在理论上容易受到选择密文攻击 (chosen cipher-text attacks).但是, 这种攻击被认为是困难的, 并且不被认为是完全可行的, 特别是如果使用相对较长的块大小.
此外, 可以通过插入包含 SSH_MSG_IGNORE 的数据包来缓解另一种 CBC 模式攻击.没有这种技术, 特定攻击可能会成功.要使此攻击 (通常称为 Rogaway 攻击 [ROGAWAY],[DAI],[BELLARE]) 起作用, 攻击者需要知道将要加密的下一个块的初始化向量 (Initialization Vector, 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
-
Nagle 算法 + TCP 重传意味着两条记录合并到单个 TCP 段中.
-
Record 2 不在 TCP 段的开头, 也永远不会在开头, 因为它被 ACK 了.
-
然而, 攻击是可能的, 因为 Record 1 已经被看到.
如此示例所示, 使用 TCP 缓冲区中未刷新数据的存在作为是否需要空数据包的指南是不安全的, 因为当执行第二次 write() 时, 缓冲区将包含未被 ACK 的 Record 1.
另一方面, 以下情况完全安全:
Client Server
------ ------
TCP(seq=x, len=500) ---->
contains SSH_MSG_IGNORE
TCP(seq=y, len=500) ---->
contains Data
如果第二个 SSH 记录的 IV 在确定 Data 数据包的数据后固定, 则应该执行以下操作:
read from user
encrypt null packet
encrypt data packet
9.3.2 Data Integrity (数据完整性)
此协议确实允许禁用数据完整性机制.实现者应该警惕出于调试以外的任何目的而暴露此功能.用户和管理员应该在启用 "none" MAC 时收到明确警告.
只要不使用 "none" MAC, 此协议就提供数据完整性.
因为 MAC 使用 32 位序列号, 它们可能在发送了 232 个数据包后开始泄漏信息.但是, 遵循重新密钥 (rekeying) 建议应该可以防止这种攻击.传输协议 [SSH-TRANS] 建议在传输 1 GB 数据后重新密钥, 最小可能的数据包是 16 字节.因此, 重新密钥最多应该在 228 个数据包后发生.
9.3.3 Replay (重放)
使用 "none" 以外的 MAC 提供完整性和认证.此外, 传输协议提供唯一的会话标识符 (部分绑定到伪随机数据, 该数据是算法和密钥交换过程的一部分), 更高级别的协议可以使用该标识符将数据绑定到给定会话并防止来自先前会话的数据重放.例如, 认证协议 ([SSH-USERAUTH]) 使用此功能来防止来自先前会话的签名重放.因为公钥认证交换密码学上绑定到会话 (即, 绑定到初始密钥交换), 它们不能在其他会话中成功重放.请注意, 会话 ID 可以公开而不会损害协议的安全性.
如果两个会话具有相同的会话 ID (密钥交换的哈希), 那么来自一个会话的数据包可以针对另一个会话重放.必须强调的是, 使用现代密码学方法时, 这种情况发生的可能性不用说是最小的.当指定更大的哈希函数输出和 DH 参数时, 这更是如此.
[RFC2085],[RFC2246],[RFC2743],[RFC1964],[RFC2025] 和 [RFC4120] 中描述了使用单调递增序列号作为 MAC 或某些情况下 HMAC 的输入的重放检测.[RFC2104] 中讨论了基本构造.本质上, 每个数据包中不同的序列号确保至少这一个 MAC 函数的输入将是唯一的, 并且将提供攻击者无法预测的非重复 MAC 输出.但是, 如果会话保持活动足够长的时间, 此序列号将回绕.此事件可能为攻击者提供重放先前记录的具有相同序列号的数据包的机会, 但仅当对等方自传输具有该序列号的第一个数据包以来没有重新密钥时.如果对等方已重新密钥, 那么重放将被检测到, 因为 MAC 检查将失败.出于这个原因, 必须强调对等方必须在序列号回绕之前重新密钥.自然地, 如果攻击者确实尝试在对等方重新密钥之前重放捕获的数据包, 那么重复数据包的接收者将无法验证 MAC, 它将被丢弃.MAC 失败的原因是接收者将根据数据包内容,共享密钥和预期序列号来制定 MAC.由于重放的数据包将不使用该预期序列号 (重放数据包的序列号将已被接收者传递), 因此计算的 MAC 将不匹配数据包接收的 MAC.
9.3.4 Man-in-the-middle (中间人攻击)
此协议不对分发主机公钥的基础设施或方式做任何假设或规定.预计此协议有时将在没有首先验证服务器主机密钥与服务器主机名之间的关联的情况下使用.此类使用容易受到中间人攻击.本节描述了这一点, 并鼓励管理员和用户在启动任何会话之前了解验证此关联的重要性.
有三种中间人攻击情况需要考虑.第一种是攻击者在会话启动之前将设备放置在客户端和服务器之间.在这种情况下, 攻击设备试图模仿合法服务器, 并将在客户端启动会话时向客户端提供其公钥.如果它要提供服务器的公钥, 那么它将无法解密或签名合法服务器和客户端之间的传输, 除非它还可以访问主机的私钥.攻击设备还将同时启动到合法服务器的会话, 将自己伪装成客户端.如果服务器的公钥在该会话启动之前已安全地分发给客户端, 则攻击设备向客户端提供的密钥将不匹配客户端上存储的密钥.在这种情况下, 应该向用户发出警告, 提供的主机密钥与客户端上缓存的主机密钥不匹配.如第 4.1 节所述, 用户可以自由接受新密钥并继续会话.建议警告向客户端设备的用户提供足够的信息, 以便用户可以做出明智的决定.如果用户选择使用服务器的存储公钥 (而不是会话开始时提供的公钥) 继续会话, 那么攻击者和服务器之间的会话特定数据将在客户端到攻击者会话和攻击者到服务器会话之间有所不同, 这是由于上面讨论的随机性.由此, 攻击者将无法使此攻击起作用, 因为攻击者将无法正确签名包含来自服务器的此会话特定数据的数据包, 因为他没有该服务器的私钥.
应该考虑的第二种情况类似于第一种情况, 因为它也发生在连接时, 但这种情况指出了需要安全分发服务器公钥.如果服务器公钥没有安全分发, 那么客户端无法知道它是否在与预期的服务器通信.攻击者可能使用社会工程技术将服务器密钥传递给毫无戒心的用户, 然后可能在合法服务器和客户端之间放置中间人攻击设备.如果允许这种情况发生, 那么客户端将形成客户端到攻击者会话, 攻击者将形成攻击者到服务器会话, 并且将能够监视和操纵客户端和合法服务器之间的所有流量.鼓励服务器管理员通过某种安全性不依赖于实际主机密钥完整性的方式使主机密钥指纹可用于检查.第 4.1 节中讨论了可能的机制, 还可能包括安全的网页,纸质物品等.实现者应该提供关于如何通过其实现最好地做到这一点的建议.因为协议是可扩展的, 协议的未来扩展可能提供更好的机制来处理在连接之前需要知道服务器主机密钥的需求.例如, 通过安全 DNS 查找使主机密钥指纹可用, 或在密钥交换期间使用 Kerberos ([RFC4120]) 通过 GSS-API ([RFC1964]) 来认证服务器是可能的.
在第三种中间人情况中, 攻击者可能会在会话建立后尝试操纵对等方之间传输的数据包.如第 9.3.3 节所述, 这种性质的成功攻击是非常不可能的.如第 9.3.3 节中所述, 此推理确实假设 MAC 是安全的, 并且构造 MAC 算法的输入以给出已知输出是不可行的.这在 [RFC2104] 的第 6 节中有更详细的讨论.如果 MAC 算法具有漏洞或足够弱, 那么攻击者可能能够指定某些输入以产生已知的 MAC.有了这个, 他们可能能够更改传输中数据包的内容.或者, 攻击者可能能够利用算法漏洞或弱点通过查看捕获的数据包的 MAC 来找到共享密钥.在这两种情况中的任何一种中, 攻击者都可以构造可以插入 SSH 流的一个或多个数据包.为了防止这种情况, 鼓励实现者利用普遍接受的 MAC 算法, 并鼓励管理员关注密码学的当前文献和讨论, 以确保他们不使用具有最近发现的漏洞或弱点的 MAC 算法.
总之, 在没有主机与其主机密钥之间绑定的可靠关联的情况下使用此协议本质上是不安全的, 不推荐使用.但是, 它在非安全关键环境中可能是必要的, 并且仍将提供针对被动攻击的保护.在此协议之上运行的协议和应用程序的实现者应该记住这种可能性.
9.3.5 Denial of Service (拒绝服务)
此协议旨在通过可靠的传输使用.如果发生传输错误或消息操纵, 则关闭连接.如果发生这种情况, 应该重新建立连接.这种类型的拒绝服务攻击 (切断线路, wire cutter) 几乎是不可避免的.
此外, 此协议容易受到拒绝服务攻击, 因为攻击者可以强制服务器在不进行认证的情况下经历 CPU 和内存密集型的连接建立和密钥交换任务.实现者应该提供使这更困难的功能, 例如, 仅允许来自已知具有有效用户的客户端子集的连接.
9.3.6 Covert Channels (隐蔽通道)
该协议并非旨在消除隐蔽通道.例如, 填充 (padding),SSH_MSG_IGNORE 消息和协议中的其他几个地方可用于传递隐蔽信息, 并且接收者没有可靠的方法验证是否正在发送此类信息.
9.3.7 Forward Secrecy (前向保密)
应该注意的是, Diffie-Hellman 密钥交换可能提供完美前向保密 (perfect forward secrecy, PFS).PFS 本质上被定义为密钥建立协议的密码学属性, 其中给定会话后会话密钥或长期私钥的泄露不会导致任何早期会话的泄露 [ANSI-T1.523-2001].使用 [SSH-TRANS] 的 Diffie-Hellman 密钥交换部分中描述的 diffie-hellman 方法 (包括 "diffie-hellman-group1-sha1" 和 "diffie-hellman-group14-sha1") 进行密钥交换产生的 SSH 会话即使在私钥/认证材料后来被泄露的情况下也是安全的, 但如果会话密钥被泄露则不安全.因此, 鉴于 PFS 的这一定义, SSH 确实具有 PFS.但是, 此属性不会传递到使用 SSH 作为传输的任何应用程序或协议.SSH 的传输层为密码认证和其他依赖秘密数据的方法提供机密性.
当然, 如果客户端和服务器的 DH 私有参数被泄露, 那么会话密钥就会被泄露, 但这些项目可以在密钥交换完成后丢弃.值得指出的是, 这些项目不应该允许最终进入交换空间, 并且应该在密钥交换完成后立即从内存中擦除.
9.3.8 Ordering of Key Exchange Methods (密钥交换方法的排序)
如 [SSH-TRANS] 的算法协商部分所述, 每个设备将发送首选密钥交换方法列表.最首选的方法是列表中的第一个.建议算法按密码学强度排序, 最强的在前.[RFC3766] 中给出了一些关于此的额外指导.
9.3.9 Traffic Analysis (流量分析)
对任何协议的被动监视可能会向攻击者提供关于会话,用户或协议特定信息的一些信息, 否则他们将无法收集这些信息.例如, 已经表明 SSH 会话的流量分析可以产生关于密码长度的信息 - [Openwall] 和 [USENIX].实现者应该使用 SSH_MSG_IGNORE 数据包以及包含随机长度的填充, 以挫败流量分析的尝试.也可以找到并实现其他方法.
9.4 Authentication Protocol (认证协议)
此协议的目的是执行客户端用户认证.它假设这运行在安全传输层协议上, 该协议已经认证了服务器机器, 建立了加密通信通道, 并为此会话计算了唯一的会话标识符.
允许使用具有不同安全特性的几种认证方法.由服务器的本地策略决定它愿意为每个用户接受哪些方法 (或方法组合).认证不会比允许的最弱组合更强.
服务器可能在重复的不成功认证尝试后进入睡眠期, 以使攻击者的密钥搜索更加困难.应该注意, 这不会成为自我拒绝服务向量.
9.4.1 Weak Transport (弱传输)
如果传输层不提供机密性, 则应该禁用依赖秘密数据的认证方法.如果它不提供强完整性保护, 则应该禁用更改认证数据的请求 (例如, 密码更改), 以防止攻击者在不被注意的情况下修改密文, 或使新的认证数据无法使用 (拒绝服务).
上面陈述的假设, 即认证协议仅运行在已预先认证服务器的安全传输上, 非常重要.部署 SSH 的人们被提醒, 如果客户端没有与服务器的主机密钥非常强的先验关联, 则中间人攻击的后果.具体而言, 对于认证协议的情况, 客户端可能与中间人攻击设备形成会话并泄露用户凭据, 例如他们的用户名和密码.即使在不泄露用户凭据的认证情况下, 攻击者仍然可能通过捕获击键来获得他们不应该拥有的信息, 就像蜜罐 (honeypot) 的工作方式一样.
9.4.2 Debug Messages (调试消息)
设计调试消息时应特别小心.如果设计不当, 这些消息可能会透露关于主机的惊人数量的信息.如果需要高安全性, 则可以禁用调试消息 (在用户认证阶段).主机机器的管理员应该尽一切努力对所有事件通知消息进行分隔, 并保护它们免受不必要的观察.开发人员应该意识到某些正常事件和调试消息的敏感性质, 并可能希望为管理员提供关于如何使此信息远离未经授权的人的指导.开发人员应该考虑最小化用户在认证阶段可获得的敏感信息量, 符合本地策略.出于这个原因, 建议在部署时初始禁用调试消息, 并要求管理员采取主动决定以允许启用它们.还建议当采取启用调试消息的操作时, 向系统管理员呈现表达此关注的消息.
9.4.3 Local Security Policy (本地安全策略)
实现者必须确保提供的凭据验证所声称的用户, 还必须确保服务器的本地策略允许用户进行所请求的访问.特别是, 由于 SSH 连接协议的灵活性质, 可能无法在认证时确定应应用的本地安全策略 (如果有), 因为此时所请求的服务类型尚不清楚.例如, 本地策略可能允许用户访问服务器上的文件, 但不启动交互式 shell.但是, 在认证协议期间, 不知道用户是将访问文件,尝试使用交互式 shell 还是两者兼而有之.无论如何, 如果存在服务器主机的本地安全策略, 则必须正确应用和执行.
鼓励实现者提供默认的本地策略并使其参数对管理员和用户已知.根据实现者的判断, 此默认策略可以是任何事情都可以的路线, 其中没有对用户施加限制, 或者它可以是过度限制的路线, 在这种情况下, 管理员将不得不主动更改初始默认参数以满足他们的需求.或者, 它可能是某种尝试为系统管理员提供实用和立即有用的东西, 这样他们就不必花太多精力来使 SSH 工作.无论做出何种选择, 都必须按照上述要求应用和执行.
9.4.4 Public Key Authentication (公钥认证)
使用公钥认证假设客户端主机没有被入侵.它还假设服务器主机的私钥没有被入侵.
通过在私钥上使用密码短语 (passphrases) 可以缓解此风险; 但是, 这不是可强制执行的策略.建议使用智能卡或其他技术使密码短语成为可强制执行的策略.
服务器可以要求密码和公钥认证; 但是, 这要求客户端向服务器暴露其密码 (请参见下面的密码认证部分).
9.4.5 Password Authentication (密码认证)
如认证协议中指定的, 密码机制假设服务器没有被入侵.如果服务器已被入侵, 则使用密码认证将向攻击者透露有效的用户名/密码组合, 这可能导致进一步的入侵.
可以通过使用替代形式的认证来缓解此漏洞.例如, 公钥认证不对服务器的安全性做任何假设.
9.4.6 Host-Based Authentication (基于主机的认证)
基于主机的认证假设客户端没有被入侵.没有缓解策略, 除了将基于主机的认证与另一种认证方法结合使用.
9.5 Connection Protocol (连接协议)
9.5.1 End Point Security (端点安全)
连接协议假设端点安全.如果服务器已被入侵, 则主机上的任何终端会话,端口转发或访问的系统都已被入侵.对此没有缓解因素.
如果客户端已被入侵, 并且服务器未能在认证协议中阻止攻击者, 则暴露的所有服务 (作为子系统或通过转发) 都将容易受到攻击.实现者应该为管理员提供控制哪些服务暴露的机制, 以限制其他服务的漏洞.这些控制可能包括控制哪些机器和端口可以在端口转发操作中作为目标, 哪些用户被允许使用交互式 shell 功能, 或哪些用户被允许使用暴露的子系统.
9.5.2 Proxy Forwarding (代理转发)
SSH 连接协议允许代理转发其他协议, 例如 SMTP,POP3 和 HTTP.这可能是网络管理员关注的问题, 他们希望控制位于其物理位置之外的用户对某些应用程序的访问.本质上, 这些协议的转发可能违反特定站点的安全策略, 因为它们可能不可检测地通过防火墙进行隧道传输.实现者应该提供管理机制来控制代理转发功能, 以便可以维护特定站点的安全策略.
此外, 还有反向代理转发功能可用, 同样可以用于绕过防火墙控制.
如上所述, 在代理转发操作期间假定端点安全.端点安全的失败将损害通过代理转发传递的所有数据.
9.5.3 X11 Forwarding (X11 转发)
SSH 连接协议提供的另一种形式的代理转发是 X11 协议的转发.如果端点安全已被入侵, X11 转发可能允许针对 X11 服务器的攻击.用户和管理员应该作为常规做法使用适当的 X11 安全机制来防止 X11 服务器的未经授权使用.希望进一步探索 X11 安全机制的实现者,管理员和用户被邀请阅读 [SCHEIFLER] 并分析先前报告的 SSH 转发和 X11 之间交互的问题, 在 CERT 漏洞 VU#363181 和 VU#118892 [CERT] 中.
使用 SSH 的 X11 显示转发本身不足以纠正 X11 安全性的众所周知的问题 [VENEMA].但是, SSH (或其他安全协议) 中的 X11 显示转发, 结合仅通过由权限或访问控制列表 (ACLs) 授权的本地 IPC 机制接受连接的实际和伪显示, 确实可以纠正许多 X11 安全问题, 只要不使用 "none" MAC.建议 X11 显示实现默认允许显示仅通过本地 IPC 打开.建议支持 X11 转发的 SSH 服务器实现默认允许显示仅通过本地 IPC 打开.在单用户系统上, 默认允许本地显示通过 TCP/IP 打开可能是合理的.
X11 转发协议的实现者应该实现魔术 cookie 访问检查欺骗机制, 如 [SSH-CONNECT] 中所述, 作为防止代理未经授权使用的额外机制.