mosquitto 开启 TLS 问题总结

正文

在使用 mosquitto 对 MQTT 开启 TLS 进行测试时,经常会遇到各种神奇的错误,但是 mosquitto 的日志却少的可怜,服务端能看到的日志大约就这几种:

SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca
SSL routines:ssl3_read_bytes:ssl handshake failure
Socket error on client <unknown>, disconnecting.

客户端能看到的日志也少得可怜:

Error: A TLS error occurred.

下面总结几种常见的错误:

  • 使用自签名证书时,CA证书 和 server证书 的 Comon Name 使用了相同的内容;这样会导致 OpenSSL 校验证书时失败,将 CA证书 和 server证书的 Comon Name 改成不同的内容即可;
  • 使用自签名证书时,server证书 的 Comon Name 与域名不相符,默认情况下客户端会连接错误,这时在连接时加入 --insecure 参数即可;
  • 使用自签名证书时,如果CA是单个文件,将 --cafile 参数错写成 --capath
  • 服务端开启双向认证 require_certificate true , 连接时没有传入客户端的证书和密钥;
  • 服务端与客户端的 TLS 版本不一致,服务端配置参数为 tls_version ,客户端配置参数为 --tls-version

当然,mosquitto 的日志不详细时,需要使用其他更有效的方式来诊断问题,这里提供一种有效的方式,使用 wireshark 来过滤底层通信数据,下面是使用 wireshark 的截图:
在这里插入图片描述
TLS Record 有四种类型:

  • change_cipher_spec (20)
  • alert (21)
  • handshake (22)
  • application_data (23)

通常在出现错误时都会通过 alert 消息来返回错误信息,所以可以通过 Alert 消息来诊断问题。上图中的 Alert 消息可以看出是CA证书 出了问题,这时可以检查 CA证书是否一致,是否加载成功等,然后找到问题并解决。

RFC5246 对 Alert 定义

/* https://tools.ietf.org/html/rfc5246#page-28 */

enum { warning(1), fatal(2), (255) } AlertLevel;

enum {
    close_notify(0),
    unexpected_message(10),
    bad_record_mac(20),
    decryption_failed_RESERVED(21),
    record_overflow(22),
    decompression_failure(30),
    handshake_failure(40),
    no_certificate_RESERVED(41),
    bad_certificate(42),
    unsupported_certificate(43),
    certificate_revoked(44),
    certificate_expired(45),
    certificate_unknown(46),
    illegal_parameter(47),
    unknown_ca(48),
    access_denied(49),
    decode_error(50),
    decrypt_error(51),
    export_restriction_RESERVED(60),
    protocol_version(70),
    insufficient_security(71),
    internal_error(80),
    user_canceled(90),
    no_renegotiation(100),
    unsupported_extension(110),
    (255)
} AlertDescription;

struct {
    AlertLevel level;
    AlertDescription description;
} Alert;

生成证书脚本

#!/usr/bin/env bash
# When OpenSSL prompts you for the Common Name for each certificate, use different names.

# CA key
openssl genrsa -out ca.key 2048
# CA csr
openssl req -new -subj "/CN=ca" -key ca.key -out ca.csr
# CA crt
openssl x509 -req -in ca.csr -out ca.crt -signkey ca.key -days 3650

# server key
openssl genrsa -out server.key 2048
# server.csr
openssl req -new -subj "/CN=server" -key server.key -out server.csr
# server.crt
openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key \
-CAcreateserial -days 3650
# server.crt verify
openssl verify -CAfile ca.crt  server.crt

# client key
openssl genrsa -out client.key 2048
# client.csr
openssl req -new -subj "/CN=client" -key client.key -out client.csr
# client.crt
openssl x509 -req -in client.csr -out client.crt -CA ca.crt -CAkey ca.key \
-CAcreateserial -days 3650
# client.crt verify
openssl verify -CAfile ca.crt  client.crt

配置文件

# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example

pid_file /var/run/mosquitto.pid

port 1883

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

allow_anonymous false

password_file /root/mosquitto/pwfile
# acl_file /root/mosquitto/aclfile

listener 8883
cafile ca.crt
certfile server.crt
keyfile server.key

# one-way or two-way authentication
require_certificate true

生成用户名密码配置文件

# create pwfile and add user
mosquitto_passwd -c pwfile admin
# add user on pwfile with password
mosquitto_passwd -b pwfile admin admin
# add user on pwfile
mosquitto_passwd pwfile admin

测试命令

# insecure sub
mosquitto_sub -d \
    -k 30 \
    -h localhost -p 1883 \
    -t gateway/test0 \
    -u admin -P admin

# insecure pub
mosquitto_pub -d \
    -h localhost -p 1883 \
    -t gateway/test0 \
    -u admin -P admin \
    -m {"message":"THIS_IS_A_TEST_MESSAGE"}

# secure pub one-way and no-check CA common name
mosquitto_pub -d \
    -h localhost -p 8883 \
    -t gateway/test0 \
    -u admin -P admin \
    --cafile ca.crt \
    --insecure \
    -m {"message":"THIS_IS_A_TEST_MESSAGE"}

# secure pub two-way
mosquitto_pub -d \
    -h localhost -p 8883 \
    -t gateway/test0 \
    -u admin -P admin \
    --cafile ca.crt \
    --cert client.crt --key client.key \
    -m {"message":"THIS_IS_A_TEST_MESSAGE"}
    

参考文档:

  1. mosquitto.conf man page
  2. RFC 5246: The Transport Layer Security (TLS) Protocol
  3. Mosquitto SSL Configuration -MQTT TLS Security
  4. mosquitto日志报错SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
mosquitto_tls_set是MQTT开源库mosquitto中的一个关键接口,用于设置TLS(Transport Layer Security)双向认证。TLS是一种用于保护网络通信安全的协议,通过使用证书和密钥来验证和加密通信。 在mosquitto_tls_set接口中,需要提供以下参数: 1. mosq:指向mosquitto结构体的指针,表示要进行设置的mosquitto客户端。 2. cafile:根证书文件的路径,用于验证服务器端的证书。 3. capath:根证书目录的路径,用于验证服务器端的证书。 4. certfile:客户端证书文件的路径,用于进行客户端的身份验证。 5. keyfile:客户端私钥文件的路径,用于进行客户端的身份验证。 6. pw_callback:密码回调函数,用于提供密钥文件的密码。 通过调用mosquitto_tls_set接口,可以为mosquitto客户端设置TLS双向认证,以确保通信的安全性。在设置完成后,可以使用mosquitto_connect函数与服务器建立安全的连接。 以上是对mosquitto_tls_set接口的简要说明。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [MQTT开源库mosquitto安装和使用(三)使用TLS](https://blog.csdn.net/skytering/article/details/119207438)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [mosquito服务器实现 ssl/tls 安全配置通信](https://blog.csdn.net/vincen_zhaozhao/article/details/128239941)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值