1. 程式人生 > >轉mosquitto auth plugin 編譯配置

轉mosquitto auth plugin 編譯配置

配置使用 mysql 作為 be (back end)

  • 使用config.mk 配置編譯引數
    cp config.mk.in config.mk
  • 修改

安裝 mysql

sudo apt-get install mysql-server libmysqlclient-dev

# Select your backends from this list
BACKEND_CDB ?= no
BACKEND_MYSQL ?= yes   # 使用 mysql 
BACKEND_SQLITE ?= no
BACKEND_REDIS ?= no
BACKEND_POSTGRES ?= no
BACKEND_LDAP ?= no
BACKEND_HTTP ?= no
BACKEND_JWT ?= no
BACKEND_MONGO ?= no
BACKEND_FILES ?= no

# Specify the path to the Mosquitto sources here
# MOSQUITTO_SRC = /usr/local/Cellar/mosquitto/1.4.12 
MOSQUITTO_SRC =/mnt/g/cjc/workspace/mqtt/mosquitto   # 指定mosquitto原始碼 # Specify the path the OpenSSL here OPENSSLDIR = /usr # Specify optional/additional linker/compiler flags here # On macOS, add # CFG_LDFLAGS = -undefined dynamic_lookup # as described in https://github.com/eclipse/mosquitto/issues/244 # # CFG_LDFLAGS = -undefined dynamic_lookup -L/usr/local/Cellar/openssl/1.0.2l/lib # CFG_CFLAGS = -I/usr/local/Cellar/openssl/1.0.2l/include -I/usr/local/Cellar/mosquitto/1.4.12/include CFG_LDFLAGS = CFG_CFLAGS = 

編譯plugin

make
得到 auth-plug.so

編譯 mosquitto

修改 mosquitto-mysql.conf
參考 mosquitto-auth-plug/examples/mosquitto-mysql.conf 中的 外掛附加選項,增加到 mosquitto-mysql.conf 中

# 外掛so路徑
auth_plugin /mnt/g/cjc/workspace/mqtt/mosquitto-auth-plug/auth-plug.so  
auth_opt_backends mysql
auth_opt_cdbname pwdb.cdb
auth_opt_host localhost
auth_opt_port 3306
auth_opt_dbname mqtttest
auth_opt_user root
auth_opt_pass root
# mysql 查詢語句約定
auth_opt_userquery SELECT pw FROM users WHERE username = '%s'
auth_opt_superquery SELECT IFNULL(COUNT(*), 0) FROM users WHERE username = '%s' AND super = 1 auth_opt_aclquery SELECT topic FROM acls WHERE username = '%s' # Usernames with this fnmatch(3) (a.k.a glob(3)) pattern are exempt from the # module's ACL checking AUTH_OPT_SUPERUSERS s* 

mysql 建表

參考 mosquitto-auth-plug/examples/mysql.sql
測試,直接跑 mysql.sql 建測試表
mysql -uroot -p -Dmqtttest<./../mosquitto-auth-plug/examples/mysql.sql

mysql> show tables;
+--------------------+
| Tables_in_mqtttest |
+--------------------+
| acls               |
| users              |
+--------------------+

mysql> desc users;                                                 
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | username | varchar(25) | NO | UNI | NULL | | | pw | varchar(128) | NO | | NULL | | | super | int(1) | NO | | 0 | | +----------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) mysql> desc acls; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | username | varchar(25) | NO | MUL | NULL | | | topic | varchar(256) | NO | | NULL | | | rw | int(1) | NO | | 1 | | +----------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) 

客戶端依賴動態庫

把 ./lib/libmosquitto.so.1 加入 /usr/lib 下
sudo cp lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1

執行測試

  • 服務端
    ./src/mosquitto -c mosquitto.conf

1500565002: |-- *** auth-plug: startup
1500565002: |-- ** Configured order: mysql
1500565002: |-- }}}} MYSQL

  • 客戶端

it MUST return a single column only with the PBKDF2 password hash. A single '%s' in the query string is replaced by the username attempting to access the broker.

未往mysql正確插入資料情況(即未授權),連線將被backend拒絕
Connection Refused: not authorised.
Error: The connection was refused.

密碼使用 PBKDF2 儲存
A user's password is stored as a PBKDF2 hash in the back-end. An example "password" is a string with five pieces in it, delimited by $
, inspired by this.

