+5

Tích hợp cơ chế xác thực, ủy quyền cho Mosquitto Broker sử dụng Plugin mosquitto-go-auth và MySQL (Part 2)

👋Giới thiệu

Hi, mình là Quân. Ở bài biết trước, mình đã chia sẻ tới các bạn cách xây dựng một Mqtt Broker trên máy chủ local Ubuntu 22.04, dựa trên Mosquitto (chi tiết bài viết ở đây). Bài viết này mình sẽ chia sẻ cách tích hợp cơ chế xác thực và ủy quyển cho Mosquitto Broker dựa trên gói mosquitto-go-auth, và đưa máy chủ Mqtt Broker lên internet.

🚀Cài đặt

⚠️Yêu cầu đã cài đặt Mosquitto Broker từ phiên bản 2.0 trở lên.

1. Cài đặt Go:

$ sudo add-apt-repository ppa:longsleep/golang-backports
$ sudo apt update
$ sudo apt install golang-go

Kiểm tra version golang (phiên bản Go tối thiếu của plugin là 1.18):

$ go version
go version go1.22.5 linux/amd64

2. Tải plugin mosquito-go-auth:

$ git clone https://github.com/iegomez/mosquitto-go-auth
$ cd mosquitto-go-auth

3. Xây dựng plugin:

ℹ️ Mình giả định các tệp mosquitto.h, mosquitto_plugin.h, mosquitto_broker.h này đã được cài đặt trong thư mục "/usr/include".

💁Trong trường hợp các tệp trên không có sẵn, các bạn có thể tự tải (tại đây) và đặt chúng vào thư mục bạn muốn. Khi đó các bạn hay sửa lại cờ "CFLAGS" trong tệp MakeFile để thay đổi đường dẫn tới thư mục chứa các tệp header:

# Ví dụ
CFLAGS := -I/usr/include -fPIC

Lưu lại tệp MakeFile và gọi make để xây dựng file go-auth.so

image.png

4. Liên kế tệp go-auth.so vào Mosquitto:

Copy file go-auth.so vào thư mục "/etc/mosquitto/"

$ sudo cp go-auth.so /etc/mosquitto/

bài viết trước, mình đã tạo file "default.conf" để cấu hình bảo mật cho Mosquitto dựa trên file passwd và acls. Bài viết này mình sẽ thay thế chúng bằng plugin mosquitto-go-auth sử dụng MySQL. Sửa file /etc/mosquitto/conf.d/default.conf:

allow_anonymous false
listener 1883  # Cổng kết nối tới Mosquitto Broker

# Liên kết plugin xác thực của Mosquitto tới file go-auth.so
auth_plugin /etc/mosquitto/conf.d/go-auth.so

# Cài đặt cho mosquitto xuất log dưới dạng file
auth_opt_log_level debug
auth_opt_log_dest file
auth_opt_log_file /var/log/mosquitto/mosquitto.log

# Cấu hình kết nối tới MySQL
auth_opt_backends mysql
auth_opt_mysql_host localhost
auth_opt_mysql_port 3306
auth_opt_mysql_user <your_database_username>
auth_opt_mysql_password <your_database_password>
auth_opt_mysql_dbname go_auth_test

# Cài đặt các truy vấn để xác thực và ủy quyền người dùng
auth_opt_mysql_userquery SELECT password_hash FROM test_user WHERE (username = ?) limit 1
auth_opt_mysql_superquery SELECT COUNT(*) FROM test_user WHERE (username = ?) AND (is_admin = 1)
auth_opt_mysql_aclquery SELECT topic FROM test_acl INNER JOIN test_user ON test_user.id=test_acl.test_user_id WHERE (username = ?) AND (rw = ? OR rw=3)

# Cấu hình hàm băm mật khẩu
auth_opt_hasher bcrypt
auth_opt_hasher_cost 10

Trong đó:

Tùy chọn Ý nghĩa
auth_opt_mysql_host Địa chỉ máy chủ MySQL (mặc định là localhost).
auth_opt_mysql_port Cổng kết nối tới MySQL (mặc định là 3306).
auth_opt_mysql_user Tên người dùng để kết nối tới MySQL.
auth_opt_mysql_password Mật khẩu của người dùng MySQL.
auth_opt_mysql_dbname Tên Database dùng để lưu trữ dữ liệu.
auth_opt_mysql_userquery Truy vấn để lấy mật khẩu băm của người dùng từ bảng test_user dựa trên username.
auth_opt_mysql_superquery Truy vấn để kiểm tra xem người dùng có phải là quản trị viên hay không. Nếu người dùng là quản trị viên, người đó có quyền đọc ghi tất cả các chủ đề
auth_opt_mysql_aclquery Truy vấn để lấy danh sách các chủ đề (topics) mà người dùng có quyền truy cập. Trong đó rw = 1 (chỉ đọc), rw = 2 (chỉ ghi), rw = 3 (đọc và ghi), đặc biệt rw = 4 (topic đó có thể được đăng kí). Nếu trường này không được chỉ định thì tất cả user xác thực sẽ có quyền đọc ghi mọi chủ đề.

5. Tiến hành thử nghiệm thôi nào😍:

  • Tạo cơ sở sử liệu MySQL mẫu:
CREATE DATABASE go_auth_test;
USE go_auth_test;
  • Tạo hai bảng test_usertest_acl để xác thực người dùng và phân quyền truy cập vào các chủ đề dựa theo các câu lệnh truy vấn đã cấu hình:
CREATE TABLE test_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 test_acl(
id mediumint not null auto_increment,
test_user_id mediumint not null,
topic varchar(200) not null,
rw int not null,
primary key(id),
foreign key(test_user_id) references test_user(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);

Kết quả:

mysql> SHOW TABLES;
+------------------------+
| Tables_in_go_auth_test |
+------------------------+
| test_acl               |
| test_user              |
+------------------------+
2 rows in set (0.00 sec)
  • Thêm dữ liệu mẫu cho hai bảng:

Tạo người dùng "admin""user1", các bạn sử dụng tools để lấy mật khẩu hashed trước khi thêm vào cơ sở dữ liệu :

INSERT INTO test_user VALUES (NULL, "admin", "mật khẩu sau khi hashed", 1);
INSERT INTO test_user VALUES (NULL, "user1", "mật khẩu sau khi hashed", 0);

Thêm các topics mới (user1 trong bảng test_user có id = 2):

INSERT INTO test_acl VALUES (NULL, 2, "read_topic", 1);
INSERT INTO test_acl VALUES (NULL, 2, "write_topic", 2);
INSERT INTO test_acl VALUES (NULL, 2, "read_write_topic", 3);

Vì người dùng "admin" có quyền truy cập mọi chủ đề nên mình không test nó nữa.

  • Khởi động lại mosquitto.service và kiểm tra trạng thái:
$ sudo systemctl restart mosquitto.service
$ sudo systemctl status mosquitto.service

image.png

Như vậy, các bạn đã cài đặt thành công bảo mật cho Mosquitto Broker sử dụng plugin mosquitto-go-auth với cơ sở dữ liệu MySQL. Nếu người dùng "user1" cố gắng đọc hay đăng kí vào chủ đề không được phép, nó sẽ nhận được thông báo lỗi: image.png

😮 Có thể các bạn sẽ thắc mắc tại sao "user1" không thể đăng kí chủ để "read_topic", ở đây tụi mình cần lưu ý là rw=1 có nghĩa là topic đó có thể được đọc các bản tin xuất bản tại đó nhưng nó không thể được đăng kí nếu không được chỉ định thêm rw=4 trong bảng dữ liệu test_acl.

Plugin mosquitto-go-auth còn rất nhiều tính năng khác mà mình chưa khám phá hết. Do đó nếu các bạn muốn sử dụng với các loại cơ sở dữ liệu khác như Sqlite3, MongoDB, hoặc JWT Backend,... các bạn có thể tham khảo tại đây.

💡 Tổng kết

🤝Như vậy, bài viết này mình đã hướng dẫn các bạn tích hợp plugin Mosquitto-go-auth và MySQL để xác thực và phân quyền người dùng cho Mosquitto Broker. Các bạn có thể xây dựng thêm một Backend RESTfull API và giao diện Dashboard Admin để thêm, sửa, xoá người dùng mới; hoặc theo dõi và quản lý trạng thái thiết bị và dữ liệu của chúng. ♥️Một lần nữa mình xin cảm ơn các bạn đã dành thời gian theo dõi bài viết của mình, nếu có bất kì câu hỏi hay góp ý đừng ngần ngại mà để lại cho mình nhé!😀

🔗 Nguồn tham khảo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí