天天看點

CentOS8下Mosquitto安裝使用指南

這裡寫自定義目錄标題

    • 環境準備
      • 關閉linuxse
      • 打開防火牆端口
      • 配置dnf
      • 安裝wget
      • 安裝tar
      • 安裝make
      • 安裝g++
      • 安裝openssl開發工具包
    • 安裝Mosquitto
      • 下載下傳編譯
      • 配置啟動
      • 設定開機啟動
      • 測試
    • 安裝mosquitto-go-auth
      • 安裝go環境
      • 下載下傳編譯mosquitto-go-auth
      • 準備MySQL
        • 安裝啟動MySQL
        • 修改root密碼
        • 準備資料庫和表結構
        • 準備測試賬号
      • 配置運作mosquitto-go-auth
        • 關閉匿名通路
        • 建立日志目錄和配置日志設定
        • 配置mosquitto-go-auth插件相關設定
      • 測試一下
    • 配置TLS
      • 機器準備和命名
      • 使用openssl生成相關證書
        • 準備/etc/mosquitto/certs目錄
        • Certificate Authority
        • Server
        • Client
      • TLS單向認證
        • 修改配置
        • 測試
        • TLS單向認證下的多個broker橋接
      • TLS雙向認證
        • 修改配置
        • 測試
        • TLS雙向認證下的多個broker橋接

環境準備

檢視系統版本

cat /etc/redhat-release
           

CentOS Linux release 8.2.2004 (Core)

關閉linuxse

臨時關閉:

setenforce 0

永久關閉:修改/etc/selinux/config 檔案将SELINUX=enforcing改為SELINUX=disabled,然後重新開機

檢視狀态:

getenforce

打開防火牆端口

firewall-cmd --zone=public --add-port=1883/tcp --permanent
firewall-cmd --zone=public --add-port=8883/tcp --permanent
firewall-cmd --reload
           

配置dnf

vi /etc/dnf/dnf.conf
           

再最下方加入一行

fastestmirror=True
           

儲存退出之後執行:

dnf clean all
dnf makecache
           

安裝wget

dnf install wget -y

安裝tar

dnf install tar -y

安裝make

dnf install make -y

安裝g++

dnf install gcc-c++ -y

安裝openssl開發工具包

dnf install openssl-devel -y

安裝Mosquitto

下載下傳編譯

wget https://mosquitto.org/files/source/mosquitto-1.6.10.tar.gz
tar -zxvf mosquitto-1.6.10.tar.gz
cd mosquitto-1.6.10
make
make install
           

配置啟動

cd /etc/mosquitto/
mv mosquitto.conf.example  mosquitto.conf
mosquitto -c /etc/mosquitto/mosquitto.conf
           

出現如下錯誤:

1596531761: Error: Invalid user 'mosquitto'.
           

為解決此問題,需要給系統建立mosquitto使用者群組:

groupadd mosquitto
useradd -g mosquitto mosquitto

chown -R mosquitto:mosquitto /etc/mosquitto/
           

建立完之後再次嘗試啟動,應該就能成功啟動了。

如果要背景運作,則加入-d參數,完整指令如下:

mosquitto -c /etc/mosquitto/mosquitto.conf  -d
           

-c參數是指定配置檔案,-d參數是指定背景運作

設定開機啟動

便攜啟動檔案

vi /usr/lib/systemd/system/mosquittod.service
           

腳本内容如下

[Unit]
Description=Mosquitto 1.6.10 mqtt server
After=network.target

[Service]
Type=forking
User=mosquitto
Group=mosquitto

ExecStart=/usr/local/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf  -d

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300

# Place temp files in a secure directory, not /tmp
PrivateTmp=true

[Install]
WantedBy=multi-user.target
           

修改檔案權限:

chmod 644 /usr/lib/systemd/system/mosquittod.service
           

使配置生效:

systemctl daemon-reload
           

設為開機啟動:

systemctl enable mosquittod.service
           

測試

訂閱一個主題,如test:

出現如下錯誤:

mosquitto_sub: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory
           

解決辦法,是建立一個符号連結:

ln -s /usr/local/lib/libmosquitto.so.1  /usr/lib/libmosquitto.so.1
ldconfig
           

然後再次執行

mosquitto_sub -t test

訂閱test主題,應該就可以成功了。

再開一個終端視窗給test主題釋出一條消息:

訂閱的視窗将列印

hello

