TLS & DTLS心跳扩展(rfc6250)

最近半年中openssl的心脏滴血漏洞造成的影响真是太大了,openssl在实现rfc6052文档中定义的心跳扩展协议的时候出现了低级错误。对于这个错误的动机是什么真是无从说起。最近自己的项目中用到了这一部分的内容,那么就把自己整理的这份文档分享出来,反正我在网上是没有看到。废话少说,赶紧上内容吧,必须吐槽的是,某机构定义的行业规范歧义太多了,根本没有办法指导实际的开发过程,该好好看看RFC文档定义的内容。



1.概述
本文描述了TLS和DTLS协议的心跳扩展。DTLS协议是基于不可靠的传送协议来实现的。一般来说没有做会话管理,在业务的处理中,有时需要确认对方是否在线。TLS基于可靠的传输协议,一般来说没有必要这样的机制来保证,但是如果想用就用呗。
心跳扩展包还可以在DTLS中用来做PMTU探测。UDP直接用socket的MTU发现属性得出来的值往往不怎么可靠。


2.Hello消息的心跳扩展
在hello消息的扩展项中可以加入心跳消息模式。协商的双方不能仅描述自己是否自持心跳,同时可以更进一步来描述,如愿意接收心跳请求消息并且回复响应消息,或者仅仅愿意发送心跳请求消息,第一种情况设置peer_allowed_to_send模式,第二种设置peer_not_allowed_to_send模式。在每次重新协商的时候可以更改这些模式。
如果对方设置了peer_not_allowed_to_send,那么就不要再发送请求消息了。如果某端声明了peer_not_allowed_to_send模式,那么它可以丢弃这个包,并给对方发送一个告警消息“unexpected_message”。
hello消息中扩展的心跳模式的定义如下:
enum {
      peer_allowed_to_send(1),
      peer_not_allowed_to_send(2),
      (255)
   } HeartbeatMode;


   struct {
      HeartbeatMode mode;
   } HeartbeatExtension;
hello消息中包含一些未定义的模式时,接收方要告诉对方一个告警消息“illegal_parameter ”。


3.心跳协议
心跳协议是一种跑在记录层之上的协议,心跳包有两种消息类型:心跳请求和心跳响应。
enum {
      heartbeat_request(1),
      heartbeat_response(2),
      (255)
   } HeartbeatMessageType;
心跳包请求可能会在连接的生命周期内都收到。当收到心跳请求包时,返回相应的响应包。
但是,心跳包尽量不要在协商阶段发送,因为这个过程中发送心跳包,可能会导致握手重传机制停止。如果在协商阶段收到心跳请求包,接收方应当悄悄禁止这个消息。在DTLS协议中,来自旧epochs的心跳请求消息要被禁止。
   在一个阶段内不要同时发送多个心跳请求消息,心跳请求消息从发出到接收到相应的响应消息应当放在同一个阶段中,或者在重传机制触发之前。
   在使用像UDP或者DCCP这样的不可靠传输协议时,心跳请求消息需要使用DTLS协议中定义的超时重传机制。当重传超过一定的次数后,还没有收到响应消息,应当终止DTLS连接。重传次数的阈值和DTLS定义的要一致。需要注意的是,定时器发现心跳请求消息到期时,在这个阶段中不需要再发送了。这种超时重传的处理方式仅用在基于UDP的DTLS上,其他有拥塞控制的重传协议就不要使用了。
   在使用像SCTP或者TCP这样的可靠流控制传输协议时,心跳请求消息只要发送一次就行了,传输层会来实现重传。在发送了心跳请求消息后的一段时间后,如果没有收到相应的响应消息,那么就终止连接。
4. 心跳请求和响应消息
心跳协议消息包含了类型,任意载荷和填充。结构如下:
   struct {
      HeartbeatMessageType type;
      uint16 payload_length;
      opaque payload[HeartbeatMessage.payload_length];
      opaque padding[padding_length];
   } HeartbeatMessage;
心跳消息的总长度不能超过2^14或者规定的最大分片单元的长度。


类型:消息类型,心跳请求或者心跳响应,在第三节定义的两个。
载荷长度:就是后面跟的载荷的长度。
载荷:载荷包含任意的内容。
填充:填充是一个随机数,会被接受者忽略不处理。心跳消息的长度是TLS活DTLS协议的明文域的长度。填充随机数的长度至少16字节。


填充长度的计算方式如下:
TLSplaintext.length - type(1)- payload_length(2) - payload_length.
DTLSplanintext.length - 3 - playload_length.
其实两种中协议的填充长度是一样的。
如果收到的载荷长度太长了,那就悄悄的给禁止了。
现在不知道为什么这个心跳协议要设计这个变长的载荷,但是就是这个设计导致了,攻击者可以将系统的内存消息看个遍,现成的会话密钥,或者用来计算会话密钥的计算因子全暴露出来了,获取会话密钥so easy。


   当接收者收到心跳消息后,需要将消息载荷中的内容精确的复制到响应消息中。如果心跳回复中没有包含期望的载荷,将会被悄悄丢弃,重传超时定时器也要停止。


5.应用场景
1).PMTU发现
    DTLS协议的PMTU发现参见rfc6347,探测包使用心跳请求消息。
2)在线状态检测
    发送方发送心跳请求,确认对方是否存活。如果在TCP协议中,也可以允许更上层的服务来做状态探测,比如在做集群的时候。除了判断对方是否可达,发送心跳请求还能刷新NAT的状态。
    心跳请求只能在发生多轮异常之后的空闲时间发送。空闲时间的周期应该是可以配置的,从一秒钟到几分钟。一般来说应该定义一个默认值,也是可以调整的。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值