记录linux环境下搭建本地MQTT服务器实现mqtt的ssl加密通讯
1、ubuntu安装mosquitto
sudo apt-get update
//安装服务端
sudo apt-get install mosquitto
//安装客户端
sudo apt-get install mosquitto-clients
2、安装openssl
3、mqtts/tls加密传输
mosquitto原生支持了TLS加密,TLS(传输层安全)是SSL(安全套接层)的新名称,mqtts/tls支持3种加密模式:
- CA Signed server certificate:由CA机构签名的服务器认证(启用ssl加密不做认证)
- Self-signed server certificate:自签名的服务器认证自签名服务器认证需要填写PEM格式的自签名CA证书 (单向认证)
- Self-signed server & client certificate:自签名的服务器&客户端双向认证。自签名的双向认证需要填写PEM格式的自签名CA证书(CA Certificate),客户端证书(Client Certificate)和客户端密钥(Client Key)。 如果客户端密钥文件是加密的,需要填写客户端密钥密码(Client Key Passphrase)。(双向认证)
证书生成
使用github中的一个脚本,可以让hostname为localhost、本机ip或127.0.0.1,脚本从OweTracks项目下载并运行generate-CA.sh脚本。该脚本创建CA文件,生成服务器证书,并使用CA来签名证书。
//创建证书目录
mkdir certs
//下载脚本到certs
cd certs
wget https://raw.githubusercontent.com/owntracks/tools/master/TLS/generate-CA.sh
//执行脚本
sh ./generate-CA.sh
可生成以下内容:
[yangzheng@localhost certs]$ ls
ca.crt ca.key ca.srl generate-CA.sh localhost.localdomain.crt localhost.localdomain.csr localhost.localdomain.key
将上述生成的文件拷贝到/etc/mosquitto/certs目录下(也可以不拷贝,再配置文件指定绝对路径)
//给下面3个文件换个名字
[yangzheng@localhost certs]$ mv localhost.localdomain.crt server.crt
[yangzheng@localhost certs]$ mv localhost.localdomain.csr server.csr
[yangzheng@localhost certs]$ mv localhost.localdomain.key server.key
//拷贝文件到/etc/mosquitto/certs
[yangzheng@localhost certs]$ sudo cp -rf ca.crt ca.key ca.srl client.crt client.csr client.key server.crt server.csr server.key /etc/mosquitto/certs/
修改mosiquitto.conf,添加证书的路径,加密端口8883(配置端口监听端口默认是1883)
[yangzheng@localhost app]$ cat /etc/mosquitto/mosquitto.conf
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
#add
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/host.crt
keyfile /etc/mosquitto/certs/host.key
# one-way or two-way authentication
#require_certificate true
#end add
include_dir /etc/mosquitto/conf.d
启动mqtt服务
[yangzheng@localhost certs]$ sudo mosquitto -d -c /etc/mosquitto/mosquitto.conf^C
[yangzheng@localhost certs]$ ps -aux |grep mosquitto
mosquit+ 4860 0.1 0.1 45356 5684 ? Ss 17:19 0:05 mosquitto -d -c /etc/mosquitto/mosquitto.conf
yangzhe+ 4958 0.0 0.0 16156 1036 pts/10 S+ 18:13 0:00 grep mosquitto
4 测试
ubuntu 命令行测试
a 单向认证
单向认证时客户端不需要生成客户端证书、钥匙和请求,仅需要将CA证书ca.crt,ca.key,ca.srl,拷贝到客户端系统中, 测试结果:
b 双向认证
双向认证则需根据CA证书生成客户端证书,生成客户端证书、钥匙和请求的方法是在CA证书文件夹下执行OpenSSL,命令如下:
[yangzheng@localhost certs]$ openssl genrsa -out client.key 2048
[yangzheng@localhost certs]$ openssl req -new -out client.csr -key client.key -subj "/CN=client/O=example.com"
[yangzheng@localhost certs]$ openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAserial ./ca.srl -out client.crt -days 3650 -addtrust clientAuth
测试结果:
源码测试,关键配置:
a 只加密不认证
MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
ssl_opts.enableServerCertAuth = DISABLE;
conn_opts.ssl = &ssl_opts;
b 单向认证
MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
ssl_opts.enableServerCertAuth = ENABLE;
ssl_opts.trustStore = "/mnt/tmp/ca.crt";
conn_opts.ssl = &ssl_opts;
c 双向认证
MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
ssl_opts.enableServerCertAuth = ENABLE;
ssl_opts.trustStore = "/mnt/tmp/ca.crt";
ssl_opts.privateKey = "/mnt/tmp/client.key";
ssl_opts.keyStore = "/mnt/tmp/client.crt";
conn_opts.ssl = &ssl_opts;
备注:
1、c 客户端源码下载git clone https://github.com/eclipse/paho.mqtt.c.git
2、使用mqtts/tls加密通信时,server地址需加"ssl://", 例如"ssl://127.0.0.1:8883";
3、编译mqtt源码时,在makefile增加OPENSSL宏定义,如CFLAGS += -DOPENSSL
4、需要移植openssl库,mqtt源码编译需要链接到openssl中的include和lib
测试结果: