CentOS8下Mosquitto安装使用指南

环境准备

查看系统版本

cat /etc/redhat-release

CentOS Linux release 8.2.2004 (Core)

关闭linuxse

临时关闭:setenforce 0

永久关闭:修改/etc/selinux/config 文件将SELINUX=enforcing改为SELINUX=disabled,然后重启

查看状态:getenforce

打开防火墙端口

firewall-cmd --zone=public --add-port=1883/tcp --permanent
firewall-cmd --zone=public --add-port=8883/tcp --permanent
firewall-cmd --reload

配置dnf

vi /etc/dnf/dnf.conf

再最下方加入一行

fastestmirror=True

保存退出之后执行:

dnf clean all
dnf makecache

安装wget

dnf install wget -y

安装tar

dnf install tar -y

安装make

dnf install make -y

安装g++

dnf install gcc-c++ -y

安装openssl开发工具包

dnf install openssl-devel -y

安装Mosquitto

下载编译

wget https://mosquitto.org/files/source/mosquitto-1.6.10.tar.gz
tar -zxvf mosquitto-1.6.10.tar.gz
cd mosquitto-1.6.10
make
make install

配置启动

cd /etc/mosquitto/
mv mosquitto.conf.example  mosquitto.conf
mosquitto -c /etc/mosquitto/mosquitto.conf

出现如下错误:

1596531761: Error: Invalid user 'mosquitto'.

为解决此问题,需要给系统创建mosquitto用户和组:

groupadd mosquitto
useradd -g mosquitto mosquitto

chown -R mosquitto:mosquitto /etc/mosquitto/

创建完之后再次尝试启动,应该就能成功启动了。

如果要后台运行,则加入-d参数,完整命令如下:

mosquitto -c /etc/mosquitto/mosquitto.conf  -d

-c参数是指定配置文件,-d参数是指定后台运行

设置开机启动

便携启动文件

vi /usr/lib/systemd/system/mosquittod.service

脚本内容如下

[Unit]
Description=Mosquitto 1.6.10 mqtt server
After=network.target

[Service]
Type=forking
User=mosquitto
Group=mosquitto

ExecStart=/usr/local/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf  -d

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300

# Place temp files in a secure directory, not /tmp
PrivateTmp=true

[Install]
WantedBy=multi-user.target

修改文件权限:

chmod 644 /usr/lib/systemd/system/mosquittod.service

使配置生效:

systemctl daemon-reload

设为开机启动:

systemctl enable mosquittod.service

测试

订阅一个主题,如test:

mosquitto_sub -t test

出现如下错误:

mosquitto_sub: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory

解决办法,是创建一个符号链接:

ln -s /usr/local/lib/libmosquitto.so.1  /usr/lib/libmosquitto.so.1
ldconfig

然后再次执行mosquitto_sub -t test订阅test主题,应该就可以成功了。

再开一个终端窗口给test主题发布一条消息:

mosquitto_pub  -t test -m "hello"

订阅的窗口将打印hello

安装mosquitto-go-auth

安装go环境

dnf install golang -y

下载编译mosquitto-go-auth

wget https://github.com/iegomez/mosquitto-go-auth/archive/1.0.0.tar.gz -O ./mosquitto-go-auth-1.0.0.tar.gz
tar -zxvf mosquitto-go-auth-1.0.0.tar.gz
cd mosquitto-go-auth-1.0.0
export CGO_CFLAGS="-I/usr/local/include -fPIC"
export CGO_LDFLAGS="-shared"
make

make的时候可能出现如下这样的一个错:

go: github.com/brocaar/lora-app-server@v2.5.1+incompatible: Get https://proxy.golang.org/github.com/brocaar/lora-app-server/@v/v2.5.1+incompatible.mod: dial tcp 34.64.4.81:443: i/o timeout
make: *** [Makefile:2: all] Error 1

解决办法是设置代理

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
make

准备MySQL

安装启动MySQL
wget https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm
yum install mysql80-community-release-el8-1.noarch.rpm
yum install mysql-server
service mysqld start
修改root密码

登录MySQL并修改密码,刚刚安装好的是没有密码的,直接回车即可登录进去

mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED BY '1234';
准备数据库和表结构
CREATE SCHEMA `mosquitto` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin ;

use mosquitto;

create table mosquitto_user(
id mediumint not null auto_increment,
username varchar(100) not null,
password_hash varchar(200) not null,
is_admin boolean not null,
primary key(id)
);

create table mosquitto_acl(
id mediumint not null auto_increment,
mosquitto_user_id mediumint not null,
topic varchar(200) not null,
rw int not null COMMENT '1:readonly, 2:writeonly ,3:readwrite ,4:subscribe ',
primary key(id),
foreign key(mosquitto_user_id) references mosquitto_user(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);

insert into mosquitto_user(username, password_hash,is_admin) values('admin','',1);
准备测试账号

使用mosquitto-go-auth编译出来的pw命令生成pbkdf2的密码,

cd ~/mosquitto-go-auth-1.0.0
./pw -l 64 -p 123456

生成的如下的字符串可以作为mosquitto用户的密码

PBKDF2$sha512$100000$ooBf5L/ANImpDrhOCiAMpg==$BzO004Rc5bT44/E/PMQluJ7Bobf7ffixw/Z3b9iB55No6c/QGy4VgQMBzsLOU9XTJx93qxd/1nKhdCa+HJm1Tw==

登录MySQL,创建测试用户

mysql -uroot -p1234
-- 插入一个管理员账号和两个普通账号
insert into mosquitto_user(username, password_hash,is_admin) values('admin','PBKDF2$sha512$100000$ooBf5L/ANImpDrhOCiAMpg==$BzO004Rc5bT44/E/PMQluJ7Bobf7ffixw/Z3b9iB55No6c/QGy4VgQMBzsLOU9XTJx93qxd/1nKhdCa+HJm1Tw==',1),('yuanpan1','PBKDF2$sha512$100000$ooBf5L/ANImpDrhOCiAMpg==$BzO004Rc5bT44/E/PMQluJ7Bobf7ffixw/Z3b9iB55No6c/QGy4VgQMBzsLOU9XTJx93qxd/1nKhdCa+HJm1Tw==',0),('yuanpan2','PBKDF2$sha512$100000$ooBf5L/ANImpDrhOCiAMpg==$BzO004Rc5bT44/E/PMQluJ7Bobf7ffixw/Z3b9iB55No6c/QGy4VgQMBzsLOU9XTJx93qxd/1nKhdCa+HJm1Tw==',0);

--  给两个普通账号插入权限控制数据,管理员账号不需要插入
insert into mosquitto_acl(mosquitto_user_id, topic, rw) values(2,'/test/#',1),(2,'/test/#',2),(2,'/test/#',3),(2,'/test/#',4),(3,'/test/#',1),(3,'/test/#',2),(3,'/test/#',3),(3,'/test/#',4);

配置运行mosquitto-go-auth

关闭匿名访问
vi /etc/mosquitto/mosquitto.conf
# 将如下配置设置为false
allow_anonymous false 
创建日志目录和配置日志设置
cd /var/log
mkdir mosquitto
chown -R mosquitto:mosquitto /var/log/mosquitto/


vi /etc/mosquitto/mosquitto.conf
# 将log_dest,log_type,connection_messages做如下设置
log_dest file /var/log/mosquitto/mosquitto.log
log_type all
connection_messages true
配置mosquitto-go-auth插件相关设置
cd /etc/mosquitto/
vi mosquitto.conf 
# 到文件末尾配置
include_dir /etc/mosquitto/conf.d


mkdir plugins
cd plugins
cp ~/mosquitto-go-auth-1.0.0/go-auth.so .


cd ..
mkdir conf.d
vi mosquitto-go-auth.conf
# 写入如下数据到mosquitto-go-auth.conf文件
auth_plugin /etc/mosquitto/plugins/go-auth.so

auth_opt_backends mysql

# Cache
#auth_opt_cache true
#auth_opt_cache_type redis
#auth_opt_cache_reset true

#auth_opt_auth_cache_seconds 30
#auth_opt_acl_cache_seconds 30

#auth_opt_cache_host localhost
#auth_opt_cache_port 6379
#auth_opt_cache_password pwd
#auth_opt_cache_db 3

#Logging
auth_opt_log_level debug
auth_opt_log_dest file
auth_opt_log_file /var/log/mosquitto/mosquitto-go-auth.log


# Hashing
auth_opt_hasher pbkdf2
auth_opt_hasher_salt_size 16                 # salt bytes length
auth_opt_hasher_iterations 100000            # number of iterations
auth_opt_hasher_keylen 64                    # key length
auth_opt_hasher_algorithm sha512             # hashing algorithm, either sha512 (default) or sha256
auth_opt_hasher_salt_encoding base64         # salt encoding, either base64 (default) or utf-8

# MySQL
auth_opt_mysql_host localhost
auth_opt_mysql_port 3306
auth_opt_mysql_dbname mosquitto
auth_opt_mysql_user root
auth_opt_mysql_password 1234
auth_opt_mysql_allow_native_passwords true
auth_opt_mysql_userquery SELECT password_hash FROM mosquitto_user WHERE username = ? limit 1
auth_opt_mysql_superquery SELECT COUNT(1) FROM mosquitto_user WHERE username = ? AND is_admin = 1 LIMIT 1
auth_opt_mysql_aclquery SELECT topic FROM mosquitto_acl acl  inner join mosquitto_user user on acl.mosquitto_user_id = user.id WHERE user.username = ? AND acl.rw = ?

以上配置完之后,运行下mosquitto试试

mosquitto -c /etc/mosquitto/mosquitto.conf

测试一下

订阅/test/1主题

mosquitto_sub  -t /test/1 -u yuanpan1 -P 123456

给/test/1主题发送一个hello消息

mosquitto_pub  -t /test/1 -m "hello" -u yuanpan2 -P 123456

配置TLS

机器准备和命名

这部分的内容将和mosquitto的桥接一起来写,准备3台虚拟机,配置其 /etc/hosts文件,来为虚拟机命名

192.168.20.200 server.mosquitto1.vm client.mosquitto1.vm ca.mosquitto1.vm
192.168.20.201 server.mosquitto2.vm client.mosquitto2.vm
192.168.20.202 server.mosquitto3.vm client.mosquitto3.vm

使用openssl生成相关证书

准备/etc/mosquitto/certs目录

在第一台虚拟机server.mosquitto1.vm上执行如下:

cd /etc/mosquitto/
mkdir certs
cd certs
Certificate Authority

Generate a certificate authority certificate and key.

openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.crt

先输入两遍密码,剩下的可以参考如下:
Country Name : CN
State or Province Name : HuBei
Locality Name (eg, city) : WuHan
Organization Name (eg, company) : Test
Organizational Unit Name (eg, section) : CA
Common Name (eg, your name or your server’s hostname) : ca.mosquitto1.vm
Email Address : test@qq.com

这里注意,Common Name 是ca.mosquitto1.vm

Server

Generate a server key.

openssl genrsa -out server.key 2048

Generate a certificate signing request to send to the CA.

openssl req -out server.csr -key server.key -new

先输入两遍密码,剩下的可以参考如下:
Country Name : CN
State or Province Name : HuBei
Locality Name (eg, city) : WuHan
Organization Name (eg, company) : Test
Organizational Unit Name (eg, section) : Server
Common Name (eg, your name or your server’s hostname) : server.mosquitto1.vm
Email Address : test@qq.com

这里注意,Common Name,在第一台机器,填server.mosquitto1.vm,在第二台机器填server.mosquitto2.vm,第三台机器填server.mosquitto3.vm

Send the CSR to the CA, or sign it with your CA key:

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650

将虚拟机的证书放到/ect/mosquitto/certs/server.mosquitto1.vm 目录下

mkdir server.mosquitto1.vm
mv server.crt server.mosquitto1.vm/
mv server.csr server.mosquitto1.vm/
mv server.key server.mosquitto1.vm/

继续执行上面生成Server证书的步骤来生成server.mosquitto2.vm的Server证书,并放入到/ect/mosquitto/certs/server.mosquitto1.vm目录下;生成server.mosquitto3.vm的Server证书,并放入到/ect/mosquitto/certs/server.mosquitto3.vm目录下

mkdir server.mosquitto2.vm
mv server.crt server.mosquitto2.vm/
mv server.csr server.mosquitto2.vm/
mv server.key server.mosquitto2.vm/

mkdir server.mosquitto3.vm
mv server.crt server.mosquitto3.vm/
mv server.csr server.mosquitto3.vm/
mv server.key server.mosquitto3.vm/
Client

Generate a client key.

openssl genrsa -out client.key 2048

Generate a certificate signing request to send to the CA.

openssl req -out client.csr -key client.key -new

Country Name : CN
State or Province Name : HuBei
Locality Name (eg, city) : WuHan
Organization Name (eg, company) : Test
Organizational Unit Name (eg, section) : Client
Common Name (eg, your name or your server’s hostname) : client.mosquitto1.vm
Email Address : test@qq.com

这里注意,Common Name,在第一台机器,填client.mosquitto1.vm,在第二台机器填client.mosquitto2.vm,第三台机器填client.mosquitto3.vm

Send the CSR to the CA, or sign it with your CA key:

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 3650

将虚拟机的证书放到/ect/mosquitto/certs/client.mosquitto1.vm 目录下

mkdir client.mosquitto1.vm
mv client.crt client.mosquitto1.vm/
mv client.csr client.mosquitto1.vm/
mv client.key client.mosquitto1.vm/

继续执行上面生成Server证书的步骤来生成server.mosquitto2.vm的Server证书,并放入到/ect/mosquitto/certs/server.mosquitto1.vm目录下;生成server.mosquitto3.vm的Server证书,并放入到/ect/mosquitto/certs/server.mosquitto3.vm目录下

mkdir client.mosquitto2.vm
mv client.crt client.mosquitto2.vm/
mv client.csr client.mosquitto2.vm/
mv client.key client.mosquitto2.vm/

mkdir client.mosquitto3.vm
mv client.crt client.mosquitto3.vm/
mv client.csr client.mosquitto3.vm/
mv client.key client.mosquitto3.vm/

TLS单向认证

修改配置
vi /etc/mosquitto/mosquitto.conf

# 修改如下配置
port 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.mosquitto1.vm/server.crt
keyfile /etc/mosquitto/certs/server.mosquitto1.vm/server.key
require_certificate false
tls_version tlsv1.2

上面是虚拟机1的配置,在配置虚拟机2和3的时候注意修改证书文件路径

单向认证和双向认证的区别在于require_certificate这个配置项

配置完成之后三台机器都启动好mosquitto

测试

开启了TLS之后我用mosquitto_submosquitto_sub命令都得到一个错误
Error: A TLS error occurred.但是如果是使用工具,如MQTT.fx就没问题

这个问题弄清楚了,是因为证书的Common Name导致的。需要在mosquitto_sub命令的参数中指定-h参数跟证书的Common Name一致就可以了。

下面开始在第一台虚拟机上测试,先订阅一个/test/1的主题

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --tls-version tlsv1.2

再向这个主题发布一个消息

mosquitto_pub -u yuanpan1 -P 123456 -t "/test/1" -m "hello" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --tls-version tlsv1.2

可以看到订阅的地方能收到hello的消息

如果是使用MQTT.fx工具测试,在SSL/TLS中选择CA certificate file ,选择ca.crt文件

TLS单向认证下的多个broker桥接

在server.mosquitto1.vm机器上配置/etc/mosquitto/mosquitto.conf,配置如下的内容:

connection bridge1
cleansession true
address server.mosquitto2.vm:8883
topic # both 0
bridge_cafile /etc/mosquitto/certs/ca.crt
remote_username admin
remote_password 123456

connection bridge2
cleansession true
address server.mosquitto3.vm:8883
topic # both 0
bridge_cafile /etc/mosquitto/certs/ca.crt
remote_username admin
remote_password 123456

注意cleansession的设置,如果设置为true,那么在桥接断开的时候,远程代理上订阅和主题会被清除,如果设置为false则不会清除。

配置玩之后重启虚拟机1上的mosquitto

测试的话,可以在任意两台机器上订阅一个主题如/test/1,然后在第三台机器上发布一个消息到这个主题
在虚拟机1和虚拟机2上订阅

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt"  --tls-version tlsv1.2

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto2.vm --cafile "/etc/mosquitto/certs/ca.crt"  --tls-version tlsv1.2

在虚拟机3上发布:

mosquitto_pub -u yuanpan1 -P 123456 -t "/test/1" -m "单向TLS测试" -p 8883 -h server.mosquitto3.vm --cafile "/etc/mosquitto/certs/ca.crt" --tls-version tlsv1.2

在虚拟机1和2上都可以看到订阅的消息:单向TLS测试

TLS双向认证

单向认证和双向认证的区别在于require_certificate这个配置项

如果是一路走过来的,那么可以先将上面讲到的的桥接部分的配置在虚拟机1上先注释掉,再往下看。

修改配置
vi /etc/mosquitto/mosquitto.conf

# 修改如下配置
port 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.mosquitto1.vm/server.crt
keyfile /etc/mosquitto/certs/server.mosquitto1.vm/server.key
require_certificate true
tls_version tlsv1.2
use_identity_as_username true

注意use_identity_as_username这个配置项,如果这个配置成了true,那么在认证的时候,会将客户端证书中的Common Name作为用户名来校验,当然,这个配置项是可以配置成false的。

测试

下面开始在第一台虚拟机上测试,先订阅一个/test/1的主题

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto1.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto1.vm/client.key" --tls-version tlsv1.2

再向这个主题发布一个消息

mosquitto_pub -u yuanpan1 -P 123456 -t "/test/1" -m "双向TLS测试" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto1.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto1.vm/client.key" --tls-version tlsv1.2

可以看到订阅的地方能收到双向TLS测试的消息

如果是使用MQTT.fx工具测试,在SSL/TLS中选择Self signed certificates。
在CA File中选择ca.crt文件
在Client Certificate File中选择client.crt文件
在Client Key File中选择client.key文件
在Client Key Password中填写生成客户端证书时候的密码
勾选PEM Formatted

TLS双向认证下的多个broker桥接

在server.mosquitto1.vm机器上配置/etc/mosquitto/mosquitto.conf,配置如下的内容:

connection bridge1
cleansession true
address server.mosquitto2.vm:8883
topic # both 0
bridge_cafile /etc/mosquitto/certs/ca.crt
remote_username admin
remote_password 123456

connection bridge2
cleansession true
address server.mosquitto3.vm:8883
topic # both 0
bridge_cafile /etc/mosquitto/certs/ca.crt
remote_username admin
remote_password 123456

测试的话,可以在任意两台机器上订阅一个主题如/test/1,然后在第三台机器上发布一个消息到这个主题
在虚拟机1和虚拟机2上订阅

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto1.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto1.vm/client.key" --tls-version tlsv1.2

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto2.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto2.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto2.vm/client.key" --tls-version tlsv1.2

在虚拟机3上发布:

mosquitto_pub -u yuanpan1 -P 123456 -t "/test/1" -m "双向TLS测试" -p 8883 -h server.mosquitto3.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto3.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto3.vm/client.key" --tls-version tlsv1.2

在虚拟机1和2上都可以看到订阅的消息:双向TLS测试

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值