如何自动创建Mosquitto的TLS证书?

MQTT

1 基础知识

1.1 前言

本章将借助第三方的脚本(generate-CA.sh)配置Mosquitto的TLS加密通讯,本章内容包括服务器端与客户端的证书创建以及引用。

1.2 TLS

1.2.1 TLS的介绍

– TLS,即英文Transport Layer Security的缩写,中文翻译为传输层安全协议
– TLS,用于防止两个应用程序通过网络进行数据交换时被窃听和篡改
– TLS,协议采用主从式架构模型(即C/S架构)
– TLS,由两层组成,TLS记录协议(TLS Record)和TLS握手协议(TLS Handshake)
– TLS,优势在于能与应用层协议(如HTTP、FTP、Telnet)无缝耦合

1.2.2 TLS的工作原理

– 客户端请求支持TLS协议的服务器创建安全连接并返回客户端支持的密码组合(加密密码算法和加密哈希函数),即握手开始
– 服务和从客户端提供的列表中选出可用的加密和散列函数,并通知客户端
– 客户端确认服务器颁发的证书是有效的
– 客户端使用服务器的公钥加密随机生成秘钥并发给服务器端(该私钥只能由服务器自己的私钥解密)
– 双方利用随机数生成用于加密和解密的对称秘钥,至此TLS握手结束
注:握手完毕直到连接被关闭的通讯都是安全的通讯连接

2 最佳实践

2.1 环境配置

2.1.1 环境信息

Server,
hostname = mosquitto.cmdschool.org
ip addresses = 10.168.0.91
OS = CentOS 7.6 x86_64

Cient,
hostname = client.cmdschool.org
ip addresses = 10.168.0.8
OS = CentOS 7.6 x86_64

2.1.2 部署服务器端

In Server,
本章假设你已经完成Mosquitto的配置,本章使用的范例是1.5.8版本,
https://www.cmdschool.org/archives/6833
如果需要1.6.3版本请参阅如下文章,
https://www.cmdschool.org/archives/6559

2.1.3 开放服务端口

In Server,

firewall-cmd --permanent --add-port=8883/tcp
firewall-cmd --reload
firewall-cmd --list-all

2.2 创建服务器端证书

In Server,

2.2.1 创建证书临时目录

mkdir ~/autoCA/

2.2.2 下载证书创建脚本

cd ~/autoCA/
wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh

你可使用如下命令查阅脚本的内容,

cat ~/autoCA/generate-CA.sh

脚本内容如下,

#!/usr/bin/env bash
#(@)generate-CA.sh - Create CA key-pair and server key-pair signed by CA

# Copyright (c) 2013-2016 Jan-Piet Mens 
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. Neither the name of mosquitto nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

#
# Usage:
#	./generate-CA.sh		creates ca.crt and server.{key,crt}
#	./generate-CA.sh hostname	creates hostname.{key,crt}
#	./generate-CA.sh client email	creates email.{key,crt}
#
# Set the following optional environment variables before invocation
# to add the specified IP addresses and/or hostnames to the subjAltName list
# These contain white-space-separated values
#
#	IPLIST="172.13.14.15 192.168.1.1"
#	HOSTLIST="a.example.com b.example.com"

set -e

export LANG=C

kind=server