安裝mosquitto-go-auth

安裝go環境

dnf install golang -y
           

下載下傳編譯mosquitto-go-auth

wget https://github.com/iegomez/mosquitto-go-auth/archive/1.0.0.tar.gz -O ./mosquitto-go-auth-1.0.0.tar.gz
tar -zxvf mosquitto-go-auth-1.0.0.tar.gz
cd mosquitto-go-auth-1.0.0
export CGO_CFLAGS="-I/usr/local/include -fPIC"
export CGO_LDFLAGS="-shared"
make
           

make的時候可能出現如下這樣的一個錯:

go: github.com/brocaar/[email protected]+incompatible: Get https://proxy.golang.org/github.com/brocaar/lora-app-server/@v/v2.5.1+incompatible.mod: dial tcp 34.64.4.81:443: i/o timeout
make: *** [Makefile:2: all] Error 1
           

解決辦法是設定代理

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
make
           

準備MySQL

安裝啟動MySQL

wget https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm
yum install mysql80-community-release-el8-1.noarch.rpm
yum install mysql-server
service mysqld start
           

修改root密碼

登入MySQL并修改密碼,剛剛安裝好的是沒有密碼的,直接回車即可登入進去

mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED BY '1234';
           

準備資料庫和表結構

CREATE SCHEMA `mosquitto` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin ;

use mosquitto;

