物联网之MQTT3.1.1和MQTT5协议 (18) 安全

安全

概述

强烈推荐提供TLS的服务端实现应该使用TCP端口8883(IANA服务名:secure-mqtt)。

安全是一个快速变化的领域,所以在设计安全解决方案时总是使用最新的建议。

解决方案需要考虑的风险包括:

  • 设备可能会被盗用
  • 客户端和服务端的静态数据可能是可访问的(可能会被修改)
  • 协议行为可能有副作用(如计时器攻击)
  • 拒绝服务(DoS)攻击
  • 通信可能会被拦截、修改、重定向或者泄露
  • 虚假MQTT控制报文注入

MQTT方案通常部署在不安全的通信环境中。在这种情况下,协议实现通常需要提供这些机制:

  • 用户和设备身份认证
  • 服务端资源访问授权
  • MQTT控制报文和内嵌应用数据的完整性校验
  • MQTT控制报文和内嵌应用数据的隐私控制

作为传输层协议,MQTT仅关注消息传输,提供合适的安全功能是实现者的责任。使用TLS是比较普遍的选择。

除了技术上的安全问题外,还有地理因素(例如美国欧盟安全港原则 [USEUSAFEHARB]),行业标准(例如第三方支付行业数据安全标准 [PCIDSS]),监管方面的考虑(例如萨班斯-奥克斯利法案 [SARBANES])等问题。

MQTT解决方案:安全和认证

协议实现可能想要符合特定的工业安全标准,如NIST网络安全框架 [NISTCSF] ,第三方支付行业数据安全标准 [PCIDSS] ,美国联邦信息处理标准 [FIPS1402] 和 NSA 加密组合B [NSAB] 。

在MQTT的补充出版物 (MQTT and the NIST Framework for Improving Critical Infrastructure Cybersecurity [MQTT NIST]) 中可以找到在NIST网络安全框架 [NISTCSF] 中使用MQTT的指导。使用行业证明、独立审计和认证技术有助于满足合规要求。

轻量级的加密与受限设备

广泛采用高级加密标准 [AES] 数据加密标准 [DES] 。

扫描二维码关注公众号,回复: 10746211 查看本文章

MQTT 5增加概述,对AES提供了硬件支持的处理器有很多,但通常不包含嵌入式处理器。加密算法ChaCha20 软件加解密速度快很多,但不像AES那样广泛可用。

推荐使用为受限的低端设备特别优化过的轻量级加密国际标准 ISO 29192

实现注意事项

实现和使用MQTT时需要考虑许多安全问题。下面的部分不应该被当作是一个 核对清单 。
协议实现可以实现下面的一部分或全部:

客户端身份认证

CONNECT报文包含用户名和密码字段。实现可以决定如何使用这些字段的内容。实现者可以提供自己的身份验证机制,或者使用外部的认证系统如LDAP或OAuth,还可以利用操作系统的认证机制。

MQTT v5.0提供了一种增强认证机制。使用此机制需要客户端和服务端双方的支持。

实现可以明文传递认证数据,混淆那些数据,或者不要求任何认证数据,但应该意识到这会增加中间人攻击和重放攻击的风险。

在客户端和服务端之间使用虚拟专用网(VPN)可以确保数据只被授权的客户端收到。

使用TLS 时,服务端可以使用客户端发送的SSL证书验证客户端的身份。

实现可以允许客户端通过应用消息给服务端发送凭证用于身份验证。

客户端授权

【MQTT3.1.1】

基于客户端提供的信息如用户名、客户端标识符(ClientId)、客户端的主机名或IP地址,或者身份认证的结果,服务端可以限制对某些服务端资源的访问。

【MQTT5】

如果客户端已经成功通过身份认证,服务端实现需要在接受连接之前执行授权检查。

授权可以基于客户端提供的信息如用户名,客户端主机名/IP地址,或认证机制的结果。

具体来说,实现应该检查客户端是否被授权使用此客户标识符,因为客户标识符提供了对MQTT会话状态的访问。此授权检查是为了防止某个客户端偶然或恶意的使用了已被其他客户端所使用的客户标识符。

实现应该提供发生在CONNECT之后的访问控制以限制客户端发布消息到特定主体或使用特定主体过滤器进行订阅的能力。实现需要考虑对具有广泛作用域的主题过滤器的访问限制,如"#"主题过滤器。

服务端身份验证

MQTT协议不是双向信任的,基本认证没有提供客户端验证服务端身份的机制。

【MQTT5】某些形式的扩展认证允许双向认证。

但是使用TLS时,客户端可以使用服务端发送的SSL证书验证服务端的身份。

MQTT5说的证书是TLS证书

从单IP多域名提供MQTT服务的实现应该考虑RFC6066的TLS的SNI扩展。SNI允许客户端告诉服务端它要连接的服务端主机名。

实现可以允许服务端通过应用消息给客户端发送凭证用于身份验证。

MQTT v5.0提供了一种增强的认证机制,它可以被客户端用于验证服务端。使用此机制需要客户端和服务端双方的支持。

在客户端和服务端之间使用虚拟专用网(VPN)可以确保客户端连接的是预期的服务器。

应用消息和MQTT控制报文的完整性

应用可以在应用消息中单独包含哈希值。这样做可以为PUBLISH控制报文的网络传输和静态数据提供内容的完整性检查。
TLS 提供了对网络传输的数据做完整性校验的哈希算法。
在客户端和服务端之间使用虚拟专用网(VPN)连接可以在VPN覆盖的网络段提供数据完整性检查。

应用消息和MQTT控制报文的保密性

TLS 可以对网络传输的数据加密。如果有效的TLS密码组合包含的加密算法为NULL,那么它不会加密数据。要确保客户端和服务端的保密,应避免使用这些密码组合。
应用可以单独加密应用消息的内容。这可以提供应用消息传输途中和静态数据的私密性。但不能给应用消息的其它属性如主题名加密。
客户端和服务端实现可以加密存储静态数据,例如可以将应用消息作为会话的一部分存储。
在客户端和服务端之间使用虚拟专用网(VPN)连接可以在VPN覆盖的网络段保证数据的私密性。

消息传输的不可否认性

应用设计者可能需要考虑适当的策略,以实现端到端的不可否认性(non-repudiation)。

客户端和服务端盗用检测

使用TLS 的客户端和服务端实现应该能够确保,初始化TLS连接时提供的SSL证书是与主机名(客户端要连接的或服务端将被连接的)关联的。

使用TLS 的客户端和服务端实现,可以选择提供检查证书吊销列表 (CRLs [RFC5280]) 和在线证书状态协议 (OSCP) [RFC6960] 的功能,拒绝使用被吊销的证书。

物理部署可以将防篡改硬件与应用消息的特殊数据传输结合。例如,一个仪表可能会内置一个GPS以确保没有在未授权的地区使用。IEEE安全设备认证就是用于实现这个机制的一个标准,它使用加密绑定标识符验证设备身份。

异常行为检测

服务端实现可以监视客户端的行为,检测潜在的安全风险。例如:

  • 重复的连接请求
  • 重复的身份验证请求
  • 连接的异常终止
  • 主题扫描(请求发送或订阅大量主题)
  • 发送无法送达的消息(没有订阅者的主题)
  • 客户端连接但是不发送数据

发现违反安全规则的行为,服务端实现可以断开客户端连接。
服务端实现检测不受欢迎的行为,可以基于IP地址或客户端标识符实现一个动态黑名单列表。
服务部署可以使用网络层次控制(如果可用)实现基于IP地址或其它信息的速率限制或黑名单。

其它安全注意事项

如果客户端或服务端的SSL证书【MQTT5,是TSL证书】丢失,或者我们考虑证书被盗用或者被吊销(利用 CRLs和 OSCP )的情况。
客户端或服务端验证凭证时,如果发现用户名和密码丢失或被盗用,应该吊销或者重新发放。
在使用长连接时:

  • 客户端和服务端使用TLS [RFC5246] 时应该允许重新协商会话以确认新的加密参数(替换会话密钥,更换密码组合,更换认证凭证)。

  • 服务端可以断开客户端连接,并要求他们使用新的凭证重新验证身份。

  • 服务端可以要求客户端使用机制周期性的进行重新认证。

    即MQTT5 的重新认证

受限网络上的受限设备和客户端可以使用TLS会话恢复降低TLS会话重连的成本。

连接到服务端的客户端与其它连接到服务端的客户端之间有一个信任传递关系,它们都有权在同一个主题上发布消息。

使用SOCKS代理

客户端实现应该意识到某些环境要求使用SOCKSv5 代理创建出站的网络连接。某些MQTT实现可以利用安全隧道(如SSH)通过SOCKS代理。一个实现决定支持SOCKS时,它们应该同时支持匿名的和用户名密码验证的SOCKS代理。对于后一种情况,实现应该意识到SOCKS可能使用明文认证,因此应该避免使用相同的凭证连接MQTT服务器。

安全配置文件

实现者和方案设计者可能希望将安全当作配置文件集合应用到MQTT协议中。下面描述的是一个分层的安全等级结构。

开放通信配置

使用开放通信配置时,MQTT协议运行在一个没有内置额外安全通信机制的开放网络上。

安全网络通信配置

使用安全网络通信配置时,MQTT协议运行在有安全控制的物理或虚拟网络上,如VPN或物理安全网络。

安全传输配置

使用安全传输配置时,MQTT协议运行在使用TLS 的物理或虚拟网络上,它提供了身份认证,完整性和保密性。

使用内置的用户名和密码字段,TLS 客户端身份认证可被用于(或者代替)MQTT客户端认证。

工业标准的安全配置

可以预料的是,MQTT被设计为支持很多工业标准的应用配置,每一种定义一个威胁模型和用于定位威胁的特殊安全机制。特殊的安全机制推荐从下面的方案中选择:

使用 WebSocket作为网络层

如果MQTT在WebSocket 连接上传输,必须满足下面的条件:

  • MQTT控制报文必须使用WebSocket二进制数据帧发送。如果收到任何其它类型的数据帧,接收者必须关闭网络连接。
  • 单个WebSocket数据帧可以包含多个或者部分MQTT报文。接收者不能假设MQTT控制报文按WebSocket帧边界对齐 。
  • 客户端必须将字符串 mqtt 包含在它提供的WebSocket子协议列表里 。
  • 服务端选择和返回的WebSocket子协议名必须是 mqtt 。
  • 用于连接客户端和服务器的WebSocket URI对MQTT协议没有任何影响。

IANA注意事项

MQTT规范中请求IANA在WebSocket子协议名条目下注册WebSocket MQTT子协议,使用下列数据:

IANA WebSocket标识符

子协议标识符 mqtt
子协议通用名 mqtt
子协议定义 http://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html
发布了189 篇原创文章 · 获赞 675 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/YuYunTan/article/details/102519748