SSL-TLS 双向认证(二) -- 基于mosquittto的MQTT双向认证

来源:互联网 发布:tp3.2商城项目源码 编辑:程序博客网 时间:2024/06/04 23:33

本文部分参考:
https://baike.baidu.com/item/MQTT/3618851?fr=aladdin
https://baike.baidu.com/item/mosquitto

一: MQTT

1.1 MQTT 介绍

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。
MQTT协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:
1、使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合
2、对负载内容屏蔽的消息传输
3、使用 TCP/IP 提供网络连接
4、有三种消息发布服务质量
至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
至少一次”,确保消息到达,但消息重复可能会发生。
只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
5、小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量
6、使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制

1.2 MQTT工作流

这里写图片描述

step 1. 启动 MQTT 服务器

MQTT 服务器是接受 MQTT 客户端的订阅和发布请求的网络实体。开发者可以根据 MQTT 协议规范 设计 MQTT server 和 MQTT client.通常 MQTT server 有很多开源项目提供,于是 MQTT server 默认为 MQTT broker.
MQTT broker: 即MQTT代理
a) MQTT broker 提供 MQTT server服务,处理客户端请求,发送心跳包等。
b) 提供 MQTT client 服务,提供订阅和发布的client端功能
c) 通常运行在处理能力较强的PC上或集群服务器上。
可供选择的MQTT broker有:
a) Mosquitto
b) EMQTT
c) HiveMQ等
d) 各个云平台提供的MQTT服务,如:微软云Azure-MQTT 、亚马逊云Amazon-MQTT等
在本文的二三四节,我们将使用Mosquitto 作为我们的 MQTT broker.

step 2. MQTT 客户端订阅

MQTT subscribe client 将向 MQTT broker订阅一个或者多个主题(topic).以后MQTT broker 收到MQTT publish client 发布消息后,将会向订阅了该主题的 MQTT subscribe client发布该消息。换句话说,如果没有client订阅主题,那么发布者发布消息将毫无意义;如果有很多订阅者,没有发布者,那么订阅也将毫无意义。MQTT订阅端通常是终端设备。

step 3. MQTT客户端发布消息

MQTT publish client 将向 MQTT broker 发布自己的消息,每个消息包含topic和payload.
MQTT broker 根据 topic 将消息转发给感兴趣的 client。
主题名称topic通常是一个简单的字符串,使用分层结构,使用左斜杠分隔。如 /yourhome/livingroom/temperature
有效载荷payload完全依赖于使用场景,他可以是二进制流,也可以是JSON数据。

step 4. MQTT订阅端接受数据

MQTT subscribe client将会收到MQTT broker发给它感兴趣的订阅主题的相关消息,同时进行对应处理。

实例展示

张先生承包了1000个大棚种植作物,每个大棚里面有温度控制系统,不同季节需对不同作物采用不同的温度,如何高效直观来控制这些大棚的温度呢?下面是一种可行高效的解决办法:
张先生为每个大棚配置一颗精致的WiFi芯片,比如ESP32,连接温度控制系统。ESP32支持连接微软云,和微软云交互温度数据。微软云支持MQTT协议,微软云可作为MQTT broker。
每颗ESP32作为 MQTT订阅段,订阅温度信息,比如:

subscribe /plant/peanut/UpdateTemperature

以后张先生可以不用去大棚里面实际操作温度控制系统,只需要在家中,控制手机端APP,发布MQTT消息就可以控制大棚温度。比如:

MQTT publish /plant/peanut/UpdateTemperature "temperature:15"

那么peanut所在大棚的ESP32通过订阅消息MQTT主题,收到15摄氏度的请求后,将这个命令,传到温度控制系统来控制大棚实际温度。同时,张先生也可以通过微软云查看所有大棚的温度变化信息等。这样,真正实现运筹帷幄家中,决胜千里之外。

二: mosquitto

mosquitto是一款很优秀的 MQTT broker.一款实现了消息推送协议 MQTT v3.1 的开源消息代理软件,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单。mosquitto 即可以作为 MQTT Server,也可以作为MQTT client.
mosquitto 下载和安装:
https://mosquitto.org/download/
ubuntu16.04下可直接使用下面方式安装:

$ sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
$ sudo apt-get update
$ sudo apt-get install mosquitto

安装完可查看当前mosquitto版本:

$ mosquitto --help

这里写图片描述

三: mosquitto 服务器 SSL/TLS 配置

3.1 证书生成脚本

同上一篇博客相同http://blog.csdn.net/ustccw/article/details/76691248#t8,使用 makefile.sh 来产生所需的所有SSL/TLS 双向认证文件。rmfile.sh 来删除产生过的文件。
makefile.sh

# * 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.# * Neither the name of the axTLS project 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.### Generate the certificates and keys for testing.#PROJECT_NAME="TLS Project"# Generate the openssl configuration files.cat > ca_cert.conf << EOF  [ req ]distinguished_name     = req_distinguished_nameprompt                 = no[ req_distinguished_name ] O                      = $PROJECT_NAME Dodgy Certificate AuthorityEOFcat > server_cert.conf << EOF  [ req ]distinguished_name     = req_distinguished_nameprompt                 = no[ req_distinguished_name ] O                      = $PROJECT_NAME CN                     = 192.168.111.100EOFcat > client_cert.conf << EOF  [ req ]distinguished_name     = req_distinguished_nameprompt                 = no[ req_distinguished_name ] O                      = $PROJECT_NAME Device Certificate CN                     = 192.168.111.101EOFmkdir camkdir servermkdir clientmkdir certDER# private key generationopenssl genrsa -out ca.key 1024openssl genrsa -out server.key 1024openssl genrsa -out client.key 1024# cert requestsopenssl req -out ca.req -key ca.key -new \            -config ./ca_cert.confopenssl req -out server.req -key server.key -new \            -config ./server_cert.conf openssl req -out client.req -key client.key -new \            -config ./client_cert.conf # generate the actual certs.openssl x509 -req -in ca.req -out ca.crt \            -sha1 -days 5000 -signkey ca.keyopenssl x509 -req -in server.req -out server.crt \            -sha1 -CAcreateserial -days 5000 \            -CA ca.crt -CAkey ca.keyopenssl x509 -req -in client.req -out client.crt \            -sha1 -CAcreateserial -days 5000 \            -CA ca.crt -CAkey ca.keyopenssl x509 -in ca.crt -outform DER -out ca.deropenssl x509 -in server.crt -outform DER -out server.deropenssl x509 -in client.crt -outform DER -out client.dermv ca.crt ca.key ca/mv server.crt server.key server/mv client.crt client.key client/mv ca.der server.der client.der certDER/rm *.confrm *.reqrm *.srl

终端执行:

$./makefile.sh

注意!
a) 将 192.168.111.100 改为你自己的 server 地址
b) 将 192.168.111.101 改为你自己的 client 地址
c) 生成的证书路径需提供给3.2节中 mosquitto.conf 配置

makefile

本地生成双向认证的证书和私钥文件。

rmfile.sh

rm ca/ -rfrm certDER/ -rfrm client/ -rfrm server/ -rf
$./rmfile.sh

删除产生过的TLS相关文件。

3.2 mosquitto.conf 配置

mosquitto配置文件 mosquitto.conf 可以丰富的配置 MQTT broker,如配置 keep-alive时间,配置服务器端口号等。
通常mosquitto安装完,配置文件在 /etc/mosquitto/mosquitto.conf。
如果您没有此文件,需将下面配置文件放在 /etc/mosquitto/ 目录下。
mosquitto.conf

