跳转到内容

CLI TLS 测试

CLI TLS 测试

本节介绍使用命令行工具测试 MQTT TLS 连接的方法。命令行测试是验证 TLS 配置是否正确的最直接方式。学习完成后,您将能够:

  • 使用 mosquitto_pub/sub 测试 TLS 连接
  • 使用 openssl s_client 诊断 TLS 问题
  • 使用 Wireshark 验证 MQTT 加密
  • 排查 TLS 连接常见问题

在开始本节之前,请确保:

  • Mosquitto TLS 已配置并运行
  • 证书文件已就位
  • 安装 mosquitto 客户端工具
  • 安装 openssl 工具
Terminal window
# Ubuntu/Debian 安装 mosquitto 客户端
sudo apt install mosquitto-clients
# macOS 安装
brew install mosquitto
# 验证安装
mosquitto_pub --help
mosquitto_sub --help
Terminal window
# 订阅测试 Topic
mosquitto_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 CONNECT
Client received CONNACK (0)
Client (null) sending PUBLISH (d0, q0, r0, m0, 'test/tls', ... (44 bytes))
Client received PUBACK (Mid: 0)
Client (null) sending PINGREQ
Client received PINGRESP
Terminal window
# 启用更详细的 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
参数用途生产环境开发环境
--cafileCA 证书文件✅ 必选✅ 推荐
--insecure跳过证书验证❌ 禁止✅ 允许
--tls-versionTLS 版本指定tlsv1.2tlsv1.2
-d调试模式
-hBroker 主机域名IP 或域名
Terminal window
# 完整 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: 1716000000
Timeout : 7200 (sec) ← 会话超时 2 小时
Verify return code: 0 (ok) ← ✅ 证书验证通过
Terminal window
# 证书过期日期检查
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.2
openssl s_client -connect mqtt.example.com:8883 -tls1_2
# 测试 TLS 1.3
openssl s_client -connect mqtt.example.com:8883 -tls1_3
// 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);
});
/usr/local/bin/test-mqtt-tls.sh
#!/bin/bash
# TLS 连接自动化测试脚本
DOMAIN="mqtt.example.com"
PORT=8883
CAFILE="/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>&1
if [ $? -eq 0 ]; then
echo "✅ 端口可达"
else
echo "❌ 端口不可达"
exit 1
fi
# 测试 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 2
kill ${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.log
fi
echo ""
echo "====================================="
echo "测试完成"
echo "====================================="
症状可能原因诊断命令解决方案
”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
测试工具测试内容适用场景
nc / telnet端口可达性网络连通性第一关
openssl s_clientTLS 握手详情证书问题诊断
mosquitto_sub/pubMQTT 功能验证端到端功能测试
Wireshark加密流量确认安全合规验证
Node-RED生产环境验证集成测试

本节介绍了命令行 TLS 测试方法:

  1. mosquitto_pub/sub:MQTT TLS 功能测试,-d 调试模式
  2. openssl s_client:TLS 握手诊断,查看证书链和加密参数
  3. 自动化测试脚本:端口检查 + TLS 握手 + MQTT 发布订阅
  4. Node-RED 测试:使用 mqtts:// 协议连接
  5. 常见问题排查:从端口到证书到 TLS 版本的系统化排查方法