mqtt搭建与加密
安装与访问控制
通过yum安装
配置 EMQX Yum 源
curl -s https://assets.emqx.com/scripts/install-emqx-rpm.sh | sudo bash
安装 EMQX
sudo yum install emqx -y
启动 EMQX
sudo systemctl start emqx
sudo systemctl stop emqx
sudo systemctl restart emqx
通过 Docker 运行单个 EMQX 节点
本节主要介绍如何通过 Docker 镜像安装最新版本的 EMQX,如希望体验其他版本,可以前往 EMQX 下载页面 (opens new window)。
运行以下命令获取 Docker 镜像:
docker pull emqx/emqx:5.1.0
1
运行以下命令启动 Docker 容器
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.1.0
3.进行访问控制,使用内置数据库进行密码认证(此项开启就无法使用匿名访问)
EMQX 通过内置数据库为用户提供了一种低成本、开箱即用的密码认证方式。启用后,EMQX 会将内置的 Mnesia 数据库存储客户端身份凭据,并通过 REST API 与 Dashboard 进行数据管理,本节将向您介绍如何通过 Dashboard 或配置项进行相关配置。
前置准备:
熟悉 EMQX 认证基本概念
#通过 Dashboard 配置
您可以使用 Dashboard 来创建通过内置数据库进行密码认证。
在 EMQX Dashboard (opens new window)页面,点击左侧导航栏的访问控制 -> 认证,在随即打开的认证页面,单击创建,依次选择认证方式为 Password-Based
,数据源为 Built-in Database
,进入配置参数页签:
账号类型:指定用于客户端身份 ID 认证的字段,可选值: username
、 clientid
(分别对应于 MQTT 客户端 CONNECT
报文中的 Username
和 Client Identifier
字段)。
密码加密方式:选择存储密码时使用的散列算法,如 plain、md5、sha、bcrypt、pbkdf2 等。
选择 plain、md5、sha、sha256 或 sha512 算法,需配置:
加盐方式:用于指定盐和密码的组合方式,除需将访问凭据从外部存储迁移到 EMQX 内置数据库中外,一般不需要更改此选项;可选值:suffix(在密码尾部加盐)、prefix(在密码头部加盐)、disable(不启用)。注意:如选择 plain,加盐方式应设为 disable。
选择 bcrypt 算法,需配置:
Salt Rounds:指定散列需要的计算次数(2^Salt Rounds),也称成本因子。默认值:10,可选值:4~31;数值越高,加密的安全性越高,因此建议采用较大的值,但相应的用户验证的耗时也会增加,您可根据业务需求进行配置。
选择 pkbdf2 算法,需配置:
伪随机函数:指定生成密钥使用的散列函数,如 sha256 等。
迭代次数:指定散列次数,默认值:4096。
密钥长度:指定希望得到的密钥长度。如不指定,密钥长度将由伪随机函数确定。
完成以上设置后,点击创建,EMQX 将按照设定通过内置数据库进行密码认证。
#通过配置文件配置
此外,您可以通过配置项完成相关配置,具体可参考: authn-builtin_db:authentication。
示例配置:
{
backend = "built_in_database"
mechanism = "password_based"
password_hash_algorithm {
name = "sha256",
salt_position = "suffix"
}
user_id_type = "username"
}
#迁移到内置数据库
如你希望将其他数据库中存储的认证凭据迁移到 EMQX 内置数据库,可通过 csv 或 json 文件将其批量导入。更多信息,可阅读导入用户。
网络与 TLS
安全对于物联网场景下的端对端加密通信至关重要。EMQX 在以下几种应用中使用 SSL 和 TLS 协议来保障网络通信安全:
MQTT 客户端与 EMQX 建立连接
连接到外部资源,比如外部数据库
集群中不同节点之间的通信
EMQX 提供了全面的 SSL/TLS 功能支持,包括单向/双向身份验证和 X.509 证书身份验证。当接受 MQTT 客户端或连接到外部资源(如数据库)时,EMQX 可以通过 SSL/TLS 建立安全连接。
提示
SSL 和 TLS 常被用于网络通信,以确保数据传输保持机密性,并且无法被攻击者截获或修改。SSL/TLS 加密功能在传输层加密网络连接,并涉及使用数字证书来验证涉及各方的身份并建立安全通信通道。
本章主要介绍了 MQTT 客户端在建立与 EMQX 的连接时以及在连接到外部资源时启用 SSL/TLS,在启用 PSK 验证中还介绍了如何在 EMQX 中开启 TLS PSK 支持。此外,在获取 SSL/TLS 证书中介绍了创建自签名证书的方法。
#启用 TLS 进行客户端加密连接
开启 SSL/TLS 连接页面详细介绍了如何在 MQTT 客户端与 EMQX 的连接中启用 SSL/TLS。在 SSL/TLS 启用的情况下,您可以同时开启 CRL 检查或 OCSP stapling 来验证证书的状态。客户端 TLS 页面列举了 MQTT 客户端库接入示例和工程项目代码,在这些示例中包括了 TLS 使用指南。
#国密 SSL
国密 SSL 即国家密码局认定的国产密码算法。我国在金融银行、教育、交通、通信、国防工业等各类重要领域的信息系统均已开始进行国产密码算法的升级改造。本节将介绍 EMQX 国密算法整体解决方案。
#启用 TLS 加密访问外部资源
除了允许接收启用了双向 SSL 认证的 MQTT 客户端外,EMQX 还提供了通过 SSL 加密访问外部资源的功能。比如,在使用 HTTP 服务进行密码认证时,通过 HTTPS 访问 web 服务器。下面的示例将介绍如何在 Dashboard 和配置文件中开启 TLS 加密。
在 Dashboard 的左侧导航栏点击访问控制->认证,在认证页面,创建 Password-Based 认证。
如上所示,连接到外部资源时,您可以启用 TLS 并配置其 SSL 证书。
SNI 意为服务器名称指示,指示服务器域名和证书是否验证为相同;空值表示没有验证。
当服务器需要验证客户端证书时,则必须填写 TLS 证书 和 TLS 密钥。
当启用 TLS 验证 时,必须填写 CA 证书 字段以验证服务器证书的合法性。
除了在 Dashboard 中开启 SSL 加密连接外部资源,您还可以通过 emqx.conf
配置,例如在 authentication
配置组中添加配置:
authentication {
url = "https://127.0.0.1:8080"
backend = "http"
...
ssl {
enable = true
//证书位置
cacertfile = "etc/certs/cacert.pem"
certfile = "etc/certs/cert.pem"
keyfile = "etc/certs/key.pem"
## `verify_peer` means turn on verification for server certificate
verify = verify_peer
}}
#启用 TLS 加密节点通信
关于如何在集群节点通信中启用 TLS的具体介绍,您可以参阅集群安全。
开启 SSL/TLS 连接
SSL/TLS 加密功能会在传输层对网络连接进行加密,它能在提升通信数据安全性的同时,保证数据的完整性。EMQX 提供了非常完整的 SSL/TLS 能力支持,包括支持单/双向认证、X.509 证书认证,您可以为包括 MQTT 在内的所有连接启用 SSL/TLS 加密连接,保证接入与消息传输安全。单向认证只保证通信被加密但无法验证客户端身份。而双向认证可以同时验证客户端身份,如果客户端无法提供证书,SSL/TLS 连接将被拒绝。
对于客户端的 SSL/TLS 连接,您可以根据使用场景选择以下两种使用方式之一:
使用方式 | 优势 | 缺点 |
直接在客户端与 EMQX 之间开启 SSL/TLS 连接 | 简单易用,不需要额外的组件。 | 会增加 EMQX 的资源消耗,如果连接数量巨大,可能会导致较高的 CPU 和内存消耗。 |
通过代理或负载均衡终结 TLS 连接 | 不影响 EMQX 性能,同时提供了负载均衡能力。 | 只有少数云厂商的负载均衡器支持 TCP SSL/TLS 终结,此外,用户还需自己部署 HAProxy (opens new window)等软件。 |
本章节将向您详细介绍 SSL/TLS 加密连接以及如何在 EMQX 中通过 Dashboard 和 配置文件开启 SSL/TLS 连接。有关如何通过代理或负载均衡终结 TLS 连接,请参考集群负载均衡。
#安全优势
启用 SSL/TLS 连接提供了以下安全优势:
强认证:开启 TLS 连接后,通讯双方将互相检查对方的身份,比如通过检查对方持有的 X.509 数字证书;这类数字证书通常是由受信机构 CA(Certificate Authority)颁发,不可伪造。
机密性:开启 TLS 连接后,每次会话都会根据双方协商得到的会话密钥进行加密。任何第三方都无法知晓通讯内容,因此即使一次会话的密钥泄露,也不影响其他会话的安全性。
完整性:加密通讯中的数据被篡改的可能性极低。
#前置准备
开始之前,您需要具备 SSL/TLS 证书。EMQX 随安装包提供了一组仅用于测试的 SSL/TLS 证书(位于 etc/certs
目录),并在 8883
端口启用了 SSL/TLS 连接。当应用于生产环境时,应切换至由可靠 CA 签发的证书。有关如何申请相关证书,请参考获取 SSL/TLS 证书部分。
#通过 Dashboard 开启 SSL/TLS 连接
在 8883
端口上启用的 SSL 监听器用来加密客户端与 EMQX 之前的数据传输。在 EMQX Dashboard 中,您可以通过修改 SSL 监听器的设置来开启 SSL/TLS 连接。
将您的私人SSL/TLS 证书文件保存到 EMQX 的
etc/certs
目录下。转到 EMQX Dashboard,在左侧导航栏中点击管理 -> 监听器。
在监听器页面, 在类型为 SSL 的监听器的名称列中点击 default。
验证服务器证书:默认为不启用。如果需要验证客户端身份进行双向认证,点击切换开关。
TLS Cert, TLS Key 和 CA Cert:点击重新设置上传您的私人证书文件以替换当前的证书文件。
SSL 版本: 支持所有 TLS/DTLS 版本。默认设置为
tlsv1.3
和tlsv1.2
。如果 PSK 验证中使用了 PSK 密码套件,确保在此处设置tlsv1.2
,tlsv1.1
和tlsv1
。更多关于 PSK 验证的内容,参阅 启用 PSK 验证。没有证书则 SSL 失败:在验证服务器证书启用时使用。默认设置为
false
。如果设置为
true
,如果客户端发送空证书,则客户端身份验证失败,SSL/TLS 连接将被拒绝。如果设置为
false
,只有当客户端发送无效证书时,客户端身份验证失败(空证书被认为是有效证书),SSL/TLS 连接将被拒绝。
CA 证书深度:允许的证书文件路径最大深度; 默认值为
10
。密钥文件密码:如果密钥文件由密码保护,则需要输入密码。
启用 OCSP Stapling: 默认为不启用;如需获取 X509 数字证书的撤销状态,可以点击切换开关。具体可参阅 OCSP Stapling。
启用 CRL 检查:默认为不启用;如需设置证书吊销列表(CRL)检查功能,可以点击切换开关。具体可参阅 CRL 检查。
完成编辑后,点击更新。
这里在从云服务厂商下载到证书后可以直接在此处进行配置,可忽略下面在文件中进行配置
用下述腾讯云根证书进行配置
hy.cn.key,放入中间TLSKey
hya.cn_bundle.crt,放入TLSCert
hy.cn_bundle.pem,放入CA Cert
通过配置文件开启 SSL/TLS 连接
ssl证书可以通过下述获取哪里自己签发
也可以通过云厂商进行签发免费证书,通过云厂商签发的需要有自己的域名,签发的证书不是以IP形式签发
在连接的时候需要将IP换成域名,#注意(IP证书需要花钱)
将 SSL/TLS 证书文件移动到 EMQX
etc/cert
目录。docker安装的emqx如果需要修改下述文件,需要将ssl文件传入到容器内部
1. 从本地主机复制文件到容器:
docker cp /path/to/local/file container_name:/path/in/container/file
将 /path/to/local/file 替换为本地主机上的文件路径,将 container_name 替换为容器的名称或ID,将 /path/in/container/file 替换为容器内部的目标路径。
2. 通过标准输入(stdin)传输文件内容到容器:
cat /path/to/local/file | docker exec -i container_name sh -c 'cat > /path/in/container/file'
将 /path/to/local/file 替换为本地主机上的文件路径,将 container_name 替换为容器的名称或ID,将 /path/in/container/file 替换为容器内部的目标路径。
3. 使用Docker卷(volume)将文件映射到容器:
首先,创建一个Docker卷:
docker volume create myvolume
将 myvolume 替换为你想要使用的卷名称。
然后,将容器与卷进行关联:
docker run -v myvolume:/path/in/container -d --name container_name image_name
将 myvolume 替换为先前创建的卷名称,将 /path/in/container 替换为容器内部的目标路径,将 container_name 替换为容器的名称, image_name 替换为容器的镜像名称。
最后,将文件复制到本地卷目录中:
docker cp /path/to/local/file $(docker volume inspect --format '{{ .Mountpoint }}' myvolume)/file_name
将 /path/to/local/file 替换为本地主机上的文件路径,将 myvolume 替换为之前创建的卷名称,将 file_name` 替换为文件的名称。
这些方法都可以将文件上传到Docker容器内部。选择适合你需求的方法,并根据实际情况进行替换。
打开配置文件
emqx.conf
(根据您的安装方式,可能位于./etc
或/etc/emqx/etc
目录),修改listeners.ssl.default
配置组,将证书替换为您的证书,并添加verify = verify_none
:
listeners.ssl.default {bind = "0.0.0.0:8883"
max_connections = 512000
ssl_options {# keyfile = "etc/certs/key.pem"
keyfile = "etc/certs/server.key"# certfile = "etc/certs/cert.pem"
certfile = "etc/certs/server.crt"# cacertfile = "etc/certs/cacert.pem"
cacertfile = "etc/certs/rootCA.crt"# 不开启对端验证
verify = verify_none
}}
至此您已经完成 EMQX 上的 SSL/TLS 单向认证配置,单向认证仅保证通信已经被加密,无法 验证客户端身份。
如需启用双向认证,请在
listeners.ssl.default
配置组中添加如下配置:
listeners.ssl.default {...
ssl_options {...
# 开启对端验证
verify = verify_peer
# 强制开启双向认证,如果客户端无法提供证书,则 SSL/TLS 连接将被拒绝
fail_if_no_peer_cert = true}}
重启 EMQX,应用以上配置。
获取 SSL/TLS 证书
您可通过以下两种方式获取相关 SSL/TLS 证书:
自签名证书:即使用自己签发的证书,由于自签名证书存在较多的安全隐患,因此只建议用于测试验证环境。
申请或购买证书:您可以向 Let's Encrypt (opens new window)或华为云、腾讯云等云厂商申请免费证书,也可以向 DigiCert (opens new window)等机构购买收费证书。对于企业级用户,一般建议申请收费的 OV 及以上类型的证书,以获取更高等级的安全保护。
#创建自签名证书
前置准备
已安装 OpenSSL (opens new window)。
运行以下命令生成密钥对,该命令随即会提示您输入密钥保护密码,后续在生成、签发、验证证书时均需要此密码。请妥善相关密钥及密码。
openssl genrsa -des3 -out rootCA.key 2048
1
运行以下命令通过密钥对中的私有密钥生成 CA 证书,该命令随即会提示您设置证书的唯一标识名称 DN(Distinguished Name)。
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt
1
使用步骤 2 中的 CA 证书来签发服务端证书,用于验证服务器所有者的身份,服务端证书通常颁发给主机名、服务器名称或域名(如 www.emqx.com)。我们需要 CA 密钥(rootCA.key)、CA 证书( rootCA.crt)和服务端 CSR (server.csr)生成服务端证书。
3.1 运行以下命令生成服务端证书密钥对:
openssl genrsa -out server.key 2048
1
3.2 运行以下命令使用 Server 密钥对制作 CSR。经 CA 根证书私钥签名后,CSR 可生成颁发给用户的证书公钥文件。该命令随即也会要求设置证书的唯一标识名称。
openssl req -new -key server.key -out server.csr
1
系统将提示以下信息,对应的含义如下:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]: # 国家/地区
State or Province Name (full name) [Some-State]: # 省/市
Locality Name (eg, city) []: # 城市
Organization Name (eg, company) [Internet Widgits Pty Ltd]: # 组织机构(或公司名),如 EMQ
Organizational Unit Name (eg, section) []: # 机构部门,如 EMQX
Common Name (e.g. server FQDN or YOUR name) []: # 通用名称,此处应当设置为服务器域名如 mqtt.emqx.com...
3.3 生成服务端证书,此时也可指定证书的有效天数,此处为 365 天:
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 365
至此您就得到了一组证书。
.
├── rootCA.crt
├── rootCA.key
├── rootCA.srl
├── server.crt
├── server.csr
└── server.key