Nếu bạn đang muốn tạo một mạng MQTT, bắt đầu với việc cài đặt, cấu hình và bảo mật MQTT broker thì bài viết này dành cho bạn. Linux ở đây là các bản phân phối thông dụng họ Debian như Ubuntu, đặc biệt là Raspbian và Armbian dành cho Raspberry Pi và các máy tính một bo mạch – SBC, phù hợp để vận hành các MQTT broker quy mô tương đối (các bản phân phối họ RHEL – Red Hat Enterprise Linux như Centos cũng có thể sử dụng, tuy nhiên cách cài đặt sẽ hơi khác).
Yêu cầu tối thiểu/khuyến nghị
Đầu tiên bạn sẽ cần một máy chủ Linux đã được cài đặt và kết nối mạng thành công. Bạn có thể tham khảo các bước đầu tiên của bài viết này nếu muốn cài đặt Raspbian/Armbian. Với Ubuntu, bạn cần tải về và theo chỉ dẫn trên trang chủ: cài đặt Ubuntu Server.
Bạn cũng cần một tài khoản với quyền root (quản trị) trên máy chủ này để cài đặt phần mềm cũng như chỉnh sửa các thiết lập của hệ thống.
Trong bài này ta sẽ thao tác toàn bộ qua giao diện dòng lệnh (command line) thông qua kết nối SSH hoặc Console (hay Terminal trên Ubuntu). Nếu bạn chưa biết đến kết nối SSH, hãy xem bài viết này: kết nối đến máy chủ SSH rồi quay lại.
Nguyên tắc chung khi nhập các lệnh trong bài này là:
- Lệnh bắt đầu bằng sudo có nghĩa là thực thi với quyền root, có thể bạn sẽ phải nhập mật khẩu tài khoản hiện tại mỗi lần thực hiện lệnh hoặc chỉ lần đầu tiên tuỳ theo cách cấu hình sudo (đừng lo nếu màn hình không hiện gì khi nhập, cứ tiếp tục nhập cho hết).
- Bạn phải copy lệnh từ đầu đến hết dòng, trước khi số dòng thay đổi (lưu ý là số dòng ở ngay trước lệnh, không phải ngắt dòng hiển thị trên màn hình) ngoại trừ các lệnh kết thúc bằng “\” phải được copy cho đến hết dòng đầu tiên không kết thúc bằng kí tự “\” (câu lệnh trên nhiều dòng). Mỗi lệnh này được thực hiện bằng phím Enter.
Bạn cũng có thể copy toàn bộ lệnh rồi paste một lần nhưng sẽ khó để phát hiện lỗi. - Toàn bộ lệnh trong bài này cần được thực hiện nối tiếp nhau trong cùng một phiên đăng nhập.
- Nên thực hiện các lệnh này dưới tài khoản bạn hay dùng (như Pi trong Raspbian), không nên dùng nó dưới tài khoản root.
Cài đặt Mosquitto MQTT Broker
Cài đặt trực tiếp trên Hệ điều hành
Cái lợi của việc cài đặt trực tiếp là thể quản lí, chỉnh sửa Mosquitto broker chung với các thành phần khác của hệ điều hành. Bạn cũng không cần phải cài đặt và tốn tài nguyên máy chủ cho các ứng dụng khác. Cái hại là đôi khi xảy ra xung đột giữa các gói phần mềm trên cùng hệ thống và không thể chạy nhiều broker riêng rẽ trên cùng một hệ điều hành theo cách này được.
Để cài đặt mosquitto, trước tiên cần thêm repository (kho phần mềm) của mosquitto vào danh sách của apt – phần mềm quản lý package chính trên các bản phân phối Linux họ Debian. Lệnh mẫu ở dưới, bạn chỉ sử dụng phần tương ứng với hệ điều hành của mình, đánh dấu bằng kí tự “#” (bỏ qua các dòng chú thích này khi nhập lệnh).
#Ubuntu sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa #Raspbian/Armbian wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key sudo apt-key add mosquitto-repo.gpg.key
Với Raspbian/Armbian, cần tiếp tục thêm các lệnh ở dưới, bạn chọn lệnh tuỳ theo phiên bản hệ điều hành là Jessie (cũ nhất), Stretch hay Buster (mới nhất).
#Raspbian/Armbian cat /etc/os-release #Chọn 1 trong 3 lệnh bên dưới sudo wget http://repo.mosquitto.org/debian/mosquitto-jessie.list sudo wget http://repo.mosquitto.org/debian/mosquitto-stretch.list sudo wget http://repo.mosquitto.org/debian/mosquitto-buster.list
Tiếp theo cập nhật apt và cài đặt mosquitto (broker) và mosquitto-client (tuỳ chọn).
#Ubuntu & Raspbian/Armbian sudo apt-get update sudo apt-get upgrade -y sudo apt-get install -y mosquitto #tuỳ chọn sudo apt-get install mosquitto-clients
Đến đây là bạn đã cài đặt xong và khởi động mosquitto. Mặc định mosquitto cũng tự khởi động cùng hệ điều hành. Có thể xem trạng thái của mosquitto bằng lệnh
systemctl status mosquitto
Ấn phím Q để trở về cửa sổ lệnh.
Cài đặt trên docker
Ưu điểm của việc cài đặt trên Docker là dễ dàng xoá bỏ, cập nhật hay chạy song song nhiều mosquitto broker khác nhau với nhiều cấu hình khác nhau. Nó cũng giúp tránh làm lộn xộn hệ điều hành của bạn với đủ loại package – phần mềm được cài đặt. Nếu bạn đang sử dụng docker để vận hành nhiều dịch vụ khác, đây là cách tốt hơn.
Cài Docker
Trước tiên cần cài đặt docker cho hệ điều hành, bỏ qua nếu đang chạy docker rồi:
#Ubuntu & Raspbian/Armbian sudo apt-get install -y apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common\ avahi-daemon \ dbus \ jq curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh ./get-docker.sh && rm get-docker.sh sudo usermod -aG docker `whoami`
Lưu ý sau câu lệnh cuối, cần thoát ra khỏi phiên đăng nhập hiện tại bằng lệnh exit rồi đăng nhập trở lại để thay đổi về group có hiệu lực.
Tạo container mosquitto
Sau khi hoàn tất, ta tiếp tục tạo container (thuật ngữ trong docker, chỉ môi trường mà ứng dụng sẽ chạy trong đó) mosquitto. Tuy nhiên, trước tiên cần tạo thư mục sẽ chứa cấu hình cũng như toàn bộ dữ liệu – data của mosquitto. Để tăng cường bảo mật, ta sẽ tạo thư mục này bên trong thư mục người dùng hiện tại (~) và ẩn nó khi đặt tên bắt đầu bằng kí tự “.“.
#Ubuntu & Raspbian/Armbian cd ~ mkdir -p .mosquitto/data && cd .mosquitto
Tiếp sau, tạo container có tên mosquitto và mount các thư mục ~/.mosquitto và ~/.mosquitto/data đã tạo ở trên vào container này. Trước đó, cần tải về file cấu hình mẫu mosquitto.conf từ github của eclipse, đơn vị phát triển mosquitto bằng ứng dụng wget.
#Ubuntu & Raspbian/Armbian wget https://raw.githubusercontent.com/eclipse/mosquitto/master/mosquitto.conf docker run --name mosquitto -p 1883:1883 -v ~/.mosquitto:/mosquitto/config -v ~/.mosquitto/data:/mosquitto/data --restart unless-stopped eclipse-mosquitto
Trong đó –name là tuỳ chọn đặt tên container, -p là tuỳ chọn map port (nôm na tương tự port forwarding) 1883 của mosquitto sang port 1883 của máy chủ, -v ~/.mosquitto:/mosquitto/config là lệnh mount thư mục ~/.mosquitto vào thư mục /mosquitto/config trong container.
Nếu các lệnh đều thành công, mosquitto broker đã cài đặt và chạy thành công bên trong container có tên mosquitto. Ấn tổ hợp phím Ctrl-C để tạm ngừng container và thoát ra.
Bạn có thể chạy – start, dừng – stop hoặc xoá – rm container này với các lệnh sau, cấu hình hay dữ liệu sẽ không bị mất đi.
#Ubuntu & Raspbian/Armbian docker start mosquitto docker stop mosquitto docker rm mosquitto
Cập nhật mosquitto trên docker
Các bản cập nhật mosquitto sẽ được phát hành dưới dạng các image mới. Do vậy, để cập nhật, bạn cần pull – tải image mới nhất (latest) về và tạo lại container.
#Ubuntu & Raspbian/Armbian docker pull mosquitto:latest docker stop mosquitto docker rm mosquitto docker run --name mosquitto -p 1883:1883 -v ~/.mosquitto:/mosquitto/config -v ~/.mosquitto/data:/mosquitto/data --restart unless-stopped eclipse-mosquitto
Lệnh docker quá dài? Sử dụng docker compose để tạo và lưu cấu hình một lần duy nhất, tiện cập nhật về sau.
Tường lửa Ubuntu
Hệ điều hành Ubuntu đi kèm ứng dụng tường lửa UFW – Uncomplicated Firewall. Tuy mặc định tường lửa này không được kích hoạt, bạn có thể kiểm tra trạng thái của nó với lệnh sudo ufw status
.
Nếu trạng thái là active hoặc firewall loaded, bạn cần cấu hình UFW mở – allow các cổng cần thiết đối với mosquitto broker. Ví dụ nếu bạn chỉ cấu hình mosquitto sử dụng cổng 1883:
sudo ufw allow 1883 sudo ufw
Home Assistant: kết nối thiết bị Zigbee qua zigbee2mqtt
IOT: giao thức MQTT
Bảo mật Mosquitto Broker
Cấu hình xác thực username/password
Cấu hình mosquitto sử dụng xác thực
Cấu hình chính của mosquitto được lưu trong file mosquitto.conf. File này nằm tại:
- /etc/mosquitto/mosquitto.conf nếu bạn cài đặt trực tiếp trên hệ điều hành
- ~/.mosquitto/mosquitto.conf như ta đã tạo và tải về khi cài đặt trong Docker
Ta cần sửa file này để thay đổi một số cài đặt liên quan đến bảo mật.
#OS sudo nano /etc/mosquitto/mosquitto.conf #Docker cd ~/.mosquitto nano mosquitto.conf
Nếu nhận được kết quả nano: command not found, dùng lệnh sudo apt-get install -y nano
để cài đặt nano – trình soạn thảo văn bản trước khi chạy lại các lệnh trên.
File mosquitto.conf có thể rất ngắn hoặc rất dài (như file tải về trên docker), tuy nhiên bạn chỉ cần thêm 2 dòng bên dưới vào cuối file. Sau đó ấn Ctrl-X rồi Y để lưu lại.
#OS allow_anonymous false password_file /etc/mosquitto/passwd #Docker allow_anonymous false password_file /mosquitto/config/passwd
Với lệnh trên, ta cấu hình mosquitto:
- Chỉ cho phép kết nối khi đã xác thực
- Sử dụng nội dung file passwd để xác thực
Tạo file chứa username/password
Ta tiếp tục tạo file passwd hiện chưa có bằng tiện ích mosquitto_passwd đi cùng mosquitto đã cài, thay myuser bằng tên người dùng bạn chọn.
#OS sudo mosquitto_passwd -c /etc/mosquitto/passwd myuser #Docker docker start mosquitto docker exec -it mosquitto mosquitto_passwd -c /mosquitto/config/passwd myuser
Với -c
là tuỳ chọn tạo mới file passwd chưa có, docker exec -it mosquitto
để chạy một lệnh bên trong container mosquitto. Sau khi chạy lệnh tạo file passwd, nhập mật khẩu/xác nhận mật khẩu rồi Enter để hoàn tất.
Khởi động lại mosquitto để tải cấu hình mới. Bạn phải làm điều này mỗi khi thay đổi cấu hình, cập nhật hay thêm username/password.
#OS sudo systemctl restart mosquitto #Docker docker restart mosquitto
Bây giờ bạn có thể sử dụng mqtt client bất kỳ để publish và subscribe vào broker mới.
Thêm, xoá, sửa username/password
Thêm username có tên myuser2
#OS sudo mosquitto_passwd /etc/mosquitto/passwd myuser2 #Docker docker exec -it mosquitto mosquitto_passwd /mosquitto/config/passwd myuser2
Thay đổi password cho username myuser2
#OS sudo mosquitto_passwd -U /etc/mosquitto/passwd myuser2 #Docker docker exec -it mosquitto mosquitto_passwd -U /mosquitto/config/passwd myuser2
Xoá username/password của myuser2
#OS sudo mosquitto_passwd -D /etc/mosquitto/passwd myuser2 #Docker docker exec -it mosquitto mosquitto_passwd -D /mosquitto/config/passwd myuser2
Mosquitto ACL
ACL – Access Control List sử dụng một file cấu hình (acl) để giới hạn/cho phép mỗi username chỉ được subscribe và publish vào một số topic nhất định. ACL không phức tạp nhưng lại hạn chế các quyền truy cập của client rất mạnh (tương tự triết lý “cấm tất cả những gì không quản được“), do vậy bạn phải cẩn trọng chỉ áp dụng khi thật sự cần thiết.
Tạo file acl
Mosquitto đi kèm với một file aclfile.example mẫu tại /etc/mosquitto/aclfile.example nếu cài trên OS hoặc có thể tải về từ github khi cài trong Docker. Ta sẽ copy/download file này thành một file mới có tên acl.
#OS sudo cp /etc/mosquitto/aclfile.example /etc/mosquitto/acl #Docker cd ~/.mosquitto wget https://raw.githubusercontent.com/eclipse/mosquitto/master/aclfile.example -O acl
Nội dung file này như ở dưới, bạn có thể sửa bằng ứng dụng nano tương tự các bước trên.
File này gồm 3 phần – section:
- Phần trên cùng là danh sách topic và quyền (read/write/readwrite) áp dụng cho tất cả client không cung cấp username khi kết nối. Các client này không có quyền đối với mọi topic không liệt kê ở đây hay ở section 3.
Trong cấu hình mẫu thì các client này được cho phép xem thông tin trạng thái của broker. - Phần 2 là danh sách topic mà một client kết nối với username có trong danh sách được phép publish và subcribe. Lưu ý rằng một username/password có thể được sử dụng bởi nhiều client.
- Phần 3 dành cho các client có cung cấp client_id hoặc user_id, cho phép một client được publish/subscribe vào danh sách topic quy định sẵn. Không như username/password, client_id không được phép dùng chung.
Section 2
Bắt đầu bằng user username, tiếp theo là danh sách các topic mà username này được phép publish & subscribe trên từng dòng riêng. Bạn có thể dùng các topic # và ? để cấp quyền. (xem topic # và ?)
Ví dụ, ở đây ta sẽ cấp quyền cho user tasmota quyền truy cập đến các topic tele/#, cmnd/# và homeassistant/?/switch
# This affects access control for clients with no username. topic read $SYS/# # This only affects clients with username "roger". user tasmota topic tele/# topic cmnd/# topic homeassistant/?/switch # This affects all clients. pattern write $SYS/broker/connection/%c/state
Section 3
Bắt đầu bằng pattern, tiếp theo là quyền read/write/readwrite, cuối cùng là topic. Ngoài các topic # và ?, bạn được sử dụng %c để thay thế cho client_id và %u để thay thế cho user_id.
Ví dụ, ta cấp quyền cho client có id là tasmota_79 quyền readwrite đến mọi topic tele/tasmota_79/# và cmnd/tasmota_79/#
# This affects access control for clients with no username. topic read $SYS/# # This only affects clients with username "roger". user roger topic foo/bar # This affects all clients. pattern readwrite tele/%c/# pattern readwrite cmnd/%c/#
Kích hoạt file ACL
Sau khi cấu hình xong file acl, kích hoạt bằng cách khai báo trong file mosquitto.conf rồi khởi động lại mosquitto.
Lần nữa lưu ý các bạn là ACL kiểm soát quyền rất chặt chẽ với phương châm “cấm tất cả những gì không quản được“, do vậy bạn phải cẩn trọng khi kích hoạt nó.
Thêm dòng sau vào cuối file mosquitto.conf (cách làm tương tự bước Cấu hình username/password).
#OS acl_file /etc/mosquitto/acl #Docker acl_file /mosquitto/config/acl
Sau đó khởi động lại mosquitto để áp dụng.
Cảm ơn bạn đã xem bài viết này!
konnectED Team.