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

MQTT

1 基础知识

1.1 插件的介绍

– 插件用于从一个或多个后端为Mosquitto用户做验证和授权
– 插件用于执行身份验证,即检查用户名和密码
– 插件用于授权,即授权通过ACL订阅或发布到特定主题的权限

1.2 插件支持的后端

– CDB
– File
– HTTP(自定义HTTPAPI)
– JWT
– LDAP
– MongoDB
– MySQL
– PostgreSQL
– Redis(键/值存储)
– SQLite3
– TLS PSK

1.3 插件与后端的功能

Capability cdb files http jwt ldap mongo mysql postgres psk redis sqlite
authentication Y Y Y Y Y Y Y Y Y Y Y
superusers Y Y Y Y Y 3
acl checking 2 Y Y Y Y Y Y 3 1 2
static superusers Y Y Y Y Y Y Y 3 Y Y

需要注意的是,
– 插件并非所有后端都支持相同的功能
– 插件不支持主题通配符(“+”或“#”)
– 插件目前尚未实现后端返回“TRUE”
– 插件PSK的功能取决于后端的数据库
– 支持同时配置多个后端进行身份验证(按指定顺序尝试后端)
– 身份验证通过后,将使用相同的后端检查授权
关于多后端支持,具体请参阅如下配置选项,

auth_opt_backends cdb,sqlite,mysql,redis,postgres,http,jwt,mongo

1.4 安装要求

– 插件的安装需要预装Mosquitto
– 插件的安装需要预装后端数据库(例如,MySQL)
– 插件的安装需要预装OpenSSL

2 最佳实践

2.1 环境的部署

2.1.1 配置Mosquitto服务端

如果你尚未预装Mosquitto,请按照如下文档部署Mosquitto,
https://www.cmdschool.org/archives/6833
注意:本章需要使用“mosquitto-1.5.8”,高版本可能无法兼容。

2.1.2 配置GLPI的Flyve MDM插件(可选)

由于本章的数据库表结构由GLPI的Flyve MDM插件提供,所以如果你需要验证,请根据如下向导配置Flyve MDM插件,
https://www.cmdschool.org/archives/6328

3.2 软件环境

3.2.1 软装编译工具

yum -y install gcc gcc-c++ cmake

3.2.2 下载软件包

cd ~
wget https://codeload.github.com/jpmens/mosquitto-auth-plug/tar.gz/0.1.3 -O mosquitto-auth-plug-0.1.3.tar.gz

其他版本请从以下链接下载,
https://github.com/jpmens/mosquitto-auth-plug/releases

3.2.3 解压软件包

cd ~
tar -xf mosquitto-auth-plug-0.1.3.tar.gz

3.3 编译软件包

3.3.1 准备编译环境

cd ~/mosquitto-auth-plug-0.1.3
cp config.mk.in config.mk

以上文件创建后,你需要使用以下命令修改文件的编译参数,

cd ~/mosquitto-auth-plug-0.1.3
vim config.mk

通过以下修改的参数,我们指定插件使用的后端、Mosquitto的源和OpenSSL的目录,

BACKEND_CDB ?= no
BACKEND_MYSQL ?= yes
BACKEND_SQLITE ?= no
BACKEND_REDIS ?= no
BACKEND_POSTGRES ?= no
BACKEND_LDAP ?= no
BACKEND_HTTP ?= no
BACKEND_JWT ?= no
BACKEND_MONGO ?= no
BACKEND_FILES ?= no
BACKEND_MEMCACHED ?= no

# Specify the path to the Mosquitto sources here
# MOSQUITTO_SRC = /usr/local/Cellar/mosquitto/1.4.12
MOSQUITTO_SRC = ~/mosquitto-1.5.8

# Specify the path the OpenSSL here
OPENSSLDIR = /usr

# Add support for django hashers algorithm name
SUPPORT_DJANGO_HASHERS ?= no

# Specify optional/additional linker/compiler flags here
# On macOS, add
#       CFG_LDFLAGS = -undefined dynamic_lookup
# as described in https://github.com/eclipse/mosquitto/issues/244
#
# CFG_LDFLAGS = -undefined dynamic_lookup  -L/usr/local/Cellar/openssl/1.0.2l/lib
# CFG_CFLAGS = -I/usr/local/Cellar/openssl/1.0.2l/include -I/usr/local/Cellar/mosquitto/1.4.12/include
CFG_LDFLAGS =
CFG_CFLAGS =

注:
– 参数“BACKEND_MYSQL”设置为yes表示启用MySQL后端,其他后端设置为“no”
– 参数“MOSQUITTO_SRC”指定Mosquitto源代码的位置
– 其他的参数请根据情况使用

3.3.2 编译软件包

cd ~/mosquitto-auth-plug-0.1.3
make

如果遇到以下错误,

/usr/bin/ld: cannot find -l/usr/local/lib/libgnutls.a
collect2: error: ld returned 1 exit status
make: *** [auth-plug.so] Error 1

请注意以上错误并不是缺少“libgnutls”库,错误可能是与二进制安装的MariaDB不兼容,例如下面链接所示的部署案例,
https://www.cmdschool.org/archives/7034
所以,你需要关闭此数据库和撤销环境变量然后再试,

/etc/init.d/mysqld stop
chkconfig mysqld off
rm -f /etc/profile.d/mysql.sh
reboot

如果你遇到以下错误,

/bin/sh: mysql_config: command not found

你可能需要安装如下包解决依赖关系,

yum install -y mysql-community-devel

3.3.3 查找编译结果文件

find ~/mosquitto-auth-plug-0.1.3 -name \*auth-plug.so\*

命令显示如下,

/root/mosquitto-auth-plug-0.1.3/auth-plug.so

注:本章的目的就是编译出认证模块“auth-plug.so”

3.4 验证认证插件(可选)

3.4.1 创建插件引用配置

vim /etc/mosquitto/conf.d/flyvemdm.conf

加入如下配置,

port 1883
allow_anonymous false

auth_plugin /usr/lib/mosquitto-auth-plugin/auth-plugin.so
auth_opt_backends mysql
auth_opt_host 127.0.0.1
auth_opt_port 3306
auth_opt_user mosquitto
auth_opt_dbname glpi
auth_opt_pass mosquittopwd
auth_opt_userquery SELECT password FROM glpi_plugin_flyvemdm_mqttusers WHERE user='%s' AND enabled='1'
auth_opt_aclquery SELECT topic FROM glpi_plugin_flyvemdm_mqttacls a LEFT JOIN glpi_plugin_flyvemdm_mqttusers u ON (a.plugin_flyvemdm_mqttusers_id = u.id) WHERE u.user='%s' AND u.enabled='1' AND (a.access_level & %d)
auth_opt_cacheseconds 300

根据以上配置文件,你需要授权插件访问数据库的权限,

echo "create user 'mosquitto'@'127.0.0.1' identified by 'mosquittopwd';" | mysql -uroot -p
echo "grant select on glpi.glpi_plugin_flyvemdm_mqttusers to 'mosquitto'@'127.0.0.1';" | mysql -uroot -p
echo "grant select on glpi.glpi_plugin_flyvemdm_mqttacls to 'mosquitto'@'127.0.0.1';" | mysql -uroot -p

配置完成后,我们建议你使用如下命令验证授权,

mysql -h 127.0.0.1 -u mosquitto -pmosquittopwd -e "select * from glpi.glpi_plugin_flyvemdm_mqttusers;"
mysql -h 127.0.0.1 -u mosquitto -pmosquittopwd -e "select * from glpi.glpi_plugin_flyvemdm_mqttacls;"

3.4.2 部署插件到配置文件指定的位置

mkdir -p /usr/lib/mosquitto-auth-plugin/
cp ~/mosquitto-auth-plug-0.1.3/auth-plug.so /usr/lib/mosquitto-auth-plugin/auth-plugin.so

3.4.3 重启服务使配置生效

systemctl restart mosquitto.service

3.4.4 生成认证的密码

cd ~/mosquitto-auth-plug-0.1.3
./np
Enter password: ******
Re-enter same password: ******
PBKDF2$sha256$901$TfeJwr3Khe7sRL/c$IcH6ZM1yNH/Lqrtf2bqryHCv0SfSnXB/

注:以上输入的密码是“123456”

3.4.5 将生成的密码更新到数据库

mysql -uroot -p

登录MySQL服务后,先使用如下命令得到当前的用户信息,

select * from glpi.glpi_plugin_flyvemdm_mqttusers;

加入信息显示如下,

+----+------------------+-----------------------------------------------------------------------------------------------------+---------+
| id | user             | password                                                                                            | enabled |
+----+------------------+-----------------------------------------------------------------------------------------------------+---------+
|  1 | flyvemdm-backend | PBKDF2$sha256$901$zn6nIRzI77i13P0N$ximExVTdO0aoYrAYbeIN/FND6u4udt233peawJFism2grOft97GGfndoIMyW6mD6 |       1 |
+----+------------------+-----------------------------------------------------------------------------------------------------+---------+
1 row in set (0.00 sec)

结合刚才生成的密码,用insert语句在表中增加一行配置新的用户数据,

insert into glpi.glpi_plugin_flyvemdm_mqttusers (user,password,enabled) values ("test","PBKDF2$sha256$901$TfeJwr3Khe7sRL/c$IcH6ZM1yNH/Lqrtf2bqryHCv0SfSnXB/","1");

更新完毕后,使用如下命令确认你的配置,

select * from glpi.glpi_plugin_flyvemdm_mqttusers;

如何显示如下则更新正确完成,

+----+------------------+-----------------------------------------------------------------------------------------------------+---------+
| id | user             | password                                                                                            | enabled |
+----+------------------+-----------------------------------------------------------------------------------------------------+---------+
|  1 | flyvemdm-backend | PBKDF2$sha256$901$zn6nIRzI77i13P0N$ximExVTdO0aoYrAYbeIN/FND6u4udt233peawJFism2grOft97GGfndoIMyW6mD6 |       1 |
|  2 | test             | PBKDF2$sha256$901$TfeJwr3Khe7sRL/c$IcH6ZM1yNH/Lqrtf2bqryHCv0SfSnXB/                                 |       1 |
+----+------------------+-----------------------------------------------------------------------------------------------------+---------+
2 rows in set (0.00 sec)

3.4.6 配置ACL的权限

mysql -uroot -p

登录MySQL服务后,先使用如下命令得到当前的用户ACL信息,

select * from glpi.glpi_plugin_flyvemdm_mqttacls;

加入信息显示如下,

+----+------------------------------+-------+--------------+
| id | plugin_flyvemdm_mqttusers_id | topic | access_level |
+----+------------------------------+-------+--------------+
|  1 |                            1 | #     |            3 |
+----+------------------------------+-------+--------------+
1 row in set (0.00 sec)

注:关于“access_level”的级别,详细如下,

- 值“0”代表“no access”
- 值“1”代表“read”
- 值“2”代表“write”
- 值“3”代表“read and write”
- 值“4”代表“subscribe”
- 值“5”代表“read and subscribe”
- 值“6”代表“write and subscribe”
- 值“7”代表“read, write and subscribe”

使用如下命令增加一行数据配置“test”用户的ACL权限,

insert into glpi.glpi_plugin_flyvemdm_mqttacls (plugin_flyvemdm_mqttusers_id,topic,access_level) values ("2","#","7");

更新完毕后,使用如下命令确认你的更新,

select * from glpi.glpi_plugin_flyvemdm_mqttacls;

如何显示如下则更新正确完成,

+----+------------------------------+-------+--------------+
| id | plugin_flyvemdm_mqttusers_id | topic | access_level |
+----+------------------------------+-------+--------------+
|  1 |                            1 | #     |            3 |
|  2 |                            2 | #     |            7 |
+----+------------------------------+-------+--------------+
2 rows in set (0.00 sec)

3.4.7 订阅主题

mosquitto_sub -t 'test/topic' -v -u test -P 123456

3.4.8 发布消息

mosquitto_pub -t 'test/topic' -m 'hello world' -u test -P 123456

参阅文档
====================

认证插件的hub
—————-
https://github.com/jpmens/mosquitto-auth-plug

软件的下载
—————–
https://github.com/jpmens/mosquitto-auth-plug/releases

其他参考资料
———-
http://www.yasith.me/2016/04/securing-mqtt-connection-using.html

包之间的依赖关系参考
——————-
https://packages.debian.org/sid/mosquitto-auth-plugin
https://packages.debian.org/stretch/net/mosquitto-auth-plugin

没有评论

发表评论

MQTT
如何手动配置Mosquitto的TLS?

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

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

1 基础知识 1.1 前言 本章将借助第三方的脚本(generate-CA.sh)配置Mosquit …

MQTT
如何编译部署Eclipse Mosquitto 1.5.8?

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