Tech

Cài đặt và bảo mật Mosquitto MQTT Broker trên Linux

Konnect Mosquitto & Linux

Cài đặt và bảo mật mosquitto broker trực tiếp trên Linux hoặc qua Docker

Mosquitto Konnects Pis
19 phút để đọc hết nội dung

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à:

  1. 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).
  2. 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.
  3. 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.
  4. 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.

Trạng thái service mosquitto
Trạng thái active của service mosquitto

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~/.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.

mosquitto bên trong docker container
Kết quả chạy thành công mosquitto trên Docker

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 
How MQTT Works
IOT: giao thức MQTT
Cơ bản về giao thức MQTT, tại sao nó hiệu quả với các thiết bị IOT và sơ lược về bảo mật MQTT
Xem Ngay

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
mosquitto.conf
Nội dung file /etc/mosquitto/mosquitto.conf

Với lệnh trên, ta cấu hình mosquitto:

  1. Chỉ cho phép kết nối khi đã xác thực
  2. 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.

Tạo mosquitto passwd
Nội dung file passwd đã tạo

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.

Nội dung file acl mẫu
Nội dung file acl mẫu

File này gồm 3 phần – section:

  1. 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.
  2. 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.
  3. 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/# 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%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/#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.

Lên Đầu
  • Đăng ký
Bạn quên mất mật khẩu? Vui lòng nhập tên đăng nhập và địa chỉ email đã đăng ký. Bạn sẽ nhận được liên kết tạo mật khẩu mới qua email (bạn nhớ kiểm tra hộp spam trong trường hợp email đi lạc).