mosquitto日志报错SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

参考文章segmentfault

  1. Mosquitto服务器的搭建以及SSL/TLS安全通讯配置
  2. Mosquitto SSL Configuration -MQTT TLS Security 读者Abhinav Saxena的评论
  3. OpenSSL - error 18 at 0 depth lookup:self signed certificate

系统版本: CentOS7安全

mosquitto版本: 1.4.15服务器

openssl版本: 1.0.1eide

参考文章1对mosquitto的TLS配置步骤讲解得十分详细, 包含了openssl生成证书及密钥, mosquitto的配置, 及其内置pub/sub客户端对证书及密钥的使用等. 测试

其实关于mosquitto的自签名SSL/TLS配置, 在用yum安装后可使用man mosquitto-tls查看, 其中也有详细的操做步骤.ui

按照这样的流程走下来, mosquitto启动正常, 相关配置以下.日志

cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
tls_version tlsv1

没什么问题, 可是在执行mosquitto_pub, mosquitto_sub命令时, 获得了Error: A TLS error occurred.错误.code

$ mosquitto_pub  -t 'room01/sensors' -m '个人消息' --cafile /etc/mosquitto/certs/ca.crt --cert /etc/mosquitto/certs/client.crt --key /etc/mosquitto/certs/client.key -h 172.32.100.10 --tls-version tlsv1
Error: A TLS error occurred

对应的, mosquitto服务端的日志以下.server

1523024283: New connection from 172.32.100.10 on port 1883.
1523024283: OpenSSL Error: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
1523024283: OpenSSL Error: error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure
1523024283: Socket error on client <unknown>, disconnecting.
--tls-version tlsv1选项要加的, 由于 pub/sub两个客户端使用的tls版本默认为 tls1.2, 不加这个选项的话, mosquitto服务会获得 SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version错误.

网上关于这个问题有说是由于mosquitto与两个客户端版本不一致的, 或者mosquitto指定ca.crt与客户端不是同一个的, 也有说是server.csr填写的Common Name与服务器IP不一样的...ssl

呵呵, 好笑, 我怎么可能会犯这种低级错误.

我也尝试过为mosquitto_pub加上--insecure选项, 可是这是让mosquitto_pub不去验证服务端证书中Common Name与其地址是否匹配的, 无效.

后来按照参考文章2中Abhinav Saxena的提示, 把--cafile的值改为了server.crt, 居然成功了...成功了...

$ mosquitto_pub  -t 'room01/sensors' -m '个人消息' --cafile /etc/mosquitto/certs/ca.crt --cert /etc/mosquitto/certs/client.crt --key /etc/mosquitto/certs/client.key -h 172.32.100.10 --tls-version tlsv1

mosquitto_sub的命令以下

$ mosquitto_sub  -t 'room01/sensors' -h 172.32.100.10 --tls-version tlsv1 --cafile /etc/mosquitto/certs/server.crt --cert /etc/mosquitto/certs/client.crt --key /etc/mosquitto/certs/client.key
个人消息

服务端的日志以下

1523175367: New connection from 172.32.100.10 on port 1883.
1523175368: New client connected from 172.32.100.10 as mosqpub|6211-localhost. (c1, k60).
1523175368: Sending CONNACK to mosqpub|6211-localhost. (0, 0)
1523175368: Received PUBLISH from mosqpub|6211-localhost. (d0, q0, r0, m0, 'room01/sensors', ... (12 bytes))
1523175368: Received DISCONNECT from mosqpub|6211-localhost.
1523175368: Client mosqpub|6211-localhost. disconnected.

若是加了--insecure选项, 命令应该是这样的

$ mosquitto_pub  -t 'room01/sensors' -m '个人消息' -h 172.32.100.10 --tls-version tlsv1 --cafile /etc/mosquitto/certs/server.crt --insecure

对应的, moquitto_sub的命令应该写作

$ mosquitto_sub  -t 'room01/sensors' -h 172.32.100.10 --tls-version tlsv1 --cafile /etc/mosquitto/certs/server.crt --insecure
个人消息

个人世界观都崩塌了...

以后的实验里, 认识到上面的TLS只是mosquitto的单向认证, 这种状况下, 是要客户端判断服务端是否可信的, 就是说, 这种认证是为了客户端的安全而不是服务端安全.

mosquitto还有一个require_certificate字段, 表示是否验证客户端传来的证书, 默认为fasle.

...呵呵, 若是没验证客户端证书, 那上面的错误是怎么来的???

不过, 将这个字段设置为true后, 上面两种订阅/发布命令都没用了.

心累.jpg, md必定是mosquitto_pub/sub两个命令有问题!


隐隐以为仍是和证书的Common Name字段有关, 以前的测试中, mosquitto服务与pub/sub客户端是在同一台服务器上. 尝试在另外一台服务器运行mosquitto_pub命令, 因此从新为其签发了证书与密钥对, 而后运行成功了.

因而猜想, 是否是CACommon Name不能与被其签发的证书的相同? 由于以前测试时, CA, server与client的Common Name都是172.32.100.10(以前也试过localhost, 127.0.0.1的).

而后从新生成CA证书, Common Name填的是0.0.0.0, server与client的依然是服务器自己的IP172.32.100.10.

事实证实个人猜想是对的.

网上你们人都只说mosquitto与其客户端的证书Common Name要与其所在服务器IP相符, 却没有人说过自签名的CA证书Common Name应该取什么, 总有人踩坑的.

关于这一点, 能够看一下参考文章3的最佳答案, 一票人来感谢这个回答...

When OpenSSL prompts you for the Common Name for each certificate, use different names.
相关文章
相关标签/搜索