参考文章segmentfault
系统版本: 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
命令, 因此从新为其签发了证书与密钥对, 而后运行成功了.
因而猜想, 是否是CA
的Common 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.