gen_conf to improve the configuration of emqttd broker
This commit is contained in:
parent
ca44fd4031
commit
03d6710b60
|
@ -0,0 +1,28 @@
|
|||
%%--------------------------------------------------------------------
|
||||
%%
|
||||
%% [ACL](https://github.com/emqtt/emqttd/wiki/ACL)
|
||||
%%
|
||||
%% -type who() :: all | binary() |
|
||||
%% {ipaddr, esockd_access:cidr()} |
|
||||
%% {client, binary()} |
|
||||
%% {user, binary()}.
|
||||
%%
|
||||
%% -type access() :: subscribe | publish | pubsub.
|
||||
%%
|
||||
%% -type topic() :: binary().
|
||||
%%
|
||||
%% -type rule() :: {allow, all} |
|
||||
%% {allow, who(), access(), list(topic())} |
|
||||
%% {deny, all} |
|
||||
%% {deny, who(), access(), list(topic())}.
|
||||
%%
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
|
||||
|
||||
{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
|
||||
|
||||
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
|
||||
|
||||
{allow, all}.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
testclientid0
|
||||
testclientid1 127.0.0.1
|
||||
testclientid2 192.168.0.1/24
|
|
@ -0,0 +1,250 @@
|
|||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Authentication
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% Anonymous: Allow all
|
||||
{auth, anonymous, []}.
|
||||
|
||||
%% Authentication with username, password
|
||||
%% Passwd Hash: plain | md5 | sha | sha256
|
||||
{auth, username, [{passwd, "etc/passwd.conf"}, {passwd_hash, plain}]}.
|
||||
|
||||
%% Authentication with clientId
|
||||
{auth, clientid, [{clients, "etc/client.config"}, {password, no}]}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% ACL
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
{acl, anonymous, []}.
|
||||
|
||||
{acl, internal, [{config, "etc/acl.conf"}, {nomatch, allow}]}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Broker
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% System interval of publishing broker $SYS messages
|
||||
{broker_sys_interval, 60}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Retained message
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% Expired after seconds, never expired if 0
|
||||
{retained_expired_after, 0}.
|
||||
|
||||
%% Max number of retained messages
|
||||
{retained_max_message_num, 100000}.
|
||||
|
||||
%% Max Payload Size of retained message
|
||||
{retained_max_playload_size, 65536}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% MQTT Protocol
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% Max ClientId Length Allowed.
|
||||
{mqtt_max_clientid_len, 512}.
|
||||
|
||||
%% Max Packet Size Allowed, 64K by default.
|
||||
{mqtt_max_packet_size, 65536}.
|
||||
|
||||
%% Socket Idle Timeout.
|
||||
{mqtt_client_idle_timeout, 30}. % Seconds
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% MQTT Session
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% Max number of QoS 1 and 2 messages that can be “inflight” at one time.
|
||||
%% 0 means no limit
|
||||
{session_max_inflight, 100}.
|
||||
|
||||
%% Retry interval for redelivering QoS1/2 messages.
|
||||
{session_unack_retry_interval, 60}.
|
||||
|
||||
%% Awaiting PUBREL Timeout
|
||||
{session_await_rel_timeout, 20}.
|
||||
|
||||
%% Max Packets that Awaiting PUBREL, 0 means no limit
|
||||
{session_max_awaiting_rel, 0}.
|
||||
|
||||
%% Statistics Collection Interval(seconds)
|
||||
{session_collect_interval, 0}.
|
||||
|
||||
%% Expired after 2 day (unit: minute)
|
||||
{session_expired_after, 2880}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Queue
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% Type: simple | priority
|
||||
{queue_type, simple}.
|
||||
|
||||
%% Topic Priority: 0~255, Default is 0
|
||||
%% {queue_priority, [{"topic/1", 10}, {"topic/2", 8}]}.
|
||||
|
||||
%% Max queue length. Enqueued messages when persistent client disconnected,
|
||||
%% or inflight window is full.
|
||||
{queue_max_length, infinity}.
|
||||
|
||||
%% Low-water mark of queued messages
|
||||
{queue_low_watermark, 0.2}.
|
||||
|
||||
%% High-water mark of queued messages
|
||||
{queue_high_watermark, 0.6}.
|
||||
|
||||
%% Queue Qos0 messages?
|
||||
{queue_qos0, true}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Listeners
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% Plain MQTT
|
||||
{listener, mqtt, 1883, [
|
||||
%% Size of acceptor pool
|
||||
{acceptors, 16},
|
||||
|
||||
%% Maximum number of concurrent clients
|
||||
{max_clients, 512},
|
||||
|
||||
%% Socket Access Control
|
||||
{access, [{allow, all}]},
|
||||
|
||||
%% Connection Options
|
||||
{connopts, [
|
||||
%% Rate Limit. Format is 'burst, rate', Unit is KB/Sec
|
||||
%% {rate_limit, "100,10"} %% 100K burst, 10K rate
|
||||
]},
|
||||
|
||||
%% Socket Options
|
||||
{sockopts, [
|
||||
%Set buffer if hight thoughtput
|
||||
%{recbuf, 4096},
|
||||
%{sndbuf, 4096},
|
||||
%{buffer, 4096},
|
||||
%{nodelay, true},
|
||||
{backlog, 1024}
|
||||
]}
|
||||
]}.
|
||||
|
||||
%% MQTT SSL
|
||||
{listener, mqtts, 8883, [
|
||||
%% Size of acceptor pool
|
||||
{acceptors, 4},
|
||||
|
||||
%% Maximum number of concurrent clients
|
||||
{max_clients, 512},
|
||||
|
||||
%% Socket Access Control
|
||||
{access, [{allow, all}]},
|
||||
|
||||
%% SSL certificate and key files
|
||||
{ssl, [{certfile, "etc/ssl/ssl.crt"},
|
||||
{keyfile, "etc/ssl/ssl.key"}]},
|
||||
|
||||
%% Socket Options
|
||||
{sockopts, [
|
||||
{backlog, 1024}
|
||||
%{buffer, 4096},
|
||||
]}
|
||||
]}.
|
||||
|
||||
%% HTTP and WebSocket Listener
|
||||
{listener, http, 8083, [
|
||||
%% Size of acceptor pool
|
||||
{acceptors, 4},
|
||||
|
||||
%% Maximum number of concurrent clients
|
||||
{max_clients, 64},
|
||||
|
||||
%% Socket Access Control
|
||||
{access, [{allow, all}]},
|
||||
|
||||
%% Socket Options
|
||||
{sockopts, [
|
||||
{backlog, 1024}
|
||||
%{buffer, 4096},
|
||||
]}
|
||||
]}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% PubSub
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% PubSub and Router. Default should be scheduler numbers.
|
||||
{pubsub_pool_size, 8}.
|
||||
|
||||
%% Route aging time(seconds)
|
||||
{pubsub_routing_age, 5}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Bridge
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% TODO: Bridge Queue Size
|
||||
{bridge_max_queue_len, 10000}.
|
||||
|
||||
%% Ping Interval of bridge node
|
||||
{bridge_ping_down_interval, 1} %seconds
|
||||
|
||||
%%-------------------------------------------------------------------
|
||||
%% Plugins
|
||||
%%-------------------------------------------------------------------
|
||||
|
||||
%% Plugins Dir
|
||||
{plugins_dir, "./plugins"}.
|
||||
|
||||
%% File to store loaded plugin names.
|
||||
{plugins_loaded_file, "./data/loaded_plugins"}.
|
||||
|
||||
%%-------------------------------------------------------------------
|
||||
%% Modules
|
||||
%%-------------------------------------------------------------------
|
||||
|
||||
%% Client presence management module. Publish presence messages when client connected or disconnected
|
||||
{module, presence, [{qos, 0}]}.
|
||||
|
||||
%% Subscribe topics automatically when client connected
|
||||
{module, subscription, [{"$queue/clients/$c", 1}, backend]}.
|
||||
|
||||
%% [Rewrite](https://github.com/emqtt/emqttd/wiki/Rewrite)
|
||||
{module, rewrite, [
|
||||
|
||||
%{topic, "x/#", [
|
||||
% {rewrite, "^x/y/(.+)$", "z/y/$1"},
|
||||
% {rewrite, "^x/(.+)$", "y/$1"}
|
||||
%]},
|
||||
|
||||
%{topic, "y/+/z/#", [
|
||||
% {rewrite, "^y/(.+)/z/(.+)$", "y/z/$2"}
|
||||
%]}
|
||||
|
||||
]}.
|
||||
|
||||
%%-------------------------------------------------------------------
|
||||
%% Erlang System Monitor
|
||||
%%-------------------------------------------------------------------
|
||||
|
||||
%% Long GC, don't monitor in production mode for:
|
||||
%% https://github.com/erlang/otp/blob/feb45017da36be78d4c5784d758ede619fa7bfd3/erts/emulator/beam/erl_gc.c#L421
|
||||
|
||||
{sysmon_long_gc, false}.
|
||||
|
||||
%% Long Schedule(ms)
|
||||
{sysmon_long_schedule, 240}.
|
||||
|
||||
%% 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM.
|
||||
%% 8 * 1024 * 1024
|
||||
{sysmon_large_heap, 8388608}.
|
||||
|
||||
%% Busy Port
|
||||
{sysmon_busy_port, false}.
|
||||
|
||||
%% Busy Dist Port
|
||||
{sysmon_busy_dist_port, true}.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
user1:passwd1
|
||||
user2:passwd2
|
323
rel/files/emqttd
323
rel/files/emqttd
|
@ -1,323 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- tab-width:4;indent-tabs-mode:nil -*-
|
||||
# ex: ts=4 sw=4 et
|
||||
|
||||
# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is.
|
||||
if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then
|
||||
POSIX_SHELL="true"
|
||||
export POSIX_SHELL
|
||||
# To support 'whoami' add /usr/ucb to path
|
||||
PATH=/usr/ucb:$PATH
|
||||
export PATH
|
||||
exec /usr/bin/ksh $0 "$@"
|
||||
fi
|
||||
unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well
|
||||
|
||||
RUNNER_SCRIPT_DIR={{runner_script_dir}}
|
||||
RUNNER_SCRIPT=${0##*/}
|
||||
|
||||
RUNNER_BASE_DIR={{runner_base_dir}}
|
||||
RUNNER_ETC_DIR={{runner_etc_dir}}
|
||||
RUNNER_LIB_DIR={{platform_lib_dir}}
|
||||
RUNNER_LOG_DIR={{runner_log_dir}}
|
||||
RUNNER_DATA_DIR=$RUNNER_BASE_DIR/data
|
||||
RUNNER_PLUGINS_DIR=$RUNNER_BASE_DIR/plugins
|
||||
|
||||
# Note the trailing slash on $PIPE_DIR/
|
||||
PIPE_DIR={{pipe_dir}}
|
||||
RUNNER_USER={{runner_user}}
|
||||
PLATFORM_DATA_DIR={{platform_data_dir}}
|
||||
SSL_DIST_CONFIG=$PLATFORM_DATA_DIR/ssl_distribution.args_file
|
||||
RIAK_VERSION="git"
|
||||
|
||||
WHOAMI=$(whoami)
|
||||
|
||||
# Make sure this script is running as the appropriate user
|
||||
if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then
|
||||
type sudo > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Attempting to restart script through sudo -H -u $RUNNER_USER" >&2
|
||||
exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@
|
||||
fi
|
||||
|
||||
# Warn the user if ulimit -n is less than 1024
|
||||
ULIMIT_F=`ulimit -n`
|
||||
if [ "$ULIMIT_F" -lt 1024 ]; then
|
||||
echo "!!!!"
|
||||
echo "!!!! WARNING: ulimit -n is ${ULIMIT_F}; 1024 is the recommended minimum."
|
||||
echo "!!!!"
|
||||
fi
|
||||
|
||||
# Make sure CWD is set to runner base dir
|
||||
cd $RUNNER_BASE_DIR
|
||||
|
||||
# Make sure log directory exists
|
||||
mkdir -p $RUNNER_LOG_DIR
|
||||
|
||||
# Make sure the data directory exists
|
||||
mkdir -p $PLATFORM_DATA_DIR
|
||||
|
||||
# Warn the user if they don't have write permissions on the log dir
|
||||
if [ ! -w $RUNNER_LOG_DIR ]; then
|
||||
echo "!!!!"
|
||||
echo "!!!! WARNING: $RUNNER_LOG_DIR not writable; logs and crash dumps unavailable."
|
||||
echo "!!!!"
|
||||
fi
|
||||
|
||||
# Extract the target node name from node.args
|
||||
NAME_ARG=`egrep '^\-s?name' $RUNNER_ETC_DIR/vm.args`
|
||||
if [ -z "$NAME_ARG" ]; then
|
||||
echo "vm.args needs to have either -name or -sname parameter."
|
||||
exit 1
|
||||
fi
|
||||
NODE_NAME=${NAME_ARG##* }
|
||||
|
||||
# Extract the target cookie
|
||||
COOKIE_ARG=`grep '^\-setcookie' $RUNNER_ETC_DIR/vm.args`
|
||||
if [ -z "$COOKIE_ARG" ]; then
|
||||
echo "vm.args needs to have a -setcookie parameter."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Identify the script name
|
||||
SCRIPT=`basename $0`
|
||||
|
||||
# Parse out release and erts info
|
||||
START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
|
||||
ERTS_VSN=${START_ERL% *}
|
||||
APP_VSN=${START_ERL#* }
|
||||
|
||||
# Add ERTS bin dir to our path
|
||||
ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
|
||||
|
||||
# Setup command to control the node
|
||||
NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
|
||||
NODETOOL_LITE="$ERTS_PATH/escript $ERTS_PATH/nodetool"
|
||||
|
||||
# Common functions
|
||||
|
||||
# Ping node without allowing nodetool to take stdin
|
||||
ping_node() {
|
||||
$NODETOOL ping < /dev/null
|
||||
}
|
||||
|
||||
# Set the PID global variable, return 1 on error
|
||||
get_pid() {
|
||||
PID=`$NODETOOL getpid < /dev/null`
|
||||
ES=$?
|
||||
if [ "$ES" -ne 0 ]; then
|
||||
echo "Node is not running!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# don't allow empty or init pid's
|
||||
if [ -z $PID ] || [ "$PID" -le 1 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Scrape out SSL distribution config info from vm.args into $SSL_DIST_CONFIG
|
||||
rm -f $SSL_DIST_CONFIG
|
||||
sed -n '/Begin SSL distribution items/,/End SSL distribution items/p' \
|
||||
$RUNNER_ETC_DIR/vm.args > $SSL_DIST_CONFIG
|
||||
|
||||
# Check the first argument for instructions
|
||||
case "$1" in
|
||||
start)
|
||||
# Make sure there is not already a node running
|
||||
RES=`ping_node`
|
||||
if [ "$RES" = "pong" ]; then
|
||||
echo "Node is already running!"
|
||||
exit 1
|
||||
fi
|
||||
# Sanity check the emqttd.config file
|
||||
RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/emqttd.config`
|
||||
if [ $? != 0 ]; then
|
||||
echo "Error reading $RUNNER_ETC_DIR/emqttd.config"
|
||||
echo $RES
|
||||
exit 1
|
||||
fi
|
||||
HEART_COMMAND="$RUNNER_SCRIPT_DIR/$SCRIPT start"
|
||||
export HEART_COMMAND
|
||||
mkdir -p $PIPE_DIR
|
||||
$ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR \
|
||||
"exec $RUNNER_SCRIPT_DIR/$SCRIPT console" 2>&1
|
||||
|
||||
# Wait for the node to come up. We can't just ping it because
|
||||
# distributed erlang comes up for a second before emqttd crashes
|
||||
# (eg. in the case of an unwriteable disk). Once the node comes
|
||||
# up we check for the node watcher process. If that's running
|
||||
# then we assume things are good enough. This will at least let
|
||||
# the user know when emqttd is crashing right after startup.
|
||||
WAIT=${WAIT_FOR_ERLANG:-15}
|
||||
while [ $WAIT -gt 0 ]; do
|
||||
WAIT=`expr $WAIT - 1`
|
||||
sleep 1
|
||||
RES=`ping_node`
|
||||
if [ "$?" -ne 0 ]; then
|
||||
continue
|
||||
fi
|
||||
echo "emqttd is started successfully!"
|
||||
exit 0
|
||||
done
|
||||
echo "emqttd failed to start within ${WAIT_FOR_ERLANG:-15} seconds,"
|
||||
echo "see the output of 'emqttd console' for more information."
|
||||
echo "If you want to wait longer, set the environment variable"
|
||||
echo "WAIT_FOR_ERLANG to the number of seconds to wait."
|
||||
exit 1
|
||||
;;
|
||||
|
||||
stop)
|
||||
UNAME_S=`uname -s`
|
||||
case $UNAME_S in
|
||||
Darwin)
|
||||
# Make sure we explicitly set this because iTerm.app doesn't for
|
||||
# some reason.
|
||||
COMMAND_MODE=unix2003
|
||||
esac
|
||||
|
||||
# Get the PID from nodetool
|
||||
get_pid
|
||||
GPR=$?
|
||||
if [ "$GPR" -ne 0 ] || [ -z $PID ]; then
|
||||
exit $GPR
|
||||
fi
|
||||
|
||||
# Tell nodetool to initiate a stop
|
||||
$NODETOOL stop
|
||||
ES=$?
|
||||
if [ "$ES" -ne 0 ]; then
|
||||
exit $ES
|
||||
fi
|
||||
|
||||
# Wait for the node to completely stop...
|
||||
while `kill -s 0 $PID 2>/dev/null`;
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
;;
|
||||
|
||||
restart)
|
||||
## Restart the VM without exiting the process
|
||||
$NODETOOL restart
|
||||
ES=$?
|
||||
if [ "$ES" -ne 0 ]; then
|
||||
exit $ES
|
||||
fi
|
||||
;;
|
||||
|
||||
reboot)
|
||||
## Restart the VM completely (uses heart to restart it)
|
||||
$NODETOOL reboot
|
||||
ES=$?
|
||||
if [ "$ES" -ne 0 ]; then
|
||||
exit $ES
|
||||
fi
|
||||
;;
|
||||
|
||||
ping)
|
||||
## See if the VM is alive
|
||||
ping_node
|
||||
ES=$?
|
||||
if [ "$ES" -ne 0 ]; then
|
||||
exit $ES
|
||||
fi
|
||||
;;
|
||||
|
||||
attach)
|
||||
if [ "$2" = "-f" ]; then
|
||||
echo "Forcing connection..."
|
||||
else
|
||||
# Make sure a node is running
|
||||
RES=`ping_node`
|
||||
ES=$?
|
||||
if [ "$ES" -ne 0 ]; then
|
||||
echo "Node is not running!"
|
||||
exit $ES
|
||||
fi
|
||||
fi
|
||||
|
||||
shift
|
||||
exec $ERTS_PATH/to_erl $PIPE_DIR
|
||||
;;
|
||||
|
||||
console)
|
||||
RES=`ping_node`
|
||||
if [ "$RES" = "pong" ]; then
|
||||
echo "Node is already running - use '$SCRIPT attach' instead"
|
||||
exit 1
|
||||
fi
|
||||
# Sanity check the emqttd.config file
|
||||
RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/emqttd.config`
|
||||
if [ $? != 0 ]; then
|
||||
echo "Error reading $RUNNER_ETC_DIR/emqttd.config"
|
||||
echo $RES
|
||||
exit 1
|
||||
fi
|
||||
# Setup beam-required vars
|
||||
ROOTDIR=$RUNNER_BASE_DIR
|
||||
ERL_LIBS=$ROOTDIR/plugins
|
||||
BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
|
||||
EMU=beam
|
||||
PROGNAME=`echo $0 | sed 's/.*\///'`
|
||||
# Setup Mnesia Dir
|
||||
MNESIA_DIR="$RUNNER_DATA_DIR/mnesia/$NODE_NAME"
|
||||
CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$SCRIPT \
|
||||
-embedded -config $RUNNER_ETC_DIR/emqttd.config \
|
||||
-pa $RUNNER_LIB_DIR/basho-patches \
|
||||
-mnesia dir "\"${MNESIA_DIR}\"" \
|
||||
-args_file $RUNNER_ETC_DIR/vm.args -- ${1+"$@"}"
|
||||
export EMU
|
||||
export ROOTDIR
|
||||
export ERL_LIBS
|
||||
export BINDIR
|
||||
export PROGNAME
|
||||
|
||||
# Dump environment info for logging purposes
|
||||
echo "Exec: $CMD"
|
||||
echo "Root: $ROOTDIR"
|
||||
|
||||
# Log the startup
|
||||
logger -t "$SCRIPT[$$]" "Starting up"
|
||||
|
||||
# Start the VM
|
||||
exec $CMD
|
||||
;;
|
||||
chkconfig)
|
||||
RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/emqttd.config`
|
||||
if [ $? != 0 ]; then
|
||||
echo "Error reading $RUNNER_ETC_DIR/emqttd.config"
|
||||
echo $RES
|
||||
exit 1
|
||||
fi
|
||||
echo "config is OK"
|
||||
;;
|
||||
escript)
|
||||
shift
|
||||
$ERTS_PATH/escript "$@"
|
||||
;;
|
||||
version)
|
||||
echo $RIAK_VERSION
|
||||
;;
|
||||
getpid)
|
||||
# Get the PID from nodetool
|
||||
get_pid
|
||||
ES=$?
|
||||
if [ "$ES" -ne 0 ] || [ -z $PID ]; then
|
||||
exit $ES
|
||||
fi
|
||||
echo $PID
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|attach|chkconfig|escript|version|getpid}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
|
@ -1,108 +0,0 @@
|
|||
@echo off
|
||||
@setlocal
|
||||
@setlocal enabledelayedexpansion
|
||||
|
||||
@set node_name=emqttd
|
||||
|
||||
@rem Get the absolute path to the parent directory,
|
||||
@rem which is assumed to be the node root.
|
||||
@for /F "delims=" %%I in ("%~dp0..") do @set node_root=%%~fI
|
||||
|
||||
@set releases_dir=%node_root%\releases
|
||||
@set runner_etc_dir=%node_root%\etc
|
||||
|
||||
@rem Parse ERTS version and release version from start_erl.data
|
||||
@for /F "usebackq tokens=1,2" %%I in ("%releases_dir%\start_erl.data") do @(
|
||||
@call :set_trim erts_version %%I
|
||||
@call :set_trim release_version %%J
|
||||
)
|
||||
|
||||
@set vm_args=%runner_etc_dir%\vm.args
|
||||
@set sys_config=%runner_etc_dir%\emqttd.config
|
||||
@set node_boot_script=%releases_dir%\%release_version%\%node_name%
|
||||
@set clean_boot_script=%releases_dir%\%release_version%\start_clean
|
||||
|
||||
@rem extract erlang cookie from vm.args
|
||||
@for /f "usebackq tokens=1-2" %%I in (`findstr /b \-setcookie "%vm_args%"`) do @set erlang_cookie=%%J
|
||||
|
||||
@set erts_bin=%node_root%\erts-%erts_version%\bin
|
||||
|
||||
@set service_name=%node_name%_%release_version%
|
||||
|
||||
@set erlsrv="%erts_bin%\erlsrv.exe"
|
||||
@set epmd="%erts_bin%\epmd.exe"
|
||||
@set escript="%erts_bin%\escript.exe"
|
||||
@set werl="%erts_bin%\werl.exe"
|
||||
|
||||
@if "%1"=="usage" @goto usage
|
||||
@if "%1"=="install" @goto install
|
||||
@if "%1"=="uninstall" @goto uninstall
|
||||
@if "%1"=="start" @goto start
|
||||
@if "%1"=="stop" @goto stop
|
||||
@if "%1"=="restart" @call :stop && @goto start
|
||||
@if "%1"=="console" @goto console
|
||||
@if "%1"=="query" @goto query
|
||||
@if "%1"=="attach" @goto attach
|
||||
@if "%1"=="upgrade" @goto upgrade
|
||||
@echo Unknown command: "%1"
|
||||
|
||||
:usage
|
||||
@echo Usage: %~n0 [install^|uninstall^|start^|stop^|restart^|console^|query^|attach^|upgrade]
|
||||
@goto :EOF
|
||||
|
||||
:install
|
||||
@set description=Erlang node %node_name% in %node_root%
|
||||
@set start_erl=%node_root%\bin\start_erl.cmd
|
||||
@set args= ++ %node_name% ++ %node_root%
|
||||
@%erlsrv% add %service_name% -c "%description%" -sname %node_name% -w "%node_root%" -m "%start_erl%" -args "%args%" -stopaction "init:stop()."
|
||||
@goto :EOF
|
||||
|
||||
:uninstall
|
||||
@%erlsrv% remove %service_name%
|
||||
@%epmd% -kill
|
||||
@goto :EOF
|
||||
|
||||
:start
|
||||
@%erlsrv% start %service_name%
|
||||
@goto :EOF
|
||||
|
||||
:stop
|
||||
@%erlsrv% stop %service_name%
|
||||
@goto :EOF
|
||||
|
||||
:console
|
||||
set dest_path=%~dp0
|
||||
cd /d !dest_path!..\plugins
|
||||
set current_path=%cd%
|
||||
set plugins=
|
||||
for /d %%P in (*) do (
|
||||
set "plugins=!plugins!"!current_path!\%%P\ebin" "
|
||||
)
|
||||
cd /d %node_root%
|
||||
|
||||
@start "%node_name% console" %werl% -boot "%node_boot_script%" -config "%sys_config%" -args_file "%vm_args%" -sname %node_name% -pa %plugins%
|
||||
@goto :EOF
|
||||
|
||||
:query
|
||||
@%erlsrv% list %service_name%
|
||||
@exit %ERRORLEVEL%
|
||||
@goto :EOF
|
||||
|
||||
:attach
|
||||
@for /f "usebackq" %%I in (`hostname`) do @set hostname=%%I
|
||||
start "%node_name% attach" %werl% -boot "%clean_boot_script%" -remsh %node_name%@%hostname% -sname console -setcookie %erlang_cookie%
|
||||
@goto :EOF
|
||||
|
||||
:upgrade
|
||||
@if "%2"=="" (
|
||||
@echo Missing upgrade package argument
|
||||
@echo Usage: %~n0 upgrade {package base name}
|
||||
@echo NOTE {package base name} MUST NOT include the .tar.gz suffix
|
||||
@goto :EOF
|
||||
)
|
||||
@%escript% %node_root%\bin\install_upgrade.escript %node_name% %erlang_cookie% %2
|
||||
@goto :EOF
|
||||
|
||||
:set_trim
|
||||
@set %1=%2
|
||||
@goto :EOF
|
|
@ -1,300 +0,0 @@
|
|||
% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||
%% ex: ft=erlang ts=4 sw=4 et
|
||||
[{kernel, [
|
||||
{start_timer, true},
|
||||
{start_pg2, true}
|
||||
]},
|
||||
{sasl, [
|
||||
{sasl_error_logger, {file, "emqttd_sasl.log"}}
|
||||
]},
|
||||
{ssl, [
|
||||
%{versions, ['tlsv1.2', 'tlsv1.1']}
|
||||
]},
|
||||
{lager, [
|
||||
{colored, true},
|
||||
{async_threshold, 1000},
|
||||
{error_logger_redirect, false},
|
||||
{crash_log, "log/emqttd_crash.log"},
|
||||
{handlers, [
|
||||
{lager_console_backend, info},
|
||||
%%NOTICE: Level >= error
|
||||
%%{lager_emqtt_backend, error},
|
||||
{lager_file_backend, [
|
||||
{formatter_config, [time, " ", pid, " [",severity,"] ", message, "\n"]},
|
||||
{file, "log/emqttd_info.log"},
|
||||
{level, info},
|
||||
{size, 104857600},
|
||||
{date, "$D0"},
|
||||
{count, 30}
|
||||
]},
|
||||
{lager_file_backend, [
|
||||
{formatter_config, [time, " ", pid, " [",severity,"] ", message, "\n"]},
|
||||
{file, "log/emqttd_error.log"},
|
||||
{level, error},
|
||||
{size, 104857600},
|
||||
{date, "$D0"},
|
||||
{count, 30}
|
||||
]}
|
||||
]}
|
||||
]},
|
||||
{esockd, [
|
||||
{logger, {lager, info}}
|
||||
]},
|
||||
{emqttd, [
|
||||
%% Authentication and Authorization
|
||||
{access, [
|
||||
%% Authetication. Anonymous Default
|
||||
{auth, [
|
||||
%% Authentication with username, password
|
||||
%% {username, [{test, "password"}, {"test1", "password1"}]},
|
||||
|
||||
%% Authentication with clientid
|
||||
%{clientid, [{password, no}, {file, "etc/clients.config"}]},
|
||||
|
||||
%% Authentication with LDAP
|
||||
% {ldap, [
|
||||
% {servers, ["localhost"]},
|
||||
% {port, 389},
|
||||
% {timeout, 30},
|
||||
% {user_dn, "uid=$u,ou=People,dc=example,dc=com"},
|
||||
% {ssl, fasle},
|
||||
% {sslopts, [
|
||||
% {"certfile", "ssl.crt"},
|
||||
% {"keyfile", "ssl.key"}]}
|
||||
% ]},
|
||||
|
||||
%% Allow all
|
||||
{anonymous, []}
|
||||
]},
|
||||
%% ACL config
|
||||
{acl, [
|
||||
%% Internal ACL module
|
||||
%% {internal, [{file, "testdata/test_acl.config"}, {nomatch, allow}]}
|
||||
]}
|
||||
]},
|
||||
%% MQTT Protocol Options
|
||||
{mqtt, [
|
||||
%% Packet
|
||||
{packet, [
|
||||
%% Max ClientId Length Allowed
|
||||
{max_clientid_len, 1024},
|
||||
%% Max Packet Size Allowed, 64K default
|
||||
{max_packet_size, 65536}
|
||||
]},
|
||||
%% Client
|
||||
{client, [
|
||||
%% Socket is connected, but no 'CONNECT' packet received
|
||||
{idle_timeout, 10} %% seconds
|
||||
]},
|
||||
%% Session
|
||||
{session, [
|
||||
%% Max number of QoS 1 and 2 messages that can be “in flight” at one time.
|
||||
%% 0 means no limit
|
||||
{max_inflight, 100},
|
||||
|
||||
%% Retry interval for redelivering QoS1/2 messages.
|
||||
{unack_retry_interval, 20},
|
||||
|
||||
%% Awaiting PUBREL Timeout
|
||||
{await_rel_timeout, 20},
|
||||
|
||||
%% Max Packets that Awaiting PUBREL, 0 means no limit
|
||||
{max_awaiting_rel, 0},
|
||||
|
||||
%% Statistics Collection Interval(seconds)
|
||||
{collect_interval, 20},
|
||||
|
||||
%% Expired after 2 day (unit: minute)
|
||||
{expired_after, 2880}
|
||||
|
||||
]},
|
||||
%% Queue
|
||||
{queue, [
|
||||
%% simple | priority
|
||||
{type, simple},
|
||||
|
||||
%% Topic Priority: 0~255, Default is 0
|
||||
%% {priority, [{"topic/1", 10}, {"topic/2", 8}]},
|
||||
|
||||
%% Max queue length. Enqueued messages when persistent client disconnected,
|
||||
%% or inflight window is full.
|
||||
{max_length, infinity},
|
||||
|
||||
%% Low-water mark of queued messages
|
||||
{low_watermark, 0.2},
|
||||
|
||||
%% High-water mark of queued messages
|
||||
{high_watermark, 0.6},
|
||||
|
||||
%% Queue Qos0 messages?
|
||||
{queue_qos0, true}
|
||||
]}
|
||||
]},
|
||||
%% Broker Options
|
||||
{broker, [
|
||||
%% System interval of publishing broker $SYS messages
|
||||
{sys_interval, 60},
|
||||
|
||||
%% Retained messages
|
||||
{retained, [
|
||||
%% Expired after seconds, never expired if 0
|
||||
{expired_after, 0},
|
||||
|
||||
%% Max number of retained messages
|
||||
{max_message_num, 100000},
|
||||
|
||||
%% Max Payload Size of retained message
|
||||
{max_playload_size, 65536}
|
||||
]},
|
||||
|
||||
%% PubSub and Router
|
||||
{pubsub, [
|
||||
%% Default should be scheduler numbers
|
||||
{pool_size, 8},
|
||||
|
||||
%% Route aging time(seconds)
|
||||
{route_aging, 5}
|
||||
]},
|
||||
|
||||
%% Bridge
|
||||
{bridge, [
|
||||
%%TODO: bridge queue size
|
||||
{max_queue_len, 10000},
|
||||
|
||||
%% Ping Interval of bridge node
|
||||
{ping_down_interval, 1} %seconds
|
||||
]}
|
||||
]},
|
||||
%% Modules
|
||||
{modules, [
|
||||
%% Client presence management module.
|
||||
%% Publish messages when client connected or disconnected
|
||||
{presence, [{qos, 0}]},
|
||||
|
||||
%% Subscribe topics automatically when client connected
|
||||
{subscription, [
|
||||
|
||||
%% $c will be replaced by clientid
|
||||
%% {"$queue/clients/$c", 1},
|
||||
|
||||
%% Static subscriptions from backend
|
||||
backend
|
||||
]}
|
||||
|
||||
%% Rewrite rules
|
||||
%% {rewrite, [{file, "etc/rewrite.config"}]}
|
||||
]},
|
||||
%% Plugins
|
||||
{plugins, [
|
||||
%% Plugin App Library Dir
|
||||
{plugins_dir, "./plugins"},
|
||||
|
||||
%% File to store loaded plugin names.
|
||||
{loaded_file, "./data/loaded_plugins"}
|
||||
]},
|
||||
|
||||
%% Listeners
|
||||
{listeners, [
|
||||
{mqtt, 1883, [
|
||||
%% Size of acceptor pool
|
||||
{acceptors, 16},
|
||||
|
||||
%% Maximum number of concurrent clients
|
||||
{max_clients, 512},
|
||||
|
||||
%% Socket Access Control
|
||||
{access, [{allow, all}]},
|
||||
|
||||
%% Connection Options
|
||||
{connopts, [
|
||||
%% Rate Limit. Format is 'burst, rate', Unit is KB/Sec
|
||||
%% {rate_limit, "100,10"} %% 100K burst, 10K rate
|
||||
]},
|
||||
|
||||
%% Socket Options
|
||||
{sockopts, [
|
||||
%Set buffer if hight thoughtput
|
||||
%{recbuf, 4096},
|
||||
%{sndbuf, 4096},
|
||||
%{buffer, 4096},
|
||||
%{nodelay, true},
|
||||
{backlog, 512}
|
||||
]}
|
||||
]},
|
||||
|
||||
{mqtts, 8883, [
|
||||
%% Size of acceptor pool
|
||||
{acceptors, 4},
|
||||
|
||||
%% Maximum number of concurrent clients
|
||||
{max_clients, 512},
|
||||
|
||||
%% Socket Access Control
|
||||
{access, [{allow, all}]},
|
||||
|
||||
%% SSL certificate and key files
|
||||
{ssl, [{certfile, "etc/ssl/ssl.crt"},
|
||||
{keyfile, "etc/ssl/ssl.key"}]},
|
||||
|
||||
%% Socket Options
|
||||
{sockopts, [
|
||||
{backlog, 1024}
|
||||
%{buffer, 4096},
|
||||
]}
|
||||
]},
|
||||
%% WebSocket over HTTPS Listener
|
||||
%% {https, 8083, [
|
||||
%% %% Size of acceptor pool
|
||||
%% {acceptors, 4},
|
||||
%% %% Maximum number of concurrent clients
|
||||
%% {max_clients, 512},
|
||||
%% %% Socket Access Control
|
||||
%% {access, [{allow, all}]},
|
||||
%% %% SSL certificate and key files
|
||||
%% {ssl, [{certfile, "etc/ssl/ssl.crt"},
|
||||
%% {keyfile, "etc/ssl/ssl.key"}]},
|
||||
%% %% Socket Options
|
||||
%% {sockopts, [
|
||||
%% %{buffer, 4096},
|
||||
%% {backlog, 1024}
|
||||
%% ]}
|
||||
%%]},
|
||||
|
||||
%% HTTP and WebSocket Listener
|
||||
{http, 8083, [
|
||||
%% Size of acceptor pool
|
||||
{acceptors, 4},
|
||||
%% Maximum number of concurrent clients
|
||||
{max_clients, 64},
|
||||
%% Socket Access Control
|
||||
{access, [{allow, all}]},
|
||||
%% Socket Options
|
||||
{sockopts, [
|
||||
{backlog, 1024}
|
||||
%{buffer, 4096},
|
||||
]}
|
||||
]}
|
||||
]},
|
||||
|
||||
%% Erlang System Monitor
|
||||
{sysmon, [
|
||||
%% Long GC
|
||||
{long_gc, 100},
|
||||
|
||||
%% Long Schedule(ms)
|
||||
{long_schedule, 100},
|
||||
|
||||
%% 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM.
|
||||
%% 8 * 1024 * 1024
|
||||
{large_heap, 8388608},
|
||||
|
||||
%% Busy Port
|
||||
{busy_port, true},
|
||||
|
||||
%% Busy Dist Port
|
||||
{busy_dist_port, true}
|
||||
|
||||
]}
|
||||
]}
|
||||
].
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
%%%-----------------------------------------------------------------------------
|
||||
%%
|
||||
%% [Rewrite](https://github.com/emqtt/emqttd/wiki/Rewrite)
|
||||
%%
|
||||
%%%-----------------------------------------------------------------------------
|
||||
|
||||
%{topic, "x/#", [
|
||||
% {rewrite, "^x/y/(.+)$", "z/y/$1"},
|
||||
% {rewrite, "^x/(.+)$", "y/$1"}
|
||||
%]}.
|
||||
|
||||
%{topic, "y/+/z/#", [
|
||||
% {rewrite, "^y/(.+)/z/(.+)$", "y/z/$2"}
|
||||
%]}.
|
|
@ -1,98 +0,0 @@
|
|||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||
%% ex: ft=erlang ts=4 sw=4 et
|
||||
{sys, [
|
||||
{lib_dirs, ["../deps"]},
|
||||
{erts, [{mod_cond, derived}, {app_file, strip}]},
|
||||
{app_file, strip},
|
||||
{rel, "emqttd", git,
|
||||
[
|
||||
kernel,
|
||||
stdlib,
|
||||
sasl,
|
||||
asn1,
|
||||
syntax_tools,
|
||||
ssl,
|
||||
crypto,
|
||||
eldap,
|
||||
xmerl,
|
||||
os_mon,
|
||||
inets,
|
||||
goldrush,
|
||||
compiler,
|
||||
runtime_tools,
|
||||
{observer, load},
|
||||
lager,
|
||||
gen_logger,
|
||||
gproc,
|
||||
esockd,
|
||||
mochiweb,
|
||||
emqttd
|
||||
]},
|
||||
{rel, "start_clean", "",
|
||||
[
|
||||
kernel,
|
||||
stdlib
|
||||
]},
|
||||
{boot_rel, "emqttd"},
|
||||
{profile, embedded},
|
||||
{incl_cond, exclude},
|
||||
%{mod_cond, derived},
|
||||
{excl_archive_filters, [".*"]}, %% Do not archive built libs
|
||||
{excl_sys_filters, ["^bin/(?!start_clean.boot)",
|
||||
"^erts.*/bin/(dialyzer|typer)",
|
||||
"^erts.*/(doc|info|include|lib|man|src)"]},
|
||||
{excl_app_filters, ["\.gitignore"]},
|
||||
{app, kernel, [{incl_cond, include}]},
|
||||
{app, stdlib, [{incl_cond, include}]},
|
||||
{app, sasl, [{incl_cond, include}]},
|
||||
{app, asn1, [{incl_cond, include}]},
|
||||
{app, crypto, [{incl_cond, include}]},
|
||||
{app, ssl, [{incl_cond, include}]},
|
||||
{app, xmerl, [{incl_cond, include}]},
|
||||
{app, os_mon, [{incl_cond, include}]},
|
||||
{app, syntax_tools, [{incl_cond, include}]},
|
||||
{app, public_key, [{incl_cond, include}]},
|
||||
{app, mnesia, [{incl_cond, include}]},
|
||||
{app, eldap, [{incl_cond, include}]},
|
||||
{app, inets, [{incl_cond, include}]},
|
||||
{app, compiler, [{incl_cond, include}]},
|
||||
{app, runtime_tools, [{incl_cond, include}]},
|
||||
{app, observer, [{incl_cond, include}]},
|
||||
{app, goldrush, [{incl_cond, include}]},
|
||||
{app, gen_logger, [{incl_cond, include}]},
|
||||
{app, lager, [{incl_cond, include}]},
|
||||
{app, gproc, [{incl_cond, include}]},
|
||||
{app, esockd, [{mod_cond, app}, {incl_cond, include}]},
|
||||
{app, mochiweb, [{mod_cond, app}, {incl_cond, include}]},
|
||||
{app, emqttd, [{mod_cond, app}, {incl_cond, include}, {lib_dir, ".."}]}
|
||||
]}.
|
||||
|
||||
{target_dir, "emqttd"}.
|
||||
|
||||
{overlay_vars, "vars.config"}.
|
||||
|
||||
{overlay, [
|
||||
{mkdir, "log/"},
|
||||
{mkdir, "etc/"},
|
||||
{mkdir, "etc/ssl/"},
|
||||
{mkdir, "data/"},
|
||||
{mkdir, "data/mnesia"},
|
||||
{mkdir, "plugins/"},
|
||||
{copy, "files/erl", "\{\{erts_vsn\}\}/bin/erl"},
|
||||
{template, "files/nodetool", "\{\{erts_vsn\}\}/bin/nodetool"},
|
||||
{template, "files/emqttd", "bin/emqttd"},
|
||||
{template, "files/emqttd_ctl", "bin/emqttd_ctl"},
|
||||
{template, "files/emqttd_top", "bin/emqttd_top"},
|
||||
{template, "files/emqttd.cmd", "bin/emqttd.cmd"},
|
||||
{copy, "files/start_erl.cmd", "bin/start_erl.cmd"},
|
||||
{copy, "files/install_upgrade.escript", "bin/install_upgrade.escript"},
|
||||
{copy, "files/ssl/ssl.crt", "etc/ssl/ssl.crt"},
|
||||
{copy, "files/ssl/ssl.key", "etc/ssl/ssl.key"},
|
||||
{template, "files/emqttd.config.production", "etc/emqttd.config"},
|
||||
{template, "files/emqttd.config.development", "etc/emqttd.config.development"},
|
||||
{template, "files/acl.config", "etc/acl.config"},
|
||||
{template, "files/rewrite.config", "etc/rewrite.config"},
|
||||
{template, "files/clients.config", "etc/clients.config"},
|
||||
{template, "files/vm.args", "etc/vm.args"},
|
||||
{copy, "files/loaded_plugins", "data/loaded_plugins"}
|
||||
]}.
|
|
@ -1,18 +0,0 @@
|
|||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||
%% ex: ft=erlang ts=4 sw=4 et
|
||||
|
||||
Sys = proplists:get_value(sys, CONFIG),
|
||||
IncludeApps = [App || {app, App, _} <- Sys],
|
||||
|
||||
[DepsDir] = proplists:get_value(lib_dirs, Sys),
|
||||
DepApps = lists:map(fun(AppFile) ->
|
||||
{ok, [{application, Name, Attrs}]}
|
||||
= file:consult(filename:join(DepsDir, AppFile)),
|
||||
Name
|
||||
end, filelib:wildcard("*/ebin/*.app", DepsDir)),
|
||||
AppendApps = DepApps -- IncludeApps,
|
||||
Cond = [{mod_cond, app}, {incl_cond, include}],
|
||||
|
||||
NewSys = lists:append(Sys, [{app, App, Cond} || App <- AppendApps]),
|
||||
|
||||
lists:keyreplace(sys, 1, CONFIG, {sys, NewSys}).
|
|
@ -1,28 +0,0 @@
|
|||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||
%% ex: ft=erlang ts=4 sw=4 et
|
||||
|
||||
%% Platform-specific installation paths
|
||||
{platform_bin_dir, "./bin"}.
|
||||
{platform_data_dir, "./var/data"}.
|
||||
{platform_etc_dir, "./etc"}.
|
||||
{platform_lib_dir, "./lib"}.
|
||||
{platform_log_dir, "./log"}.
|
||||
|
||||
%%
|
||||
%% etc/emqttd.config
|
||||
%%
|
||||
|
||||
|
||||
%%
|
||||
%% etc/vm.args
|
||||
%%
|
||||
|
||||
%%
|
||||
%% bin/emqttd
|
||||
%%
|
||||
{runner_script_dir, "$(cd ${0%/*} && pwd)"}.
|
||||
{runner_base_dir, "${RUNNER_SCRIPT_DIR%/*}"}.
|
||||
{runner_etc_dir, "$RUNNER_BASE_DIR/etc"}.
|
||||
{runner_log_dir, "$RUNNER_BASE_DIR/log"}.
|
||||
{pipe_dir, "/tmp/$RUNNER_SCRIPT/"}.
|
||||
{runner_user, ""}.
|
|
@ -1,77 +0,0 @@
|
|||
%%--------------------------------------------------------------------
|
||||
%% Copyright (c) 2012-2016 Feng Lee <feng@emqtt.io>.
|
||||
%%
|
||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||
%% you may not use this file except in compliance with the License.
|
||||
%% You may obtain a copy of the License at
|
||||
%%
|
||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||
%%
|
||||
%% Unless required by applicable law or agreed to in writing, software
|
||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
%% See the License for the specific language governing permissions and
|
||||
%% limitations under the License.
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% @doc LDAP Authentication Module
|
||||
-module(emqttd_auth_ldap).
|
||||
|
||||
-include("emqttd.hrl").
|
||||
|
||||
-import(proplists, [get_value/2, get_value/3]).
|
||||
|
||||
-behaviour(emqttd_auth_mod).
|
||||
|
||||
-export([init/1, check/3, description/0]).
|
||||
|
||||
-record(state, {servers, user_dn, options}).
|
||||
|
||||
init(Opts) ->
|
||||
Servers = get_value(servers, Opts, ["localhost"]),
|
||||
Port = get_value(port, Opts, 389),
|
||||
Timeout = get_value(timeout, Opts, 30),
|
||||
UserDn = get_value(user_dn, Opts),
|
||||
LdapOpts =
|
||||
case get_value(ssl, Opts, false) of
|
||||
true ->
|
||||
SslOpts = get_value(sslopts, Opts),
|
||||
[{port, Port}, {timeout, Timeout}, {sslopts, SslOpts}];
|
||||
false ->
|
||||
[{port, Port}, {timeout, Timeout}]
|
||||
end,
|
||||
{ok, #state{servers = Servers, user_dn = UserDn, options = LdapOpts}}.
|
||||
|
||||
check(#mqtt_client{username = undefined}, _Password, _State) ->
|
||||
{error, username_undefined};
|
||||
check(_Client, undefined, _State) ->
|
||||
{error, password_undefined};
|
||||
check(_Client, <<>>, _State) ->
|
||||
{error, password_undefined};
|
||||
check(#mqtt_client{username = Username}, Password,
|
||||
#state{servers = Servers, user_dn = UserDn, options = Options}) ->
|
||||
case eldap:open(Servers, Options) of
|
||||
{ok, LDAP} ->
|
||||
UserDn1 = fill(binary_to_list(Username), UserDn),
|
||||
ldap_bind(LDAP, UserDn1, binary_to_list(Password));
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
ldap_bind(LDAP, UserDn, Password) ->
|
||||
case catch eldap:simple_bind(LDAP, UserDn, Password) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, invalidCredentials} ->
|
||||
{error, invalid_credentials};
|
||||
{error, Error} ->
|
||||
{error, Error};
|
||||
{'EXIT', Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
fill(Username, UserDn) ->
|
||||
re:replace(UserDn, "\\$u", Username, [global, {return, list}]).
|
||||
|
||||
description() -> "LDAP Authentication Module".
|
||||
|
Loading…
Reference in New Issue