# Config file for mosquitto## See mosquitto.conf(5) for more information.## Default values are shown, uncomment to change.## Use the # character to indicate a comment, but only if it is the # very first character on the line.# =================================================================# General configuration# =================================================================# Time in seconds to wait before resending an outgoing QoS=1 or # QoS=2 message.#retry_interval 20# Time in seconds between updates of the $SYS tree.# Set to 0 to disable the publishing of the $SYS tree.#sys_interval 10# Time in seconds between cleaning the internal message store of # unreferenced messages. Lower values will result in lower memory # usage but more processor time, higher values will have the # opposite effect.# Setting a value of 0 means the unreferenced messages will be # disposed of as quickly as possible.#store_clean_interval 10# Write process id to a file. Default is a blank string which means # a pid file shouldn't be written.# This should be set to /var/run/mosquitto.pid if mosquitto is# being run automatically on boot with an init script and # start-stop-daemon or similar.#pid_file# When run as root, drop privileges to this user and its primary # group.# Leave blank to stay as root, but this is not recommended.# If run as a non-root user, this setting has no effect.# Note that on Windows this has no effect and so mosquitto should # be started by the user you wish it to run as.#user mosquitto# The maximum number of QoS 1 and 2 messages currently inflight per # client.# This includes messages that are partway through handshakes and # those that are being retried. Defaults to 20. Set to 0 for no # maximum. Setting to 1 will guarantee in-order delivery of QoS 1 # and 2 messages.#max_inflight_messages 20# The maximum number of QoS 1 and 2 messages to hold in a queue # above those that are currently in-flight.  Defaults to 100. Set # to 0 for no maximum (not recommended).# See also queue_qos0_messages.#max_queued_messages 100# Set to true to queue messages with QoS 0 when a persistent client is# disconnected. These messages are included in the limit imposed by# max_queued_messages.# Defaults to false.# This is a non-standard option for the MQTT v3.1 spec but is allowed in# v3.1.1.#queue_qos0_messages false# This option sets the maximum publish payload size that the broker will allow.# Received messages that exceed this size will not be accepted by the broker.# The default value is 0, which means that all valid MQTT messages are# accepted. MQTT imposes a maximum payload size of 268435455 bytes. #message_size_limit 0# This option controls whether a client is allowed to connect with a zero# length client id or not. This option only affects clients using MQTT v3.1.1# and later. If set to false, clients connecting with a zero length client id# are disconnected. If set to true, clients will be allocated a client id by# the broker. This means it is only useful for clients with clean session set# to true.#allow_zero_length_clientid true# If allow_zero_length_clientid is true, this option allows you to set a prefix# to automatically generated client ids to aid visibility in logs.#auto_id_prefix# This option allows persistent clients (those with clean session set to false)# to be removed if they do not reconnect within a certain time frame.## This is a non-standard option in MQTT V3.1 but allowed in MQTT v3.1.1.## Badly designed clients may set clean session to false whilst using a randomly# generated client id. This leads to persistent clients that will never# reconnect. This option allows these clients to be removed.## The expiration period should be an integer followed by one of h d w m y for# hour, day, week, month and year respectively. For example## persistent_client_expiration 2m# persistent_client_expiration 14d# persistent_client_expiration 1y## The default if not set is to never expire persistent clients.#persistent_client_expiration# If a client is subscribed to multiple subscriptions that overlap, e.g. foo/## and foo/+/baz , then MQTT expects that when the broker receives a message on# a topic that matches both subscriptions, such as foo/bar/baz, then the client# should only receive the message once.# Mosquitto keeps track of which clients a message has been sent to in order to# meet this requirement. The allow_duplicate_messages option allows this# behaviour to be disabled, which may be useful if you have a large number of# clients subscribed to the same set of topics and are very concerned about# minimising memory usage.# It can be safely set to true if you know in advance that your clients will# never have overlapping subscriptions, otherwise your clients must be able to# correctly deal with duplicate messages even when then have QoS=2.#allow_duplicate_messages false# The MQTT specification requires that the QoS of a message delivered to a# subscriber is never upgraded to match the QoS of the subscription. Enabling# this option changes this behaviour. If upgrade_outgoing_qos is set true,# messages sent to a subscriber will always match the QoS of its subscription.# This is a non-standard option explicitly disallowed by the spec.#upgrade_outgoing_qos false# =================================================================# Default listener# =================================================================# IP address/hostname to bind the default listener to. If not# given, the default listener will not be bound to a specific # address and so will be accessible to all network interfaces.# bind_address ip-address/host name#bind_address# Port to use for the default listener.port 8883# The maximum number of client connections to allow. This is # a per listener setting.# Default is -1, which means unlimited connections.# Note that other process limits mean that unlimited connections # are not really possible. Typically the default maximum number of # connections possible is around 1024.#max_connections -1# Choose the protocol to use when listening.# This can be either mqtt or websockets.# Websockets support is currently disabled by default at compile time.# Certificate based TLS may be used with websockets, except that# only the cafile, certfile, keyfile and ciphers options are supported.#protocol mqtt# When a listener is using the websockets protocol, it is possible to serve# http data as well. Set http_dir to a directory which contains the files you# wish to serve. If this option is not specified, then no normal http# connections will be possible.#http_dir# Set use_username_as_clientid to true to replace the clientid that a client# connected with with its username. This allows authentication to be tied to# the clientid, which means that it is possible to prevent one client# disconnecting another by using the same clientid.# If a client connects with no username it will be disconnected as not# authorised when this option is set to true.# Do not use in conjunction with clientid_prefixes.# See also use_identity_as_username.#use_username_as_clientid# -----------------------------------------------------------------# Certificate based SSL/TLS support# -----------------------------------------------------------------# The following options can be used to enable SSL/TLS support for # this listener. Note that the recommended port for MQTT over TLS# is 8883, but this must be set manually.## See also the mosquitto-tls man page.# At least one of cafile or capath must be defined. They both # define methods of accessing the PEM encoded Certificate # Authority certificates that have signed your server certificate # and that you wish to trust.# cafile defines the path to a file containing the CA certificates.# capath defines a directory that will be searched for files# containing the CA certificates. For capath to work correctly, the# certificate files must have ".crt" as the file ending and you must run# "c_rehash <path to capath>" each time you add/remove a certificate.cafile /home/chenwu/TLSDir/ca/ca.crt#capath# Path to the PEM encoded server certificate.certfile /home/chenwu/TLSDir/server/server.crt# Path to the PEM encoded keyfile.keyfile /home/chenwu/TLSDir/server/server.key# This option defines the version of the TLS protocol to use for this listener.# The default value allows v1.2, v1.1 and v1.0, if they are all supported by# the version of openssl that the broker was compiled against. For openssl >=# 1.0.1 the valid values are tlsv1.2 tlsv1.1 and tlsv1. For openssl < 1.0.1 the# valid values are tlsv1.#tls_version# By default a TLS enabled listener will operate in a similar fashion to a# https enabled web server, in that the server has a certificate signed by a CA# and the client will verify that it is a trusted certificate. The overall aim# is encryption of the network traffic. By setting require_certificate to true,# the client must provide a valid certificate in order for the network# connection to proceed. This allows access to the broker to be controlled# outside of the mechanisms provided by MQTT.require_certificate true# If require_certificate is true, you may set use_identity_as_username to true# to use the CN value from the client certificate as a username. If this is# true, the password_file option will not be used for this listener.use_identity_as_username true# If you have require_certificate set to true, you can create a certificate# revocation list file to revoke access to particular client certificates. If# you have done this, use crlfile to point to the PEM encoded revocation file.#crlfile# If you wish to control which encryption ciphers are used, use the ciphers# option. The list of available ciphers can be optained using the "openssl# ciphers" command and should be provided in the same format as the output of# that command.# If unset defaults to DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH#ciphers DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH# -----------------------------------------------------------------# Pre-shared-key based SSL/TLS support# -----------------------------------------------------------------# The following options can be used to enable PSK based SSL/TLS support for# this listener. Note that the recommended port for MQTT over TLS is 8883, but# this must be set manually.## See also the mosquitto-tls man page and the "Certificate based SSL/TLS# support" section. Only one of certificate or PSK encryption support can be# enabled for any listener.# The psk_hint option enables pre-shared-key support for this listener and also# acts as an identifier for this listener. The hint is sent to clients and may# be used locally to aid authentication. The hint is a free form string that# doesn't have much meaning in itself, so feel free to be creative.# If this option is provided, see psk_file to define the pre-shared keys to be# used or create a security plugin to handle them.#psk_hint# Set use_identity_as_username to have the psk identity sent by the client used# as its username. Authentication will be carried out using the PSK rather than# the MQTT username/password and so password_file will not be used for this# listener.#use_identity_as_username false# When using PSK, the encryption ciphers used will be chosen from the list of# available PSK ciphers. If you want to control which ciphers are available,# use the "ciphers" option.  The list of available ciphers can be optained# using the "openssl ciphers" command and should be provided in the same format# as the output of that command.#ciphers# =================================================================# Extra listeners# =================================================================# Listen on a port/ip address combination. By using this variable # multiple times, mosquitto can listen on more than one port. If # this variable is used and neither bind_address nor port given, # then the default listener will not be started.# The port number to listen on must be given. Optionally, an ip # address or host name may be supplied as a second argument. In # this case, mosquitto will attempt to bind the listener to that # address and so restrict access to the associated network and # interface. By default, mosquitto will listen on all interfaces.# Note that for a websockets listener it is not possible to bind to a host# name.# listener port-number [ip address/host name]#listener# The maximum number of client connections to allow. This is # a per listener setting.# Default is -1, which means unlimited connections.# Note that other process limits mean that unlimited connections # are not really possible. Typically the default maximum number of # connections possible is around 1024.#max_connections -1# The listener can be restricted to operating within a topic hierarchy using# the mount_point option. This is achieved be prefixing the mount_point string# to all topics for any clients connected to this listener. This prefixing only# happens internally to the broker; the client will not see the prefix.#mount_point# Choose the protocol to use when listening.# This can be either mqtt or websockets.# Certificate based TLS may be used with websockets, except that only the# cafile, certfile, keyfile and ciphers options are supported.#protocol mqtt# When a listener is using the websockets protocol, it is possible to serve# http data as well. Set http_dir to a directory which contains the files you# wish to serve. If this option is not specified, then no normal http# connections will be possible.#http_dir# Set use_username_as_clientid to true to replace the clientid that a client# connected with with its username. This allows authentication to be tied to# the clientid, which means that it is possible to prevent one client# disconnecting another by using the same clientid.# If a client connects with no username it will be disconnected as not# authorised when this option is set to true.# Do not use in conjunction with clientid_prefixes.# See also use_identity_as_username.#use_username_as_clientid# -----------------------------------------------------------------# Certificate based SSL/TLS support# -----------------------------------------------------------------# The following options can be used to enable certificate based SSL/TLS support# for this listener. Note that the recommended port for MQTT over TLS is 8883,# but this must be set manually.## See also the mosquitto-tls man page and the "Pre-shared-key based SSL/TLS# support" section. Only one of certificate or PSK encryption support can be# enabled for any listener.# At least one of cafile or capath must be defined to enable certificate based# TLS encryption. They both define methods of accessing the PEM encoded# Certificate Authority certificates that have signed your server certificate# and that you wish to trust.# cafile defines the path to a file containing the CA certificates.# capath defines a directory that will be searched for files# containing the CA certificates. For capath to work correctly, the# certificate files must have ".crt" as the file ending and you must run# "c_rehash <path to capath>" each time you add/remove a certificate.#cafile#capath# Path to the PEM encoded server certificate.#certfile# Path to the PEM encoded keyfile.#keyfile# By default an TLS enabled listener will operate in a similar fashion to a# https enabled web server, in that the server has a certificate signed by a CA# and the client will verify that it is a trusted certificate. The overall aim# is encryption of the network traffic. By setting require_certificate to true,# the client must provide a valid certificate in order for the network# connection to proceed. This allows access to the broker to be controlled# outside of the mechanisms provided by MQTT.#require_certificate false# If require_certificate is true, you may set use_identity_as_username to true# to use the CN value from the client certificate as a username. If this is# true, the password_file option will not be used for this listener.#use_identity_as_username false# If you have require_certificate set to true, you can create a certificate# revocation list file to revoke access to particular client certificates. If# you have done this, use crlfile to point to the PEM encoded revocation file.#crlfile# If you wish to control which encryption ciphers are used, use the ciphers# option. The list of available ciphers can be optained using the "openssl# ciphers" command and should be provided in the same format as the output of# that command.#ciphers# -----------------------------------------------------------------# Pre-shared-key based SSL/TLS support# -----------------------------------------------------------------# The following options can be used to enable PSK based SSL/TLS support for# this listener. Note that the recommended port for MQTT over TLS is 8883, but# this must be set manually.## See also the mosquitto-tls man page and the "Certificate based SSL/TLS# support" section. Only one of certificate or PSK encryption support can be# enabled for any listener.# The psk_hint option enables pre-shared-key support for this listener and also# acts as an identifier for this listener. The hint is sent to clients and may# be used locally to aid authentication. The hint is a free form string that# doesn't have much meaning in itself, so feel free to be creative.# If this option is provided, see psk_file to define the pre-shared keys to be# used or create a security plugin to handle them.#psk_hint# Set use_identity_as_username to have the psk identity sent by the client used# as its username. Authentication will be carried out using the PSK rather than# the MQTT username/password and so password_file will not be used for this# listener.#use_identity_as_username false# When using PSK, the encryption ciphers used will be chosen from the list of# available PSK ciphers. If you want to control which ciphers are available,# use the "ciphers" option.  The list of available ciphers can be optained# using the "openssl ciphers" command and should be provided in the same format# as the output of that command.#ciphers# =================================================================# Persistence# =================================================================# If persistence is enabled, save the in-memory database to disk # every autosave_interval seconds. If set to 0, the persistence # database will only be written when mosquitto exits. See also# autosave_on_changes.# Note that writing of the persistence database can be forced by # sending mosquitto a SIGUSR1 signal.#autosave_interval 1800# If true, mosquitto will count the number of subscription changes, retained# messages received and queued messages and if the total exceeds# autosave_interval then the in-memory database will be saved to disk.# If false, mosquitto will save the in-memory database to disk by treating# autosave_interval as a time in seconds.#autosave_on_changes false# Save persistent message data to disk (true/false).# This saves information about all messages, including # subscriptions, currently in-flight messages and retained # messages.# retained_persistence is a synonym for this option.#persistence false# The filename to use for the persistent database, not including # the path.#persistence_file mosquitto.db# Location for persistent database. Must include trailing /# Default is an empty string (current directory).# Set to e.g. /var/lib/mosquitto/ if running as a proper service on Linux or# similar.#persistence_location# =================================================================# Logging# =================================================================# Places to log to. Use multiple log_dest lines for multiple # logging destinations.# Possible destinations are: stdout stderr syslog topic file## stdout and stderr log to the console on the named output.## syslog uses the userspace syslog facility which usually ends up # in /var/log/messages or similar.## topic logs to the broker topic '$SYS/broker/log/<severity>', # where severity is one of D, E, W, N, I, M which are debug, error, # warning, notice, information and message. Message type severity is used by# the subscribe/unsubscribe log_types and publishes log messages to# $SYS/broker/log/M/susbcribe or $SYS/broker/log/M/unsubscribe.## The file destination requires an additional parameter which is the file to be# logged to, e.g. "log_dest file /var/log/mosquitto.log". The file will be# closed and reopened when the broker receives a HUP signal. Only a single file# destination may be configured.## Note that if the broker is running as a Windows service it will default to# "log_dest none" and neither stdout nor stderr logging is available.# Use "log_dest none" if you wish to disable logging.#log_dest stderr# If using syslog logging (not on Windows), messages will be logged to the# "daemon" facility by default. Use the log_facility option to choose which of# local0 to local7 to log to instead. The option value should be an integer# value, e.g. "log_facility 5" to use local5.#log_facility# Types of messages to log. Use multiple log_type lines for logging# multiple types of messages.# Possible types are: debug, error, warning, notice, information, # none, subscribe, unsubscribe, websockets, all.# Note that debug type messages are for decoding the incoming/outgoing# network packets. They are not logged in "topics".#log_type error#log_type warning#log_type notice#log_type information# Change the websockets logging level. This is a global option, it is not# possible to set per listener. This is an integer that is interpreted by# libwebsockets as a bit mask for its lws_log_levels enum. See the# libwebsockets documentation for more details. "log_type websockets" must also# be enabled.#websockets_log_level 0# If set to true, client connection and disconnection messages will be included# in the log.#connection_messages true# If set to true, add a timestamp value to each log message.#log_timestamp true# =================================================================# Security# =================================================================# If set, only clients that have a matching prefix on their # clientid will be allowed to connect to the broker. By default, # all clients may connect.# For example, setting "secure-" here would mean a client "secure-# client" could connect but another with clientid "mqtt" couldn't.#clientid_prefixes# Boolean value that determines whether clients that connect # without providing a username are allowed to connect. If set to # false then a password file should be created (see the # password_file option) to control authenticated client access. # Defaults to true.#allow_anonymous true# In addition to the clientid_prefixes, allow_anonymous and TLS # authentication options, username based authentication is also # possible. The default support is described in "Default # authentication and topic access control" below. The auth_plugin # allows another authentication method to be used.# Specify the path to the loadable plugin and see the # "Authentication and topic access plugin options" section below.#auth_plugin# If auth_plugin_deny_special_chars is true, the default, then before an ACL# check is made, the username/client id of the client needing the check is# searched for the presence of either a '+' or '#' character. If either of# these characters is found in either the username or client id, then the ACL# check is denied before it is sent to the plugin.o## This check prevents the case where a malicious user could circumvent an ACL# check by using one of these characters as their username or client id. This# is the same issue as was reported with mosquitto itself as CVE-2017-7650.## If you are entirely sure that the plugin you are using is not vulnerable to# this attack (i.e. if you never use usernames or client ids in topics) then# you can disable this extra check and have all ACL checks delivered to your# plugin by setting auth_plugin_deny_special_chars to false.#auth_plugin_deny_special_chars true# -----------------------------------------------------------------# Default authentication and topic access control# -----------------------------------------------------------------# Control access to the broker using a password file. This file can be# generated using the mosquitto_passwd utility. If TLS support is not compiled# into mosquitto (it is recommended that TLS support should be included) then# plain text passwords are used, in which case the file should be a text file# with lines in the format:# username:password# The password (and colon) may be omitted if desired, although this # offers very little in the way of security.# # See the TLS client require_certificate and use_identity_as_username options# for alternative authentication options.#password_file# Access may also be controlled using a pre-shared-key file. This requires# TLS-PSK support and a listener configured to use it. The file should be text# lines in the format:# identity:key# The key should be in hexadecimal format without a leading "0x".#psk_file# Control access to topics on the broker using an access control list# file. If this parameter is defined then only the topics listed will# have access.# If the first character of a line of the ACL file is a # it is treated as a# comment.# Topic access is added with lines of the format:## topic [read|write|readwrite] <topic># # The access type is controlled using "read", "write" or "readwrite". This# parameter is optional (unless <topic> contains a space character) - if not# given then the access is read/write.  <topic> can contain the + or ## wildcards as in subscriptions.# # The first set of topics are applied to anonymous clients, assuming# allow_anonymous is true. User specific topic ACLs are added after a # user line as follows:## user <username>## The username referred to here is the same as in password_file. It is# not the clientid.### If is also possible to define ACLs based on pattern substitution within the# topic. The patterns available for substition are:## %c to match the client id of the client# %u to match the username of the client## The substitution pattern must be the only text for that level of hierarchy.## The form is the same as for the topic keyword, but using pattern as the# keyword.# Pattern ACLs apply to all users even if the "user" keyword has previously# been given.## If using bridges with usernames and ACLs, connection messages can be allowed# with the following pattern:# pattern write $SYS/broker/connection/%c/state## pattern [read|write|readwrite] <topic>## Example:## pattern write sensor/%u/data##acl_file# -----------------------------------------------------------------# Authentication and topic access plugin options# -----------------------------------------------------------------# If the auth_plugin option above is used, define options to pass to the# plugin here as described by the plugin instructions. All options named# using the format auth_opt_* will be passed to the plugin, for example:## auth_opt_db_host# auth_opt_db_port # auth_opt_db_username# auth_opt_db_password# =================================================================# Bridges# =================================================================# A bridge is a way of connecting multiple MQTT brokers together.# Create a new bridge using the "connection" option as described below. Set# options for the bridges using the remaining parameters. You must specify the# address and at least one topic to subscribe to.# Each connection must have a unique name.# The address line may have multiple host address and ports specified. See# below in the round_robin description for more details on bridge behaviour if# multiple addresses are used.# The direction that the topic will be shared can be chosen by # specifying out, in or both, where the default value is out. # The QoS level of the bridged communication can be specified with the next# topic option. The default QoS level is 0, to change the QoS the topic# direction must also be given.# The local and remote prefix options allow a topic to be remapped when it is# bridged to/from the remote broker. This provides the ability to place a topic# tree in an appropriate location. # For more details see the mosquitto.conf man page.# Multiple topics can be specified per connection, but be careful # not to create any loops.# If you are using bridges with cleansession set to false (the default), then# you may get unexpected behaviour from incoming topics if you change what# topics you are subscribing to. This is because the remote broker keeps the# subscription for the old topic. If you have this problem, connect your bridge# with cleansession set to true, then reconnect with cleansession set to false# as normal.#connection <name>#address <host>[:<port>] [<host>[:<port>]]#topic <topic> [[[out | in | both] qos-level] local-prefix remote-prefix]# Set the version of the MQTT protocol to use with for this bridge. Can be one# of mqttv31 or mqttv311. Defaults to mqttv31.#bridge_protocol_version mqttv31# If a bridge has topics that have "out" direction, the default behaviour is to# send an unsubscribe request to the remote broker on that topic. This means# that changing a topic direction from "in" to "out" will not keep receiving# incoming messages. Sending these unsubscribe requests is not always# desirable, setting bridge_attempt_unsubscribe to false will disable sending# the unsubscribe request.#bridge_attempt_unsubscribe true# If the bridge has more than one address given in the address/addresses# configuration, the round_robin option defines the behaviour of the bridge on# a failure of the bridge connection. If round_robin is false, the default# value, then the first address is treated as the main bridge connection. If# the connection fails, the other secondary addresses will be attempted in# turn. Whilst connected to a secondary bridge, the bridge will periodically# attempt to reconnect to the main bridge until successful.# If round_robin is true, then all addresses are treated as equals. If a# connection fails, the next address will be tried and if successful will# remain connected until it fails#round_robin false# Set the client id to use on the remote end of this bridge connection. If not# defined, this defaults to 'name.hostname' where name is the connection name# and hostname is the hostname of this computer.# This replaces the old "clientid" option to avoid confusion. "clientid"# remains valid for the time being.#remote_clientid# Set the clientid to use on the local broker. If not defined, this defaults to# 'local.<clientid>'. If you are bridging a broker to itself, it is important# that local_clientid and clientid do not match.#local_clientid# Set the clean session variable for this bridge.# When set to true, when the bridge disconnects for any reason, all # messages and subscriptions will be cleaned up on the remote # broker. Note that with cleansession set to true, there may be a # significant amount of retained messages sent when the bridge # reconnects after losing its connection.# When set to false, the subscriptions and messages are kept on the # remote broker, and delivered when the bridge reconnects.#cleansession false# If set to true, publish notification messages to the local and remote brokers# giving information about the state of the bridge connection. Retained# messages are published to the topic $SYS/broker/connection/<clientid>/state# unless the notification_topic option is used.# If the message is 1 then the connection is active, or 0 if the connection has# failed.#notifications true# Choose the topic on which notification messages for this bridge are# published. If not set, messages are published on the topic# $SYS/broker/connection/<clientid>/state#notification_topic # Set the keepalive interval for this bridge connection, in # seconds.#keepalive_interval 60# Set the start type of the bridge. This controls how the bridge starts and# can be one of three types: automatic, lazy and once. Note that RSMB provides# a fourth start type "manual" which isn't currently supported by mosquitto.## "automatic" is the default start type and means that the bridge connection# will be started automatically when the broker starts and also restarted# after a short delay (30 seconds) if the connection fails.## Bridges using the "lazy" start type will be started automatically when the# number of queued messages exceeds the number set with the "threshold"# parameter. It will be stopped automatically after the time set by the# "idle_timeout" parameter. Use this start type if you wish the connection to# only be active when it is needed.## A bridge using the "once" start type will be started automatically when the# broker starts but will not be restarted if the connection fails.#start_type automatic# Set the amount of time a bridge using the automatic start type will wait# until attempting to reconnect.  Defaults to 30 seconds.#restart_timeout 30# Set the amount of time a bridge using the lazy start type must be idle before# it will be stopped. Defaults to 60 seconds.#idle_timeout 60# Set the number of messages that need to be queued for a bridge with lazy# start type to be restarted. Defaults to 10 messages.# Must be less than max_queued_messages.#threshold 10# If try_private is set to true, the bridge will attempt to indicate to the# remote broker that it is a bridge not an ordinary client. If successful, this# means that loop detection will be more effective and that retained messages# will be propagated correctly. Not all brokers support this feature so it may# be necessary to set try_private to false if your bridge does not connect# properly.#try_private true# Set the username to use when connecting to a broker that requires# authentication.# This replaces the old "username" option to avoid confusion. "username"# remains valid for the time being.#remote_username# Set the password to use when connecting to a broker that requires# authentication. This option is only used if remote_username is also set.# This replaces the old "password" option to avoid confusion. "password"# remains valid for the time being.#remote_password# -----------------------------------------------------------------# Certificate based SSL/TLS support# -----------------------------------------------------------------# Either bridge_cafile or bridge_capath must be defined to enable TLS support# for this bridge.# bridge_cafile defines the path to a file containing the# Certificate Authority certificates that have signed the remote broker# certificate.# bridge_capath defines a directory that will be searched for files containing# the CA certificates. For bridge_capath to work correctly, the certificate# files must have ".crt" as the file ending and you must run "c_rehash <path to# capath>" each time you add/remove a certificate.#bridge_cafile#bridge_capath# Path to the PEM encoded client certificate, if required by the remote broker.#bridge_certfile# Path to the PEM encoded client private key, if required by the remote broker.#bridge_keyfile# When using certificate based encryption, bridge_insecure disables# verification of the server hostname in the server certificate. This can be# useful when testing initial server configurations, but makes it possible for# a malicious third party to impersonate your server through DNS spoofing, for# example. Use this option in testing only. If you need to resort to using this# option in a production environment, your setup is at fault and there is no# point using encryption.#bridge_insecure false# -----------------------------------------------------------------# PSK based SSL/TLS support# -----------------------------------------------------------------# Pre-shared-key encryption provides an alternative to certificate based# encryption. A bridge can be configured to use PSK with the bridge_identity# and bridge_psk options. These are the client PSK identity, and pre-shared-key# in hexadecimal format with no "0x". Only one of certificate and PSK based# encryption can be used on one# bridge at once.#bridge_identity#bridge_psk# =================================================================# External config files# =================================================================# External configuration files may be included by using the # include_dir option. This defines a directory that will be searched# for config files. All files that end in '.conf' will be loaded as# a configuration file. It is best to have this as the last option# in the main file. This option will only be processed from the main# configuration file. The directory specified must not contain the # main configuration file.#include_dir# =================================================================# rsmb options - unlikely to ever be supported# =================================================================#ffdc_output#max_log_entries#trace_level#trace_output

注意!!!
根据单向认证和双向认证需要,可能需修改的字段有:
a) port 8883 // MQTT服务器将选择此端口 listen
b) cafile /home/chenwu/TLSDir/ca/ca.crt

  • 双向认证必须配置为你的CA证书
  • 单向认证(通常认为是client校验server证书,下同)可选配置
    单向认证中,server 和 client 端 ca 配置必须保持一致。即 server 若配置 ca.crt ,则 client 必须配置 ca.crt, server 不配置ca.crt ,client 也不可配置 ca.crt
  • 路径必须为绝对路径!!!

c) certfile /home/chenwu/TLSDir/server/server.crt

  • 单项认证和双向认证都必须配置为你的server证书

d) keyfile /home/chenwu/TLSDir/server/server.key

  • 单项认证和双向认证都必须配置为你的server私钥

e) require_certificate true

  • 单向认证需设置为 false,注释此行,默认也是 false

  • 双向认证必须配置为true

f) use_identity_as_username true

  • 单向认证设置为 false,注释此行,默认也是 false

  • 双向认证通常设置为true

本人双向认证的mosquitto.conf 配置如下:
双向认证

单向认证只需要注释下面两行即可:

#require_certificate true#use_identity_as_username true

3.3 MQTT 双向认证 server 启动

