在MQTT中使用SSL/TLS提高安全性

来源:互联网 发布:国家电网 大数据预算 编辑:程序博客网 时间:2024/06/05 05:42

在MQTT中使用SSL/TLS提高安全性

当我开始使用MQTT时, 发现比较容易找到使用SSL/TLS验证去加密与代理之间的数据的相关资料。OwnTracks项目甚至提供了一个设置CA及签名的一个脚本, 不过证书是给代理服务器而不是客户端用的。

在按照其说明去使用SSL验证MQTT客户端身份时我遇到了一些问题, 这皮按文章主要是想弥补一下原有文档的一些不足。

术语说明:TLS(传输层安全)是SSL的新名称(安全套接层)。StackExchange对于SSL, TLS, and HTTPS三者的区别提供了更详尽的解析

准备

  • 使用openssl来生成证书(我在Ubuntu 14.04 LTS上进行开发并亲测了这个过程).
  • 将使用开源代理mosquitto来演示这个过程。 通过apt-get来安装:

$ sudo apt-get install mosquitto

步骤

提示: 该过程在同一个系统中进行

1. 创建一个受保护的workspace

警告: 对证书的密钥并没有使用密码保护。也许这不是最好的做法,但它确实使它更容易在守护进程和嵌入式设备中使用。你隐藏好它们这很重要。

在当前示例中,我们将创建并使用其他用户没有权限访问的目录。

$ mkdir myCA
$ chmod 700 myCA
$ cd myCA

2. 创建CA并生成server端证书

从OweTracks项目下载并运行generate-CA.sh脚本。该脚本创建CA文件,生成服务器证书,并使用CA来签名证书。

注:在生产环境中使用此实例之前,你应该定制thegenerate-CA.sh脚本,而这些这超出了本章节要讲解的范围。

$ wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh .
$ bash ./generate-CA.sh

generate-CA.sh会产生6个文件:ca.crt,ca.key,ca.srl,myhost.crt,myhost.csr和myhost.key。分别为: 证书(.CRT),钥匙(.KEY),请求(.csr文件),并在签名过程中的一系列记录文件(.slr)。注意myhost文件在您的系统上或许是不同的名字。

其中有三个文件会拷贝到/etc/mosquitto目录:

$ sudo cp ca.crt /etc/mosquitto/ca_certificates/
$ sudo cp myhost.crt myhost.key /etc/mosquitto/certs/

配置文件/etc/mosquitto/mosquitto.conf大概是这个样子:

# mosquitto.confpid_file /var/run/mosquitto.pidpersistence truepersistence_location /var/lib/mosquitto/log_dest file /var/log/mosquitto/mosquitto.logcafile /etc/mosquitto/ca_certificates/ca.crtcertfile /etc/mosquitto/certs/myhost.crtkeyfile /etc/mosquitto/certs/myhost.key

在拷贝证书文件和修改mosiquitto.conf后, 重启服务:

$ sudo service mosquitto restart

3. 检验

您可以通过使用客户端mosquitto_sub来进行验证:

$ mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile ca.crt
$SYS/broker/bytes/received 65
$SYS/broker/bytes/sent 67
$SYS/broker/bytes/received 130
$SYS/broker/bytes/sent 196

这些topic每10秒更新一次。如果需要调试,你可以这样mosquitto_sub -d或者看/var/logs/mosquitto/mosquitto.log日志记录。

4. 生成证书

在这一点上,你可以尝试我做过的步骤,并使用generate-CA.sh生成另一个证书,但还是别这样做!它不会生效,因为它创建证书nsCertType设置为服务器有效,因此在客户端上使用无效。用脚本试了一下,同时阅读手册页的OpenSSL后,我发现以下三个命令将创建我所需要的证书:

$ openssl genrsa -out client.key 2048
$ openssl req -new -out client.csr
-key client.key -subj "/CN=client/O=example.com"

$ openssl x509 -req -in client.csr -CA ca.crt
-CAkey ca.key -CAserial ./ca.srl -out client.crt
-days 3650 -addtrust clientAuth

关键的参数为-addtrust clientAuth, 它使得签名的证书同样适用与客户端。

这很简单,但你可能会希望有一定量的不同客户端的证书。用这样的方式来实现一个客户端一个证书是不靠谱的。所以附加的脚本是generate-CA.sh的一个补充。可以这样使用:

$ bash ./generate-client.sh client2

5. 重新配置

更改mosquitto配置, 在/etc/mosquitto/mosquitto.conf文件末尾加上这几行,用来要求客户端添加安全认证:

# mosquitto.confpid_file /var/run/mosquitto.pidpersistence truepersistence_location /var/lib/mosquitto/log_dest file /var/log/mosquitto/mosquitto.logcafile /etc/mosquitto/ca_certificates/ca.crtcertfile /etc/mosquitto/certs/SVE14A1HFXB.crtkeyfile /etc/mosquitto/certs/SVE14A1HFXB.keyrequire_certificate true

然后重启服务:

$ sudo service mosquitto restart

6. 测试

这时这样使用mosquitto_sub命令会失败:

$ mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile ca.crt

//Error: Protocol errorError: A TLS error occurred.

指定参数–cert和–key来满足服务器要求:

$ mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile ca.crt --cert client.crt --key client.key
$SYS/broker/bytes/received 65
$SYS/broker/bytes/sent 67
$SYS/broker/bytes/received 130
$SYS/broker/bytes/sent 136

第二个client也这样做:

$ mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile ca.crt --cert client2.crt --key client2.key
$SYS/broker/bytes/received 130
$SYS/broker/bytes/sent 198
$SYS/broker/bytes/received 195
$SYS/broker/bytes/sent 269

总结

使用客户端证书,在另一层次也给您的MQTT系统提供安全保护。现在除了有一个加密的通信通道,服务器也将只接受正确签名证书的连接。

在MQTT系统上的安全工作还有很多, 而加密通信信息是一个好的开始。

Follow-up

需要联系我的话, 可以在我的google+文章下留言。

3 0
原创粉丝点击