最近物联网很热,有个朋友的小项目让我帮忙弄个环境。就用docker搭建mosquitto,并通过MongoDB鉴权。记录一下步骤:
- 寻找合适的镜像
在github找到了一个项目: docker-mosquitto-mongo-auth
dockerfile文件内容贴一下:
- 寻找合适的镜像
FROM alpine:3.6
EXPOSE 1883
EXPOSE 9883
#VOLUME ["/var/lib/mosquitto", "/etc/mosquitto", "/etc/mosquitto.d"]
VOLUME ["/mosquitto/config", "/mosquitto/data", "/mosquitto/log"]
RUN addgroup -S mosquitto && \
adduser -S -H -h /var/empty -s /sbin/nologin -D -G mosquitto mosquitto
ENV PATH=/usr/local/bin:/usr/local/sbin:$PATH
ENV MOSQUITTO_VERSION=v1.4.14
ENV MONGOC_VERSION=9982861dac67bae659ce8a3370b18c3a44f764fc
ENV AUTHPLUG_VERSION=b74a79a6767b56c773e21e9c4cf12b392c29e8e2
COPY run.sh /
COPY libressl.patch /
RUN buildDeps='git build-base libressl-dev libwebsockets-dev c-ares-dev util-linux-dev curl-dev libxslt docbook-xsl automake autoconf libtool'; \
chmod +x /run.sh && \
mkdir -p /mosquitto/data && \
touch /mosquitto/data/.keep && \
apk update && \
apk add $buildDeps libwebsockets libuuid c-ares libressl curl ca-certificates && \
git clone https://github.com/mongodb/mongo-c-driver.git && \
cd mongo-c-driver && \
git checkout ${MONGOC_VERSION} && \
sh autogen.sh --with-libbson=bundled && \
make && \
make install && \
cd / && \
git clone https://github.com/eclipse/mosquitto.git mosquitto_src && \
cd mosquitto_src && \
git checkout ${MOSQUITTO_VERSION} -b ${MOSQUITTO_VERSION} && \
sed -i -e "s|(INSTALL) -s|(INSTALL)|g" -e 's|--strip-program=${CROSS_COMPILE}${STRIP}||' */Makefile */*/Makefile && \
sed -i "s@/usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl@/usr/share/xml/docbook/xsl-stylesheets-1.79.1/manpages/docbook.xsl@" man/manpage.xsl && \
## musl c lib do not support libanl
sed -i 's/ -lanl//' config.mk && \
patch -p1 < /libressl.patch && \
# wo WITH_MEMORY_TRACKING=no, mosquitto segfault after receiving first message
# libressl does not suppor PSK
make WITH_MEMORY_TRACKING=no WITH_SRV=yes WITH_WEBSOCKETS=yes WITH_TLS_PSK=no && \
make install && \
git clone git://github.com/jpmens/mosquitto-auth-plug.git && \
cd mosquitto-auth-plug && \
git checkout ${AUTHPLUG_VERSION} && \
cp config.mk.in config.mk && \
sed -i "s/BACKEND_MONGO ?= no/BACKEND_MONGO ?= yes/" config.mk && \
sed -i "s/BACKEND_FILES ?= no/BACKEND_FILES ?= yes/" config.mk && \
sed -i "s/BACKEND_MYSQL ?= yes/BACKEND_MYSQL ?= no/" config.mk && \
sed -i "s/MOSQUITTO_SRC =/MOSQUITTO_SRC = ..\//" config.mk && \
sed -i "s/EVP_MD_CTX_new/EVP_MD_CTX_create/g" cache.c && \
sed -i "s/EVP_MD_CTX_free/EVP_MD_CTX_destroy/g" cache.c && \
make && \
cp auth-plug.so /usr/local/lib/ && \
cp np /usr/local/bin/ && chmod +x /usr/local/bin/np && \
cd / && rm -rf mosquitto_src && rm /libressl.patch && rm -rf mongo-c-driver && \
apk del $buildDeps && rm -rf /var/cache/apk/*
ADD mosquitto.conf /mosquitto/config/mosquitto.conf
ENTRYPOINT ["/run.sh"]
CMD ["mosquitto"]
- build镜像
先用git clone把项目拉下来,然后就用利用项目里面写好的Makefile进行make了,执行以下命令:
- build镜像
make image REPOSITORY=10xjzheng/mqtt-auth TAG=v1.0
- 配置
我自己配置文件修改为:
1)docker-compose.yml
- 配置
version: '2'
services:
mosquitto:
image: 10xjzheng/mqtt-auth:v1.0
build: .
volumes:
- "./auth-plugin.conf:/mosquitto/config/conf.d/auth-plugin.conf"
- "./mosquitto.conf:/mosquitto/config/mosquitto.conf"
- "./mosquitto.log:/mosquitto/log/mosquitto.log"
ports:
- "1883:1883"
- "9885:9883"
php:
image: 10xjzheng/php-mongodb-mqtt-redis:2.0
ports:
- "9005:9000" # php-fpm
restart: always
volumes:
- "./:/usr/share/nginx/html"
2)auth-plugin.conf
auth_plugin /usr/local/lib/auth-plug.so
auth_opt_backends mongo
auth_opt_mongo_uri mongodb://root:****@url:port
auth_opt_mongo_database mqtt
auth_opt_mongo_coll users
MongoDB的document组织形式:
{
"username": "user1",
"password": "PBKDF2$sha256$901$8ebTR72Pcmjl3cYq$SCVHHfqn9t6Ev9sE6RMTeF3pawvtGqTu",
"superuser": false,
"topics": {
"public/#": "r",
"client/user1/#": "rw"
}
}
更多配置参数:
Option | default | Meaning |
---|---|---|
uri | mongodb://localhost:27107 | [MongoDB connection string] (database part is ignored) |
database | mqGate | Name of the database containing users (and topiclists) |
user_coll | users | Collection for user documents |
topiclist_coll | topics | Collection for topiclist documents (optional if embedded topics are used) |
user_username_prop | username | Username property name in the user document |
user_password_prop | password | Password property name in the user document |
user_superuser_prop | superuser | Superuser property name in the user document |
user_topics_prop | topics | Name of a property on the user document containing an embedded topic list |
user_topiclist_fk_prop | topics | Property used as a foreign key to reference a topiclist document |
topiclist_key_prop | _id | Unique key in the topiclist document pointed to by user_topiclist_fk_prop |
topiclist_topics_prop | topics | Property containing topics within the topiclist document |
参见:# mosquitto-auth-plug
3) mosquitto.conf
port 1883
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /mosquitto/data/
user mosquitto
allow_anonymous false
log_dest file /mosquitto/log/mosquitto.log
log_dest stdout
log_type all
include_dir /mosquitto/config/conf.d
- php生成PBKDF2加密的密码,用于管理mosquitto鉴权:
代码如下:
- php生成PBKDF2加密的密码,用于管理mosquitto鉴权:
<?php
# Contributed by @w3hacker in https://github.com/jpmens/mosquitto-auth-plug/issues/49
define("PBKDF2_HASH_ALGORITHM", "sha256");
define("PBKDF2_ITERATIONS", 901);
define("PBKDF2_SALT_BYTE_SIZE", 12);
define("PBKDF2_HASH_BYTE_SIZE", 24);
define("SEPARATOR", "$");
define("TAG", "PBKDF2");
function create_hash($password) {
$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTE_SIZE, MCRYPT_DEV_URANDOM));
return TAG . SEPARATOR . PBKDF2_HASH_ALGORITHM . SEPARATOR . PBKDF2_ITERATIONS . SEPARATOR . $salt . SEPARATOR .
base64_encode(pbkdf2(
PBKDF2_HASH_ALGORITHM,
$password,
$salt,
PBKDF2_ITERATIONS,
PBKDF2_HASH_BYTE_SIZE,
true
));
}
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false) {
$algorithm = strtolower($algorithm);
if(!in_array($algorithm, hash_algos(), true))
trigger_error('PBKDF2 ERROR: Invalid hash algorithm.', E_USER_ERROR);
if($count <= 0 || $key_length <= 0)
trigger_error('PBKDF2 ERROR: Invalid parameters.', E_USER_ERROR);
if (function_exists("hash_pbkdf2")) {
// The output length is in NIBBLES (4-bits) if $raw_output is false!
if (!$raw_output) {
$key_length = $key_length * 2;
}
return hash_pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output);
}
$hash_length = strlen(hash($algorithm, "", true));
$block_count = ceil($key_length / $hash_length);
$output = "";
for($i = 1; $i <= $block_count; $i++) {
// $i encoded as 4 bytes, big endian.
$last = $salt . pack("N", $i);
// first iteration
$last = $xorsum = hash_hmac($algorithm, $last, $password, true);
// perform the other $count - 1 iterations
for ($j = 1; $j < $count; $j++) {
$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
}
$output .= $xorsum;
}
if($raw_output)
return substr($output, 0, $key_length);
else
return bin2hex(substr($output, 0, $key_length));
}
?>
来源:## mosquitto-auth-plug/contrib/genhash.php
网友评论