我们将Ubuntu作为我们的server:

mosquittostart

-c /etc/mosquitto/mosquitto.conf //设置mosquitto配置文件
-v // 调试模式,可查看更多的log信息
mosquitto 版本: 1.4.14
listen 端口: 8883

四: mosquitto 客户端SSL/TLS配置

4.1 MQTT订阅段设置

我们将Ubuntu作为我们的subscribe client,直接shell中订阅:

$mosquitto_sub -h 192.168.111.100 -p 8883 -t "/plant/peanut/UpdateTemperature" --cafile /home/chenwu/TLSDir/ca/ca.crt --cert /home/chenwu/TLSDir/client/client.crt --key /home/chenwu/TLSDir/client/client.key

mosquitto_sub 订阅
-h 订阅MQTT broker 的 IP地址
-p 端口号
-t topic 订阅主题
–cafile CA证书位置
–cert client证书位置 // 单向认证中不需要此字段
–key client私钥位置 // 单向认证中不需要此字段

结果如下图:
在订阅消息之后,会收到来自4.2节publish client发布的消息.

temperature:15

这里写图片描述

4.2 MQTT发布端设置

我们同样将Ubuntu作为我们的发布端,shell中publish MQTT消息

 $mosquitto_pub -h 192.168.111.100 -p 8883 -t "/plant/peanut/UpdateTemperature" -m "temperature:15"  --cafile /home/chenwu/TLSDir/ca/ca.crt --cert /home/chenwu/TLSDir/client/client.crt --key /home/chenwu/TLSDir/client/client.key

-h MQTT broker 主机的IP地址
-p MQTT broker listen的端口号
-t 发布主题topic
-m 发布消息message
–cafile CA证书文件,pem格式
–cert client证书文件 // 单向认证不需要此字段
–key client私钥文件 // 单向认证不需要此字段

如图:
这里写图片描述

4.3 MQTT broker 状态

这里写图片描述

New client connected from 192.168.111.100 as mosqsub…//订阅段连接
New client connected from 192.168.111.100 as mosqpub… //发布端连接
Sending PINGRESP to mosqsub|13652-chenwu // 发送心跳包
Received PINGREQ from mosqsub|13652-chenwu //收到心跳包

阅读全文
1 0
原创粉丝点击