diff --git a/etc/acl.conf b/etc/acl.conf new file mode 100644 index 000000000..c818c64f0 --- /dev/null +++ b/etc/acl.conf @@ -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}. + diff --git a/etc/client.conf b/etc/client.conf new file mode 100644 index 000000000..2c880c365 --- /dev/null +++ b/etc/client.conf @@ -0,0 +1,3 @@ +testclientid0 +testclientid1 127.0.0.1 +testclientid2 192.168.0.1/24 diff --git a/etc/emqttd.conf b/etc/emqttd.conf new file mode 100644 index 000000000..92a575795 --- /dev/null +++ b/etc/emqttd.conf @@ -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}. + diff --git a/etc/passwd.conf b/etc/passwd.conf new file mode 100644 index 000000000..e6998746d --- /dev/null +++ b/etc/passwd.conf @@ -0,0 +1,2 @@ +user1:passwd1 +user2:passwd2 diff --git a/rel/files/ssl/ssl.crt b/etc/ssl/ssl.crt similarity index 100% rename from rel/files/ssl/ssl.crt rename to etc/ssl/ssl.crt diff --git a/rel/files/ssl/ssl.key b/etc/ssl/ssl.key similarity index 100% rename from rel/files/ssl/ssl.key rename to etc/ssl/ssl.key diff --git a/rel/files/emqttd b/rel/files/emqttd deleted file mode 100755 index b78e68e25..000000000 --- a/rel/files/emqttd +++ /dev/null @@ -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 diff --git a/rel/files/emqttd.cmd b/rel/files/emqttd.cmd deleted file mode 100644 index effa49536..000000000 --- a/rel/files/emqttd.cmd +++ /dev/null @@ -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 diff --git a/rel/files/emqttd.test.config b/rel/files/emqttd.test.config deleted file mode 100644 index 48ad73252..000000000 --- a/rel/files/emqttd.test.config +++ /dev/null @@ -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} - - ]} - ]} -]. - diff --git a/rel/files/rewrite.config b/rel/files/rewrite.config deleted file mode 100644 index 494a85f74..000000000 --- a/rel/files/rewrite.config +++ /dev/null @@ -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"} -%]}. diff --git a/rel/reltool.config b/rel/reltool.config deleted file mode 100644 index c79fa74cd..000000000 --- a/rel/reltool.config +++ /dev/null @@ -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"} - ]}. diff --git a/rel/reltool.config.script b/rel/reltool.config.script deleted file mode 100644 index fa6b571ac..000000000 --- a/rel/reltool.config.script +++ /dev/null @@ -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}). diff --git a/rel/vars.config b/rel/vars.config deleted file mode 100644 index 982940a28..000000000 --- a/rel/vars.config +++ /dev/null @@ -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, ""}. diff --git a/src/emqttd_auth_ldap.erl b/src/emqttd_auth_ldap.erl deleted file mode 100644 index 11e1f27f3..000000000 --- a/src/emqttd_auth_ldap.erl +++ /dev/null @@ -1,77 +0,0 @@ -%%-------------------------------------------------------------------- -%% Copyright (c) 2012-2016 Feng Lee . -%% -%% 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". -