Note that the salt
by default will be taken as-is (thus it will not be base64 decoded before the validation). In case your own implementation uses the raw bytes when hashing the password and base64 is only used for display purpose, compile this project with the -DRAW_SALT
flag (you could add this in the config.mk
file to CFG_CFLAGS
).

  • pw 格式:


      image.png
  • 使用auth plugin 提供的 np 工具生成密碼
    np 工具使用加密演算法,明文把組合隨機生成的salt,用 sha256作為hash函式, 迭代次數901 次的 PBKDF2 生成了 hashed password, 返回拼接格式的字串
    mysql資料庫pw儲存拼接後的密碼, auth-plugin 從根據 username從表裡查詢得到拼接後的密碼(包括了 salt,interations, hashfunction),並提取出salt,用使用者 password 計算 hashed password 進行比對鑑權。
$ ./np
Enter password:12345
Re-enter same password:12345
PBKDF2$sha256$901$IV/rAqUxT519iO+K$4pe0utPHFZnKpJTASyP0Ann5Nwx5yqZY
  • 往 mysql mqtttest 表中新增 user, pw="PBKDF2$sha256$901$IV/rAqUxT519iO+K$4pe0utPHFZnKpJTASyP0Ann5Nwx5yqZY"
    update users set pw="PBKDF2$sha256$901$ubLO1LjWJ0+Gpedp$lpPza0X4dDntdrc5qTqyuRVtIvpLx1N2" where id=7;

  • 新增 acl 記錄
    insert into acls values(13,'cjc','cjc/rw',2);
    | 13 | cjc | cjc/rw | 2 |

  • 測試 訂閱
    ./mosquitto_sub -t "cjc/rw" -u "cjc" -P "12345"

  • 測試釋出
    ./mosquitto_pub -t "cjc/rw" -m "hello" -u "cjc" -P "12345"

  • 服務端輸出

1500569102: Sending CONNACK to mosqsub|1240-ra1z (0, 0)
1500569102: Received SUBSCRIBE from mosqsub|1240-ra1z
1500569102: cjc/rw (QoS 0)
1500569102: Sending SUBACK to mosqsub|1240-ra1z
1500569112: |-- mosquitto_auth_unpwd_check(cjc)
1500569112: |-- ** checking backend mysql
1500569112: |-- getuser(cjc) AUTHENTICATED=1 by mysql
1500569112: Sending CONNACK to mosqpub|1241-ra1z (0, 0)
1500569112: |-- mosquitto_auth_acl_check(..., mosqpub|1241-ra1z, cjc, cjc/rw, MOSQ_ACL_WRITE)
1500569112: |-- mysql: topic_matches(cjc/rw, cjc/rw) == 1
1500569112: |-- aclcheck(cjc, cjc/rw, 2) trying to acl with mysql
1500569112: |-- aclcheck(cjc, cjc/rw, 2) AUTHORIZED=1 by mysql
1500569112: |-- Cached [1C2BBC255AB58D79DE677B3078E31D74C900A74D] for (mosqpub|1241-ra1z,cjc,2)
1500569112: Received PUBLISH from mosqpub|1241-ra1z (d0, q0, r0, m0, 'cjc/rw', ... (5 bytes))
1500569112: |-- mosquitto_auth_acl_check(..., mosqsub|1240-ra1z, cjc, cjc/rw, MOSQ_ACL_READ)
1500569112: |-- mysql: topic_matches(cjc/rw, cjc/rw) == 1
1500569112: |-- aclcheck(cjc, cjc/rw, 1) trying to acl with mysql
1500569112: |-- aclcheck(cjc, cjc/rw, 1) AUTHORIZED=1 by mysql
1500569112: |-- Cached [AD78C641352E6B2001205F385A3D612C609D6739] for (mosqsub|1240-ra1z,cjc,1)
1500569112: Sending PUBLISH to mosqsub|1240-ra1z (d0, q0, r0, m0, 'cjc/rw', ... (5 bytes))

np 密碼生成演算法與實現

https://github.com/manolodd/pbkdf2-mosquitto
https://github.com/jpmens/mosquitto-auth-plug/tree/master/contrib/python3
https://github.com/jpmens/mosquitto-auth-plug/issues/44

  • Create a salt (byte array with random chars)
  • Convert the salt to Base64
  • cast this base64 string as a byte array.
  • Take the password
  • Do the hashing with the password and the converted -> casted salt




連結:https://www.jianshu.com/p/df5ce786781b