前言
在前文 编译 mosquitto 和 mosquitto-auth-plug 中,详细描述了 mosquitto
和 mosquitto-auth-plug
的编译构建过程。
接下来,我们将开始在 编译 mosquitto 和 mosquitto-auth-plug 基础上,对 mosquitto-auth-plug
进行调试。
调试 mosquitto-auth-plug 用户鉴权
mosquitto
项目的 mosquitto_plugin.h
文件中的用户鉴权接口定义。
/*
* Function: mosquitto_auth_unpwd_check
*
* This function is OPTIONAL. Only include this function in your plugin if you
* are making basic username/password checks.
*
* Called by the broker when a username/password must be checked.
*
* Return:
* MOSQ_ERR_SUCCESS if the user is authenticated.
* MOSQ_ERR_AUTH if authentication failed.
* MOSQ_ERR_UNKNOWN for an application specific error.
* MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check.
*/
mosq_plugin_EXPORT int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password);
1)查询 auth-plug.so
(mosquitto-auth-plug
编译结果)的位置。
$ pwd
/tmp/tmp.dHVBlwblW0
$ ls -al | grep .so
-rwxr-xr-x 1 meikai meikai 61584 Jul 2 11:05 auth-plug.so
2)在 mosquitto
项目中的 mosquitto.conf
文件中新增如下配置:
# -----------------------------------------------------------------
# External authentication and topic access plugin options
# -----------------------------------------------------------------
# External authentication and access control can be supported with the
# auth_plugin option. This is a path to a loadable plugin. See also the
# auth_opt_* options described below.
#
# The auth_plugin option can be specified multiple times to load multiple
# plugins. The plugins will be processed in the order that they are specified
# here. If the auth_plugin option is specified alongside either of
# password_file or acl_file then the plugin checks will be made first.
#
#auth_plugin
auth_plugin /tmp/tmp.dHVBlwblW0/auth-plug.so
3)启动 mosquitto
进程
命令启动
$ /tmp/tmp.rcJYQzXv2I/cmake-build-debug/src/mosquitto -c /tmp/tmp.rcJYQzXv2I/mosquitto.conf
或者,在 CLion 中添加 【Program arguments】的形式启动
image.png
控制台输出:
1625195356: mosquitto version 2.0.11 starting
1625195356: Config loaded from /tmp/tmp.rcJYQzXv2I/mosquitto.conf.
1625195356: Loading plugin: /tmp/tmp.dHVBlwblW0/auth-plug.so
1625195356: |-- *** auth-plug: startup
|-- No backends configured.
|-- *** ABORT.
在 mosquitto-auth-plug
项目的 auth-plug.c
文件中可以找到 No backends configured
日志对应的代码行。
4)完善第(2)步 mosquitto.conf
文件中的 auth_plugin
配置。
#auth_plugin
auth_plugin /tmp/tmp.dHVBlwblW0/auth-plug.so
auth_opt_backends redis
控制台输出:
/tmp/tmp.rcJYQzXv2I/cmake-build-debug/src/mosquitto -c /tmp/tmp.rcJYQzXv2I/mosquitto.conf
1625195930: mosquitto version 2.0.11 starting
1625195930: Config loaded from /tmp/tmp.rcJYQzXv2I/mosquitto.conf.
1625195930: Loading plugin: /tmp/tmp.dHVBlwblW0/auth-plug.so
1625195930: |-- *** auth-plug: startup
1625195930: |-- ** Configured order: redis
1625195930: |-- }}}} Redis
1625195930: Starting in local only mode. Connections will only be possible from clients running on this machine.
1625195930: Create a configuration file which defines a listener to allow remote access.
1625195930: For more details see https://mosquitto.org/documentation/authentication-methods/
1625195930: Opening ipv4 listen socket on port 1883.
1625195930: Opening ipv6 listen socket on port 1883.
1625195930: Error: Cannot assign requested address
1625195930: mosquitto version 2.0.11 running
【安装 redis】
问题:
1625195544: |-- }}}} Redis
1625195544: |-- Redis connection error: Connection refused for localhost:6379
|-- redis init returns NULL
|-- *** ABORT.
解决方法,安装 redis-server:
$ sudo apt install redis-server
安装后使用 redis-cli
命令进行测试
$ redis-cli
127.0.0.1:6379> keys *
(empty list or set)
5)通过 mosquitto_sub
命令连接到 mosquitto
进程。
$ /tmp/tmp.rcJYQzXv2I/cmake-build-debug/client/mosquitto_sub -t test -u admin -P 123456
Connection error: Connection Refused: not authorised.
-
-t
:指定 topic -
-u
:指定 broker 访问用户 -
-P
:指定 broker 访问密码
broker
指的就是 mosquitto
进程。
$ /tmp/tmp.rcJYQzXv2I/cmake-build-debug/src/mosquitto -h
mosquitto version 2.0.11
mosquitto is an MQTT v5.0/v3.1.1/v3.1 broker.
...
6)修改 mosquitto-auth-plug
项目的 auth-plug.c
文件中的 mosquitto_auth_unpwd_check
方法:
match = (strcmp((char *)password, phash) == 0);
修改前后对比如下所示:
7)重新编译 mosquitto-auth-plug
项目生成 auth-plug.so
并运行 mosquitto
项目。并在在 redis 中设置配置鉴权使用的用户名和密码。
meikai@test:~$ redis-cli
127.0.0.1:6379> set admin 123456
OK
127.0.0.1:6379> get admin
"123456"
8)再次通过 mosquitto_sub
连接到 mosquitto
进程。
# 连接成功
$ /tmp/tmp.rcJYQzXv2I/cmake-build-debug/client/mosquitto_sub -t test -u admin -P 123456
# 连接失败
$ /tmp/tmp.rcJYQzXv2I/cmake-build-debug/client/mosquitto_sub -t test -u adminP 1234567
Connection error: Connection Refused: not authorised.
调试 mosquitto-auth-plug topic 鉴权
mosquitto
项目的 mosquitto_plugin.h
文件中的 topic 鉴权接口定义。
/*
* Function: mosquitto_auth_acl_check
*
* Called by the broker when topic access must be checked. access will be one
* of:
* MOSQ_ACL_SUBSCRIBE when a client is asking to subscribe to a topic string.
* This differs from MOSQ_ACL_READ in that it allows you to
* deny access to topic strings rather than by pattern. For
* example, you may use MOSQ_ACL_SUBSCRIBE to deny
* subscriptions to '#', but allow all topics in
* MOSQ_ACL_READ. This allows clients to subscribe to any
* topic they want, but not discover what topics are in use
* on the server.
* MOSQ_ACL_READ when a message is about to be sent to a client (i.e. whether
* it can read that topic or not).
* MOSQ_ACL_WRITE when a message has been received from a client (i.e. whether
* it can write to that topic or not).
*
* Return:
* MOSQ_ERR_SUCCESS if access was granted.
* MOSQ_ERR_ACL_DENIED if access was not granted.
* MOSQ_ERR_UNKNOWN for an application specific error.
* MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check.
*/
mosq_plugin_EXPORT int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg);
#define MOSQ_ACL_READ 0x01
#define MOSQ_ACL_WRITE 0x02
#define MOSQ_ACL_SUBSCRIBE 0x04
struct mosquitto_acl_msg {
const char *topic;
const void *payload;
long payloadlen;
int qos;
bool retain;
};
1)在 mosquitto
项目中的 mosquitto.conf
文件中新增如下配置:
auth_opt_redis_aclquery GET acl:%s:%s
2)通过 mosquitto_sub
连接到 mosquitto
进程。
$ /tmp/tmp.rcJYQzXv2I/cmake-build-debug/client/mosquitto_sub -t test -u admin -P 123456
All subscription requests were denied.
3)在 redis 中设置配置 topic 鉴权使用的 key 和 access 值。
meikai@test:~$ redis-cli
127.0.0.1:6379> get acl:admin:test
(nil)
127.0.0.1:6379> set acl:admin:test 4
OK
127.0.0.1:6379> get acl:admin:test
"4"
4)再次通过 mosquitto_sub
连接到 mosquitto
进程。
# 连接成功
$ /tmp/tmp.rcJYQzXv2I/cmake-build-debug/client/mosquitto_sub -t test -u admin -P 123456
# 连接失败
$ /tmp/tmp.rcJYQzXv2I/cmake-build-debug/client/mosquitto_sub -t test123 -u admin -P 123456
All subscription requests were denied.
至此,已经对 mosquitto-auth-plug 实现的【用户鉴权】和【topic 鉴权】进行了初步调试。
后面有机会再进行深入剖析。
网友评论