if [ $# -ne 2 ]; then
	kind=server
	host=$(hostname -f)
	if [ -n "$1" ]; then
		host="$1"
	fi
else
	kind=client
	CLIENT="$2"
fi

[ -z "$USER" ] && USER=root

DIR=${TARGET:='.'}
# A space-separated list of alternate hostnames (subjAltName)
# may be empty ""
ALTHOSTNAMES=${HOSTLIST}
ALTADDRESSES=${IPLIST}
CA_ORG='/O=OwnTracks.org/OU=generate-CA/emailAddress=nobody@example.net'
CA_DN="/CN=An MQTT broker${CA_ORG}"
CACERT=${DIR}/ca
SERVER="${DIR}/${host}"
SERVER_DN="/CN=${host}$CA_ORG"
keybits=2048
openssl=$(which openssl)
MOSQUITTOUSER=${MOSQUITTOUSER:=$USER}

# Signature Algorithm. To find out which are supported by your
# version of OpenSSL, run `openssl dgst -help` and set your
# signature algorithm here. For example:
#
#	defaultmd="-sha256"
#
defaultmd="-sha512"

function maxdays() {
	nowyear=$(date +%Y)
	years=$(expr 2032 - $nowyear)
	days=$(expr $years '*' 365)

	echo $days
}

function getipaddresses() {
	/sbin/ifconfig |
		grep -v tunnel |
		sed -En '/inet6? /p' |
		sed -Ee 's/inet6? (addr:)?//' |
		awk '{print $1;}' |
		sed -e 's/[%/].*//' |
		egrep -v '(::1|127\.0\.0\.1)'	# omit loopback to add it later
}


function addresslist() {

	ALIST=""
	for a in $(getipaddresses); do
		ALIST="${ALIST}IP:$a,"
	done
	ALIST="${ALIST}IP:127.0.0.1,IP:::1,"

	for ip in $(echo ${ALTADDRESSES}); do
		ALIST="${ALIST}IP:${ip},"
	done
	for h in $(echo ${ALTHOSTNAMES}); do
		ALIST="${ALIST}DNS:$h,"
	done
	ALIST="${ALIST}DNS:localhost"
	echo $ALIST

}

days=$(maxdays)

if [ -n "$CAKILLFILES" ]; then
	rm -f $CACERT.??? $SERVER.??? $CACERT.srl
fi

if [ ! -f $CACERT.crt ]; then

	#    ____    _    
	#   / ___|  / \   
	#  | |     / _ \  
	#  | |___ / ___ \ 
	#   \____/_/   \_\
	#                 

	# Create un-encrypted (!) key
	$openssl req -newkey rsa:${keybits} -x509 -nodes $defaultmd -days $days -extensions v3_ca -keyout $CACERT.key -out $CACERT.crt -subj "${CA_DN}"
	echo "Created CA certificate in $CACERT.crt"
	$openssl x509 -in $CACERT.crt -nameopt multiline -subject -noout

	chmod 400 $CACERT.key
	chmod 444 $CACERT.crt
	chown $MOSQUITTOUSER $CACERT.*
	echo "Warning: the CA key is not encrypted; store it safely!"
fi


if [ $kind == 'server' ]; then

	#   ____                           
	#  / ___|  ___ _ ____   _____ _ __ 
	#  \___ \ / _ \ '__\ \ / / _ \ '__|
	#   ___) |  __/ |   \ V /  __/ |   
	#  |____/ \___|_|    \_/ \___|_|   
	#                                  

	if [ ! -f $SERVER.key ]; then
		echo "--- Creating server key and signing request"
		$openssl genrsa -out $SERVER.key $keybits
		$openssl req -new $defaultmd \
			-out $SERVER.csr \
			-key $SERVER.key \
			-subj "${SERVER_DN}"
		chmod 400 $SERVER.key
		chown $MOSQUITTOUSER $SERVER.key
	fi

	if [ -f $SERVER.csr -a ! -f $SERVER.crt ]; then

		# There's no way to pass subjAltName on the CLI so
		# create a cnf file and use that.

		CNF=`mktemp /tmp/cacnf.XXXXXXXX` || { echo "$0: can't create temp file" >&2; exit 1; }
		sed -e 's/^.*%%% //' > $CNF <&2; exit 1; }
		# Mosquitto's use_identity_as_username takes the CN attribute
		# so we're populating that with the client's name
		sed -e 's/^.*%%% //' > $CNF <&2; exit 1; }
		sed -e 's/^.*%%% //' > $CNF <<\!ENDClientconfig
		%%% [ JPMclientextensions ]
		%%% basicConstraints        = critical,CA:false
		%%% subjectAltName          = email:copy
		%%% nsCertType              = client,email
		%%% extendedKeyUsage        = clientAuth,emailProtection
		%%% keyUsage                = digitalSignature, keyEncipherment, keyAgreement
		%%% nsComment               = "Client Broker Certificate"
		%%% subjectKeyIdentifier    = hash
		%%% authorityKeyIdentifier  = keyid,issuer:always

!ENDClientconfig

		SUBJALTNAME="$(addresslist)"
		export SUBJALTNAME		# Use environment. Because I can. ;-)

		echo "--- Creating and signing client certificate"
		$openssl x509 -req $defaultmd \
			-in $CLIENT.csr \
			-CA $CACERT.crt \
			-CAkey $CACERT.key \
			-CAcreateserial \
			-CAserial "${DIR}/ca.srl" \
			-out $CLIENT.crt \
			-days $days \
			-extfile ${CNF} \
			-extensions JPMclientextensions

		rm -f $CNF
		chmod 444 $CLIENT.crt
	fi
fi

2.2.3 自定义证书脚本变量

cp ~/autoCA/generate-CA.sh ~/autoCA/generate-CA.sh.default
vim ~/autoCA/generate-CA.sh

启用或修改如下参数,

IPLIST="10.168.0.91"
HOSTLIST="mosquitto.cmdschool.org"
CA_ORG='/O=cmdschool.org/OU=cmdschool/emailAddress=will@cmdschool.org'
CA_DN="/CN=mosquitto.cmdschool.org${CA_ORG}"

注:
– 变量“IPLIST”与“HOSTLIST”应该尽量在正式代码前定义
– 变量“IPLIST”与“HOSTLIST”参数用于声明服务器的IP和域名
– 变量“IPLIST”与“HOSTLIST”需要声明多个参数时,请使用空格分隔

2.2.4 创建服务器端证书

cd ~/autoCA/
sh generate-CA.sh

运行脚本后,你可使用如下命令查看创建的证书,

ls -l ~/autoCA/

可见如下显示,

total 36
-r--r--r--. 1 root root 1326 Aug  9 19:35 ca.crt
-r--------. 1 root root 1704 Aug  9 19:35 ca.key
-rw-r--r--. 1 root root   17 Aug  9 19:35 ca.srl
-rw-r--r--. 1 root root 8711 Aug  9 19:35 generate-CA.sh
-r--r--r--. 1 root root 1887 Aug  9 19:35 mosquitto.cmdschool.org.crt
-rw-r--r--. 1 root root 1021 Aug  9 19:35 mosquitto.cmdschool.org.csr
-r--------. 1 root root 1679 Aug  9 19:35 mosquitto.cmdschool.org.key

证书创建后,我们建议你使用如下命令查看证书的信息,

openssl x509 -in ~/autoCA/ca.crt -nameopt multiline -subject -noout
openssl x509 -in ~/autoCA/mosquitto.cmdschool.org.crt -nameopt multiline -subject -noout

可见如下输出,

subject=
    commonName                = mosquitto.cmdschool.org
    organizationName          = cmdschool.org
    organizationalUnitName    = cmdschool
    emailAddress              = will@cmdschool.org

2.3 配置服务器端证书

In Server,

2.3.1 部署服务器端证书

cd ~/autoCA/
mkdir -p /etc/mosquitto/ca_certificates/
mkdir -p /etc/mosquitto/certs/
cp ca.crt /etc/mosquitto/ca_certificates/
cp mosquitto.cmdschool.org.crt mosquitto.cmdschool.org.key /etc/mosquitto/certs/

证书部署完毕后,我建议你使用以下命令配置证书的安全权限,

chmod 600 /etc/mosquitto/certs/mosquitto.cmdschool.org.key
chown mosquitto:root /etc/mosquitto/certs/mosquitto.cmdschool.org.key

2.3.2 引用服务器端证书

vim /etc/mosquitto/conf.d/tls.conf

加入如下配置,

listener 8883
cafile /etc/mosquitto/ca_certificates/ca.crt
keyfile /etc/mosquitto/certs/mosquitto.cmdschool.org.key
certfile /etc/mosquitto/certs/mosquitto.cmdschool.org.crt
tls_version tlsv1.2

另外,如果要同时保留1883端口,请按如下配置书写,

port 1883

listener 8883
cafile /etc/mosquitto/ca_certificates/ca.crt
keyfile /etc/mosquitto/certs/mosquitto.cmdschool.org.key
certfile /etc/mosquitto/certs/mosquitto.cmdschool.org.crt
tls_version tlsv1.2

需要注意的是,紧跟端口的配置一般只在声明的端口范围内生效,修改完配置后,你需要重启服务使配置生效,

systemctl restart mosquitto.service

重启完毕后,我们建议你检查服务状态,

systemctl status mosquitto.service

并且,查看加密端口的倾听状态,

netstat -antp | grep 8883

如果信息显示如下则正常,

tcp        0      0 0.0.0.0:8883            0.0.0.0:*               LISTEN      8174/mosquitto
tcp6       0      0 :::8883                 :::*                    LISTEN      8174/mosquitto

2.4 服务端自测TLS证书

2.4.1 订阅主题

mosquitto_sub -t 'test/topic' -v --cafile ~/autoCA/ca.crt

注:以上命令启动后会一直倾听,请不要按【Ctrl+C】等键关闭

2.4.2 发布消息

mosquitto_pub -t 'test/topic' -m 'hello world' --cafile ~/autoCA/ca.crt

2.5 配置支持的密码算法

In Server,

2.5.1 列出openSSL的加密算法

openssl ciphers

可见如下输出,

ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DH-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DH-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DH-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DH-DSS-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DH-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DH-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:SEED-SHA:CAMELLIA128-SHA:PSK-AES128-CBC-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:IDEA-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-IDEA-CBC-MD5:KRB5-DES-CBC3-MD5:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:PSK-RC4-SHA:KRB5-RC4-SHA:KRB5-RC4-MD5

2.5.2 声明mosquitto支持的加密算法

vim /etc/mosquitto/conf.d/tls.conf

将上一条命令的输出用“ciphers”参数在配置文件内声明,

ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DH-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DH-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DH-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DH-DSS-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DH-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DH-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:SEED-SHA:CAMELLIA128-SHA:PSK-AES128-CBC-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:IDEA-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-IDEA-CBC-MD5:KRB5-DES-CBC3-MD5:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:PSK-RC4-SHA:KRB5-RC4-SHA:KRB5-RC4-MD5

需要注意的是,以上不一定要全部套用,需要根据你的实际环境和要求决定,修改完配置后,你需要重启服务使配置生效,

systemctl restart mosquitto.service

2.5.3 使用订阅主题验证新配置

mosquitto_sub -t 'test/topic' -v --cafile ~/autoCA/ca.crt

2.5.4 使用发布消息验证新配置

mosquitto_pub -t 'test/topic' -m 'hello world' --cafile ~/autoCA/ca.crt

2.6 非本机测试

2.6.1 部署证书到客户端

In Server,

scp ~/autoCA/ca.crt 10.168.0.8:~

2.6.2 配置客户端的名称解析

In Client,

echo '10.168.0.91 mosquitto.cmdschool.org' >> /etc/hosts

注:以上设置仅适用于测试环境,生产环境中请使用DNS代替

2.6.3 向服务器订阅主题

In Client,

mosquitto_sub -t 'test/topic' -v --cafile ~/ca.crt -h mosquitto.cmdschool.org

2.6.4 向服务器发布消息

In Client,

mosquitto_pub -t 'test/topic' -m 'hello world' --cafile ~/ca.crt -h mosquitto.cmdschool.org

注:
– 参数“-h”指定服务器端的域名
– 以上工具请按服务器的安装方法自行编译安装

2.7 要求验证客户端的证书(可选)

2.7.1 增加服务器端证书参数

In Server,

echo 'require_certificate true' >> /etc/mosquitto/conf.d/tls.conf

修改完配置后,你需要重启服务使配置生效,

systemctl restart mosquitto.service

2.7.2 创建客户端证书

In Server,

cd ~/autoCA/
openssl genrsa -out client.key 2048
openssl req -new \
            -key client.key \
            -subj "/CN=client/O=cmdschool.org" \
            -out client.csr
openssl x509 -req \
             -in client.csr \
             -CA ca.crt \
             -CAserial ca.srl \
             -CAkey ca.key \
             -days 3650 \
             -addtrust clientAuth \
             -out client.crt

注:参数“-addtrust”增加客户端认证成功的关键

2.7.3 部署证书到客户端

In Server,

scp ~/autoCA/ca.crt ~/autoCA/client.crt ~/autoCA/client.key 10.168.0.8:~

2.7.4 订阅主题

In Client,

mosquitto_sub -t 'test/topic' -v --cafile ~/ca.crt --cert ~/client.crt --key ~/client.key  -h mosquitto.cmdschool.org

以上使用“–cert”与“–key”参数向服务器提交客户端证书,如果不使用以上参数,一般会有以下提示,

Error: A TLS error occurred.

2.7.5 发布消息

In Client,

mosquitto_pub -t 'test/topic' -m 'hello world' --cafile ~/ca.crt --cert ~/client.crt --key ~/client.key  -h mosquitto.cmdschool.org

官方文档
====================

官方手册
———–
https://mosquitto.org/man/mosquitto-tls-7.html
https://mosquitto.org/man/mosquitto-conf-5.html
https://mosquitto.org/man/mosquitto_sub-1.html
https://mosquitto.org/man/mosquitto_pub-1.html

知识扩展
———–
https://baike.baidu.com/item/TLS/2979545?fr=aladdin

非官方的参考文章
————–
https://github.com/owntracks/tools/blob/master/TLS/generate-CA.sh
http://rockingdlabs.dunmire.org/exercises-experiments/ssl-client-certs-to-secure-mqtt
https://jpmens.net/2014/07/03/the-mosquitto-mqtt-broker-gets-websockets-support/

没有评论

发表回复

MQTT
如何编译部署Eclipse Mosquitto 2.0.9?

1 MQTT基础知识 1.1 MQTT的概念 – MQTT即英文“Message Que …

MQTT
如何手动配置Mosquitto的TLS?

1 基础知识 1.1 前言 本章将配置Mosquitto的TLS加密通讯,本章内容包括服务器端与客户 …

MQTT
如何编译部署Eclipse Mosquitto的认证插件?

1 基础知识 1.1 插件的介绍 – 插件用于从一个或多个后端为Mosquitto用户做 …