create table mosquitto_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 mosquitto_acl(
id mediumint not null auto_increment,
mosquitto_user_id mediumint not null,
topic varchar(200) not null,
rw int not null COMMENT '1:readonly, 2:writeonly ,3:readwrite ,4:subscribe ',
primary key(id),
foreign key(mosquitto_user_id) references mosquitto_user(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);

insert into mosquitto_user(username, password_hash,is_admin) values('admin','',1);
           

準備測試賬号

使用mosquitto-go-auth編譯出來的pw指令生成pbkdf2的密碼,

cd ~/mosquitto-go-auth-1.0.0
./pw -l 64 -p 123456
           

生成的如下的字元串可以作為mosquitto使用者的密碼

PBKDF2$sha512$100000$ooBf5L/ANImpDrhOCiAMpg==$BzO004Rc5bT44/E/PMQluJ7Bobf7ffixw/Z3b9iB55No6c/QGy4VgQMBzsLOU9XTJx93qxd/1nKhdCa+HJm1Tw==
           

登入MySQL,建立測試使用者

mysql -uroot -p1234
           
-- 插入一個管理者賬号和兩個普通賬号
insert into mosquitto_user(username, password_hash,is_admin) values('admin','PBKDF2$sha512$100000$ooBf5L/ANImpDrhOCiAMpg==$BzO004Rc5bT44/E/PMQluJ7Bobf7ffixw/Z3b9iB55No6c/QGy4VgQMBzsLOU9XTJx93qxd/1nKhdCa+HJm1Tw==',1),('yuanpan1','PBKDF2$sha512$100000$ooBf5L/ANImpDrhOCiAMpg==$BzO004Rc5bT44/E/PMQluJ7Bobf7ffixw/Z3b9iB55No6c/QGy4VgQMBzsLOU9XTJx93qxd/1nKhdCa+HJm1Tw==',0),('yuanpan2','PBKDF2$sha512$100000$ooBf5L/ANImpDrhOCiAMpg==$BzO004Rc5bT44/E/PMQluJ7Bobf7ffixw/Z3b9iB55No6c/QGy4VgQMBzsLOU9XTJx93qxd/1nKhdCa+HJm1Tw==',0);

--  給兩個普通賬号插入權限控制資料,管理者賬号不需要插入
insert into mosquitto_acl(mosquitto_user_id, topic, rw) values(2,'/test/#',1),(2,'/test/#',2),(2,'/test/#',3),(2,'/test/#',4),(3,'/test/#',1),(3,'/test/#',2),(3,'/test/#',3),(3,'/test/#',4);
           

配置運作mosquitto-go-auth

關閉匿名通路

vi /etc/mosquitto/mosquitto.conf
# 将如下配置設定為false
allow_anonymous false 
           

建立日志目錄和配置日志設定

cd /var/log
mkdir mosquitto
chown -R mosquitto:mosquitto /var/log/mosquitto/


vi /etc/mosquitto/mosquitto.conf
# 将log_dest,log_type,connection_messages做如下設定
log_dest file /var/log/mosquitto/mosquitto.log
log_type all
connection_messages true
           

配置mosquitto-go-auth插件相關設定

cd /etc/mosquitto/
vi mosquitto.conf 
# 到檔案末尾配置
include_dir /etc/mosquitto/conf.d


mkdir plugins
cd plugins
cp ~/mosquitto-go-auth-1.0.0/go-auth.so .


cd ..
mkdir conf.d
vi mosquitto-go-auth.conf
# 寫入如下資料到mosquitto-go-auth.conf檔案
auth_plugin /etc/mosquitto/plugins/go-auth.so

auth_opt_backends mysql

# Cache
#auth_opt_cache true
#auth_opt_cache_type redis
#auth_opt_cache_reset true

#auth_opt_auth_cache_seconds 30
#auth_opt_acl_cache_seconds 30

#auth_opt_cache_host localhost
#auth_opt_cache_port 6379
#auth_opt_cache_password pwd
#auth_opt_cache_db 3

#Logging
auth_opt_log_level debug
auth_opt_log_dest file
auth_opt_log_file /var/log/mosquitto/mosquitto-go-auth.log


# Hashing
auth_opt_hasher pbkdf2
auth_opt_hasher_salt_size 16                 # salt bytes length
auth_opt_hasher_iterations 100000            # number of iterations
auth_opt_hasher_keylen 64                    # key length
auth_opt_hasher_algorithm sha512             # hashing algorithm, either sha512 (default) or sha256
auth_opt_hasher_salt_encoding base64         # salt encoding, either base64 (default) or utf-8

# MySQL
auth_opt_mysql_host localhost
auth_opt_mysql_port 3306
auth_opt_mysql_dbname mosquitto
auth_opt_mysql_user root
auth_opt_mysql_password 1234
auth_opt_mysql_allow_native_passwords true
auth_opt_mysql_userquery SELECT password_hash FROM mosquitto_user WHERE username = ? limit 1
auth_opt_mysql_superquery SELECT COUNT(1) FROM mosquitto_user WHERE username = ? AND is_admin = 1 LIMIT 1
auth_opt_mysql_aclquery SELECT topic FROM mosquitto_acl acl  inner join mosquitto_user user on acl.mosquitto_user_id = user.id WHERE user.username = ? AND acl.rw = ?

           

以上配置完之後,運作下mosquitto試試

mosquitto -c /etc/mosquitto/mosquitto.conf
           

測試一下

訂閱/test/1主題

mosquitto_sub  -t /test/1 -u yuanpan1 -P 123456
           

給/test/1主題發送一個hello消息

mosquitto_pub  -t /test/1 -m "hello" -u yuanpan2 -P 123456
           

配置TLS

機器準備和命名

這部分的内容将和mosquitto的橋接一起來寫,準備3台虛拟機,配置其 /etc/hosts檔案,來為虛拟機命名

192.168.20.200 server.mosquitto1.vm client.mosquitto1.vm ca.mosquitto1.vm
192.168.20.201 server.mosquitto2.vm client.mosquitto2.vm
192.168.20.202 server.mosquitto3.vm client.mosquitto3.vm
           

使用openssl生成相關證書

準備/etc/mosquitto/certs目錄

在第一台虛拟機

server.mosquitto1.vm

上執行如下:

cd /etc/mosquitto/
mkdir certs
cd certs
           

Certificate Authority

Generate a certificate authority certificate and key.

openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.crt
           

先輸入兩遍密碼,剩下的可以參考如下:

Country Name : CN

State or Province Name : HuBei

Locality Name (eg, city) : WuHan

Organization Name (eg, company) : Test

Organizational Unit Name (eg, section) : CA

Common Name (eg, your name or your server’s hostname) : ca.mosquitto1.vm

Email Address : [email protected]

這裡注意,Common Name 是ca.mosquitto1.vm

Server

Generate a server key.

openssl genrsa -out server.key 2048
           

Generate a certificate signing request to send to the CA.

openssl req -out server.csr -key server.key -new
           

先輸入兩遍密碼,剩下的可以參考如下:

Country Name : CN

State or Province Name : HuBei

Locality Name (eg, city) : WuHan

Organization Name (eg, company) : Test

Organizational Unit Name (eg, section) : Server

Common Name (eg, your name or your server’s hostname) : server.mosquitto1.vm

Email Address : [email protected]

這裡注意,Common Name,在第一台機器,填server.mosquitto1.vm,在第二台機器填server.mosquitto2.vm,第三台機器填server.mosquitto3.vm

Send the CSR to the CA, or sign it with your CA key:

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650
           

将虛拟機的證書放到

/ect/mosquitto/certs/server.mosquitto1.vm

目錄下

mkdir server.mosquitto1.vm
mv server.crt server.mosquitto1.vm/
mv server.csr server.mosquitto1.vm/
mv server.key server.mosquitto1.vm/
           
繼續執行上面生成Server證書的步驟來生成server.mosquitto2.vm的Server證書,并放入到

/ect/mosquitto/certs/server.mosquitto1.vm

目錄下;生成server.mosquitto3.vm的Server證書,并放入到

/ect/mosquitto/certs/server.mosquitto3.vm

目錄下
mkdir server.mosquitto2.vm
mv server.crt server.mosquitto2.vm/
mv server.csr server.mosquitto2.vm/
mv server.key server.mosquitto2.vm/

mkdir server.mosquitto3.vm
mv server.crt server.mosquitto3.vm/
mv server.csr server.mosquitto3.vm/
mv server.key server.mosquitto3.vm/
           

Client

Generate a client key.

openssl genrsa -out client.key 2048
           

Generate a certificate signing request to send to the CA.

openssl req -out client.csr -key client.key -new
           

Country Name : CN

State or Province Name : HuBei

Locality Name (eg, city) : WuHan

Organization Name (eg, company) : Test

Organizational Unit Name (eg, section) : Client

Common Name (eg, your name or your server’s hostname) : client.mosquitto1.vm

Email Address : [email protected]

這裡注意,Common Name,在第一台機器,填client.mosquitto1.vm,在第二台機器填client.mosquitto2.vm,第三台機器填client.mosquitto3.vm

Send the CSR to the CA, or sign it with your CA key:

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 3650
           

将虛拟機的證書放到

/ect/mosquitto/certs/client.mosquitto1.vm

目錄下

mkdir client.mosquitto1.vm
mv client.crt client.mosquitto1.vm/
mv client.csr client.mosquitto1.vm/
mv client.key client.mosquitto1.vm/
           
繼續執行上面生成Server證書的步驟來生成server.mosquitto2.vm的Server證書,并放入到

/ect/mosquitto/certs/server.mosquitto1.vm

目錄下;生成server.mosquitto3.vm的Server證書,并放入到

/ect/mosquitto/certs/server.mosquitto3.vm

目錄下
mkdir client.mosquitto2.vm
mv client.crt client.mosquitto2.vm/
mv client.csr client.mosquitto2.vm/
mv client.key client.mosquitto2.vm/

mkdir client.mosquitto3.vm
mv client.crt client.mosquitto3.vm/
mv client.csr client.mosquitto3.vm/
mv client.key client.mosquitto3.vm/
           

TLS單向認證

修改配置

vi /etc/mosquitto/mosquitto.conf

# 修改如下配置
port 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.mosquitto1.vm/server.crt
keyfile /etc/mosquitto/certs/server.mosquitto1.vm/server.key
require_certificate false
tls_version tlsv1.2
           
上面是虛拟機1的配置,在配置虛拟機2和3的時候注意修改證書檔案路徑

單向認證和雙向認證的差別在于

require_certificate

這個配置項

配置完成之後三台機器都啟動好mosquitto

測試

開啟了TLS之後我用

mosquitto_sub

mosquitto_sub

指令都得到一個錯誤

Error: A TLS error occurred.

但是如果是使用工具,如MQTT.fx就沒問題

這個問題弄清楚了,是因為證書的Common Name導緻的。需要在mosquitto_sub指令的參數中指定

-h

參數跟證書的Common Name一緻就可以了。

下面開始在第一台虛拟機上測試,先訂閱一個

/test/1

的主題

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --tls-version tlsv1.2
           

再向這個主題釋出一個消息

mosquitto_pub -u yuanpan1 -P 123456 -t "/test/1" -m "hello" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --tls-version tlsv1.2
           

可以看到訂閱的地方能收到hello的消息

如果是使用MQTT.fx工具測試,在SSL/TLS中選擇CA certificate file ,選擇ca.crt檔案

TLS單向認證下的多個broker橋接

在server.mosquitto1.vm機器上配置

/etc/mosquitto/mosquitto.conf

,配置如下的内容:

connection bridge1
cleansession true
address server.mosquitto2.vm:8883
topic # both 0
bridge_cafile /etc/mosquitto/certs/ca.crt
remote_username admin
remote_password 123456

connection bridge2
cleansession true
address server.mosquitto3.vm:8883
topic # both 0
bridge_cafile /etc/mosquitto/certs/ca.crt
remote_username admin
remote_password 123456

           
注意cleansession的設定,如果設定為true,那麼在橋接斷開的時候,遠端代理上訂閱和主題會被清除,如果設定為false則不會清除。

配置玩之後重新開機虛拟機1上的mosquitto

測試的話,可以在任意兩台機器上訂閱一個主題如/test/1,然後在第三台機器上釋出一個消息到這個主題

在虛拟機1和虛拟機2上訂閱

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt"  --tls-version tlsv1.2

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto2.vm --cafile "/etc/mosquitto/certs/ca.crt"  --tls-version tlsv1.2
           

在虛拟機3上釋出:

mosquitto_pub -u yuanpan1 -P 123456 -t "/test/1" -m "單向TLS測試" -p 8883 -h server.mosquitto3.vm --cafile "/etc/mosquitto/certs/ca.crt" --tls-version tlsv1.2
           

在虛拟機1和2上都可以看到訂閱的消息:單向TLS測試

TLS雙向認證

單向認證和雙向認證的差別在于

require_certificate

這個配置項
如果是一路走過來的,那麼可以先将上面講到的的橋接部分的配置在虛拟機1上先注釋掉,再往下看。

修改配置

vi /etc/mosquitto/mosquitto.conf

# 修改如下配置
port 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.mosquitto1.vm/server.crt
keyfile /etc/mosquitto/certs/server.mosquitto1.vm/server.key
require_certificate true
tls_version tlsv1.2
use_identity_as_username true
           

注意

use_identity_as_username

這個配置項,如果這個配置成了

true

,那麼在認證的時候,會将用戶端證書中的

Common Name

作為使用者名來校驗,當然,這個配置項是可以配置成

false

的。

測試

下面開始在第一台虛拟機上測試,先訂閱一個

/test/1

的主題

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto1.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto1.vm/client.key" --tls-version tlsv1.2
           

再向這個主題釋出一個消息

mosquitto_pub -u yuanpan1 -P 123456 -t "/test/1" -m "雙向TLS測試" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto1.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto1.vm/client.key" --tls-version tlsv1.2
           

可以看到訂閱的地方能收到雙向TLS測試的消息

如果是使用MQTT.fx工具測試,在SSL/TLS中選擇Self signed certificates。

在CA File中選擇ca.crt檔案

在Client Certificate File中選擇client.crt檔案

在Client Key File中選擇client.key檔案

在Client Key Password中填寫生成用戶端證書時候的密碼

勾選PEM Formatted

TLS雙向認證下的多個broker橋接

在server.mosquitto1.vm機器上配置

/etc/mosquitto/mosquitto.conf

,配置如下的内容:

connection bridge1
cleansession true
address server.mosquitto2.vm:8883
topic # both 0
bridge_cafile /etc/mosquitto/certs/ca.crt
remote_username admin
remote_password 123456

connection bridge2
cleansession true
address server.mosquitto3.vm:8883
topic # both 0
bridge_cafile /etc/mosquitto/certs/ca.crt
remote_username admin
remote_password 123456

           

測試的話,可以在任意兩台機器上訂閱一個主題如/test/1,然後在第三台機器上釋出一個消息到這個主題

在虛拟機1和虛拟機2上訂閱

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto1.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto1.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto1.vm/client.key" --tls-version tlsv1.2

mosquitto_sub -u yuanpan1 -P 123456 -t "/test/1" -p 8883 -h server.mosquitto2.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto2.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto2.vm/client.key" --tls-version tlsv1.2
           

在虛拟機3上釋出:

mosquitto_pub -u yuanpan1 -P 123456 -t "/test/1" -m "雙向TLS測試" -p 8883 -h server.mosquitto3.vm --cafile "/etc/mosquitto/certs/ca.crt" --cert "/etc/mosquitto/certs/client.mosquitto3.vm/client.crt" --key "/etc/mosquitto/certs/client.mosquitto3.vm/client.key" --tls-version tlsv1.2
           

在虛拟機1和2上都可以看到訂閱的消息:雙向TLS測試

繼續閱讀