CLI TLS 测试
CLI TLS 测试
本节介绍使用命令行工具测试 MQTT TLS 连接的方法。命令行测试是验证 TLS 配置是否正确的最直接方式。学习完成后,您将能够:
- 使用 mosquitto_pub/sub 测试 TLS 连接
- 使用 openssl s_client 诊断 TLS 问题
- 使用 Wireshark 验证 MQTT 加密
- 排查 TLS 连接常见问题
在开始本节之前,请确保:
- Mosquitto TLS 已配置并运行
- 证书文件已就位
- 安装 mosquitto 客户端工具
- 安装 openssl 工具
Install CLI Tools
Section titled “Install CLI Tools”# Ubuntu/Debian 安装 mosquitto 客户端sudo apt install mosquitto-clients
# macOS 安装brew install mosquitto
# 验证安装mosquitto_pub --helpmosquitto_sub --helpTesting with mosquitto_pub/sub
Section titled “Testing with mosquitto_pub/sub”基本 TLS 测试
Section titled “基本 TLS 测试”# 订阅测试 Topicmosquitto_sub -h mqtt.example.com \ -p 8883 \ --cafile /opt/mosquitto/certs/fullchain.pem \ -t "test/tls" \ -u "testuser" \ -P "testpass" \ -d
# 另一个终端:发布测试消息mosquitto_pub -h mqtt.example.com \ -p 8883 \ --cafile /opt/mosquitto/certs/fullchain.pem \ -t "test/tls" \ -m "{\"message\": \"Hello TLS!\", \"timestamp\": 1716000000}" \ -u "testuser" \ -P "testpass" \ -d-d 调试输出示例:
Client (null) sending CONNECTClient received CONNACK (0)Client (null) sending PUBLISH (d0, q0, r0, m0, 'test/tls', ... (44 bytes))Client received PUBACK (Mid: 0)Client (null) sending PINGREQClient received PINGRESPTLS 特定调试信息
Section titled “TLS 特定调试信息”# 启用更详细的 TLS 调试mosquitto_sub -h mqtt.example.com \ -p 8883 \ --cafile /opt/mosquitto/certs/fullchain.pem \ -t "test/tls" \ --tls-version tlsv1.2 \ -d -D <tls-verbose>
# 测试不验证证书(跳过 CA 验证)mosquitto_sub -h mqtt.example.com \ -p 8883 \ --insecure \ # 不验证服务器证书 -t "test/tls" \ -d测试参数对照
Section titled “测试参数对照”| 参数 | 用途 | 生产环境 | 开发环境 |
|---|---|---|---|
--cafile | CA 证书文件 | ✅ 必选 | ✅ 推荐 |
--insecure | 跳过证书验证 | ❌ 禁止 | ✅ 允许 |
--tls-version | TLS 版本指定 | tlsv1.2 | tlsv1.2 |
-d | 调试模式 | ✅ | ✅ |
-h | Broker 主机 | 域名 | IP 或域名 |
openssl s_client
Section titled “openssl s_client”TLS 连接诊断
Section titled “TLS 连接诊断”# 完整 TLS 诊断openssl s_client -connect mqtt.example.com:8883 \ -servername mqtt.example.com \ -CAfile /opt/mosquitto/certs/fullchain.pem \ -debug
# 输出包含:# 1. 证书链# 2. SSL 协商参数# 3. 加密套件信息# 4. 会话详情关键输出解读:
# 证书链Certificate chain 0 s:CN = mqtt.example.com ← 服务器证书 i:C = US, O = Let's Encrypt, CN = R3 ← 中间 CA 1 s:C = US, O = Let's Encrypt, CN = R3 ← 中间证书 i:C = US, O = Internet Security Research Group, CN = ISRG Root X1 ← 根 CA
# TLS 参数SSL handshake has read 3333 bytes and written 389 bytes ← 握手数据量
# TLS 版本和加密套件New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 ← 使用 TLS 1.3 + AES-256
# 会话信息Session-ID: A1B2C3D4...Session-ID-ctx:Master-Key: ... ← 会话主密钥(加密)Start Time: 1716000000Timeout : 7200 (sec) ← 会话超时 2 小时Verify return code: 0 (ok) ← ✅ 证书验证通过常见错误诊断
Section titled “常见错误诊断”# 证书过期日期检查openssl s_client -connect mqtt.example.com:8883 \ -servername mqtt.example.com 2>&1 | openssl x509 -noout -dates
# 证书域名验证openssl s_client -connect mqtt.example.com:8883 \ -servername mqtt.example.com 2>&1 | openssl x509 -noout -subject
# TLS 版本兼容性测试# 测试 TLS 1.2openssl s_client -connect mqtt.example.com:8883 -tls1_2# 测试 TLS 1.3openssl s_client -connect mqtt.example.com:8883 -tls1_3Node-RED TLS Test
Section titled “Node-RED TLS Test”Node-RED 中测试 TLS 连接
Section titled “Node-RED 中测试 TLS 连接”// Node-RED Function: 测试 MQTT TLS 连接const mqtt = require('mqtt');
const options = { host: 'mqtt.example.com', port: 8883, protocol: 'mqtts', // 使用 MQTTS 协议 username: 'nodered', password: 'nodered_password', rejectUnauthorized: true, // 验证服务器证书 clientId: 'nodered_tls_test'};
const client = mqtt.connect(options);
client.on('connect', function() { node.warn("MQTT TLS 连接成功!"); client.publish('test/tls', 'Node-RED TLS test'); client.end();});
client.on('error', function(err) { node.error("MQTT TLS 连接失败: " + err.message);});Automated Test Script
Section titled “Automated Test Script”#!/bin/bash# TLS 连接自动化测试脚本
DOMAIN="mqtt.example.com"PORT=8883CAFILE="/opt/mosquitto/certs/fullchain.pem"TEST_TOPIC="test/tls/$(date +%s)"
echo "====================================="echo "MQTT TLS 连接测试"echo "====================================="echo "Broker: ${DOMAIN}:${PORT}"echo "时间: $(date)"echo ""
# 测试 1: 端口可达性echo "[测试 1] 端口可达性..."nc -zv ${DOMAIN} ${PORT} 2>&1if [ $? -eq 0 ]; then echo "✅ 端口可达"else echo "❌ 端口不可达" exit 1fi
# 测试 2: TLS 握手echo ""echo "[测试 2] TLS 握手..."openssl s_client -connect ${DOMAIN}:${PORT} \ -servername ${DOMAIN} -CAfile ${CAFILE} <<< "Q" 2>&1 | \ grep -E "^(New|SSL handshake|Verify return)"if [ $? -eq 0 ]; then echo "✅ TLS 握手成功"else echo "❌ TLS 握手失败"fi
# 测试 3: MQTT 发布/订阅echo ""echo "[测试 3] MQTT 发布/订阅..."# 后台订阅timeout 5 mosquitto_sub -h ${DOMAIN} -p ${PORT} \ --cafile ${CAFILE} -t ${TEST_TOPIC} -d &>/tmp/mqtt_sub.log &SUB_PID=$!sleep 1
# 发布消息mosquitto_pub -h ${DOMAIN} -p ${PORT} \ --cafile ${CAFILE} -t ${TEST_TOPIC} \ -m "TLS test from $(hostname)" -d &>/tmp/mqtt_pub.log
sleep 2kill ${SUB_PID} 2>/dev/null
if grep -q "PUBLISH" /tmp/mqtt_pub.log; then echo "✅ MQTT over TLS 发布成功"else echo "❌ MQTT over TLS 发布失败" cat /tmp/mqtt_pub.logfi
echo ""echo "====================================="echo "测试完成"echo "====================================="Debugging Common Issues
Section titled “Debugging Common Issues”TLS 连接失败排查
Section titled “TLS 连接失败排查”| 症状 | 可能原因 | 诊断命令 | 解决方案 |
|---|---|---|---|
| ”certificate verify failed” | 证书不受信任 | openssl verify | 使用正确 CA 或 --insecure |
| ”connection refused” | 端口未监听 | netstat -tlnp | 检查 Mosquitto 配置 |
| ”no shared cipher” | TLS 版本不兼容 | openssl s_client -tls1_2 | 统一 TLS 版本配置 |
| ”SSL routines:WRONG_VERSION_NUMBER” | 连接了非 TLS 端口 | 确认端口号 | 使用 8883 而非 1883 |
| ”certificate has expired” | 证书过期 | openssl x509 -dates | 运行 certbot renew |
Pre-sales Key Points
Section titled “Pre-sales Key Points”测试方法总结
Section titled “测试方法总结”| 测试工具 | 测试内容 | 适用场景 |
|---|---|---|
| nc / telnet | 端口可达性 | 网络连通性第一关 |
| openssl s_client | TLS 握手详情 | 证书问题诊断 |
| mosquitto_sub/pub | MQTT 功能验证 | 端到端功能测试 |
| Wireshark | 加密流量确认 | 安全合规验证 |
| Node-RED | 生产环境验证 | 集成测试 |
Summary
Section titled “Summary”本节介绍了命令行 TLS 测试方法:
- mosquitto_pub/sub:MQTT TLS 功能测试,
-d调试模式 - openssl s_client:TLS 握手诊断,查看证书链和加密参数
- 自动化测试脚本:端口检查 + TLS 握手 + MQTT 发布订阅
- Node-RED 测试:使用 mqtts:// 协议连接
- 常见问题排查:从端口到证书到 TLS 版本的系统化排查方法