diff --git a/etc/emq.conf b/etc/emq.conf index 7238f3395..e30ddfa26 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -1,3 +1,8 @@ + +##=================================================================== +## EMQ Configuration R2.1 +##=================================================================== + ##-------------------------------------------------------------------- ## Node Args ##-------------------------------------------------------------------- @@ -45,16 +50,25 @@ node.crash_dump = {{ platform_log_dir }}/crash.dump node.dist_net_ticktime = 60 ## Distributed node port range -## node.dist_listen_min = 6000 -## node.dist_listen_max = 6999 +## node.dist_listen_min = 6369 +## node.dist_listen_max = 6369 ##-------------------------------------------------------------------- ## Log ##-------------------------------------------------------------------- +## Set the log dir +log.dir = {{ platform_log_dir }} + ## Console log. Enum: off, file, console, both log.console = console +## Syslog. Enum: on, off +log.syslog = on + +## syslog level. Enum: debug, info, notice, warning, error, critical, alert, emergency +log.syslog.level = error + ## Console log level. Enum: debug, info, notice, warning, error, critical, alert, emergency log.console.level = error @@ -70,18 +84,9 @@ log.crash = on log.crash.file = {{ platform_log_dir }}/crash.log ##-------------------------------------------------------------------- -## MQTT Protocol +## Allow Anonymous and Default ACL ##-------------------------------------------------------------------- -## Max ClientId Length Allowed. -mqtt.max_clientid_len = 1024 - -## Max Packet Size Allowed, 64K by default. -mqtt.max_packet_size = 64KB - -## Client Idle Timeout (Second) -mqtt.client_idle_timeout = 30 - ## Allow Anonymous authentication mqtt.allow_anonymous = true @@ -91,25 +96,48 @@ mqtt.acl_file = {{ platform_etc_dir }}/acl.conf ## Cache ACL for PUBLISH mqtt.cache_acl = true +##-------------------------------------------------------------------- +## MQTT Protocol +##-------------------------------------------------------------------- + +## Max ClientId Length Allowed. +mqtt.max_clientid_len = 1024 + +## Max Packet Size Allowed, 64K by default. +mqtt.max_packet_size = 64KB + +##-------------------------------------------------------------------- +## MQTT Client +##-------------------------------------------------------------------- + +## Client Idle Timeout (Second) +mqtt.client.idle_timeout = 30s + +## Enable client Stats: seconds or off +mqtt.client.enable_stats = off + ##-------------------------------------------------------------------- ## MQTT Session ##-------------------------------------------------------------------- +## Upgrade QoS? +mqtt.session.upgrade_qos = off + ## Max number of QoS 1 and 2 messages that can be “inflight” at one time. ## 0 means no limit -mqtt.session.max_inflight = 100 +mqtt.session.max_inflight = 32 -## Retry interval for redelivering QoS1/2 messages. -mqtt.session.retry_interval = 60 - -## Awaiting PUBREL Timeout -mqtt.session.await_rel_timeout = 20 +## Retry Interval for redelivering QoS1/2 messages. +mqtt.session.retry_interval = 20s ## Max Packets that Awaiting PUBREL, 0 means no limit -mqtt.session.max_awaiting_rel = 0 +mqtt.session.max_awaiting_rel = 100 -## Statistics Collection Interval(seconds) -mqtt.session.collect_interval = 0 +## Awaiting PUBREL Timeout +mqtt.session.await_rel_timeout = 20s + +## Enable Statistics at the Interval(seconds) +mqtt.session.enable_stats = off ## Expired after 1 day: ## w - week @@ -117,7 +145,7 @@ mqtt.session.collect_interval = 0 ## h - hour ## m - minute ## s - second -mqtt.session.expired_after = 1d +mqtt.session.expiry_interval = 2h ##-------------------------------------------------------------------- ## MQTT Queue @@ -212,9 +240,10 @@ mqtt.listener.ssl.max_clients = 512 ## Rate Limit. Format is 'burst,rate', Unit is KB/Sec ## mqtt.listener.ssl.rate_limit = 100,10 -## Configuring SSL Options -## See http://erlang.org/doc/man/ssl.html -mqtt.listener.ssl.handshake_timeout = 15 +## Configuring SSL Options. See http://erlang.org/doc/man/ssl.html +### TLS only for POODLE attack +mqtt.listener.ssl.tls_versions = tlsv1.2,tlsv1.1,tlsv1 +mqtt.listener.ssl.handshake_timeout = 15s mqtt.listener.ssl.keyfile = {{ platform_etc_dir }}/certs/key.pem mqtt.listener.ssl.certfile = {{ platform_etc_dir }}/certs/cert.pem ## mqtt.listener.ssl.cacertfile = {{ platform_etc_dir }}/certs/cacert.pem diff --git a/priv/emq.schema b/priv/emq.schema index 1722522c4..156bc4874 100644 --- a/priv/emq.schema +++ b/priv/emq.schema @@ -148,8 +148,13 @@ end}. %% Log %%-------------------------------------------------------------------- +{mapping, "log.dir", "lager.log_dir", [ + {default, "log"}, + {datatype, string} +]}. + {mapping, "log.console", "lager.handlers", [ - {default, file }, + {default, file}, {datatype, {enum, [off, file, console, both]}} ]}. @@ -168,6 +173,26 @@ end}. {datatype, file} ]}. +{mapping, "log.syslog", "lager.handlers", [ + {default, off}, + {datatype, flag} +]}. + +{mapping, "log.syslog.identity", "lager.handlers", [ + {default, "emq"}, + {datatype, string} +]}. + +{mapping, "log.syslog.facility", "lager.handlers", [ + {default, local0}, + {datatype, {enum, [daemon, local0, local1, local2, local3, local4, local5, local6, local7]}} +]}. + +{mapping, "log.syslog.level", "lager.handlers", [ + {default, err}, + {datatype, {enum, [debug, info, notice, warning, error, critical, alert, emergency]}} +]}. + {mapping, "log.error.redirect", "lager.error_logger_redirect", [ {default, on}, {datatype, flag}, @@ -209,7 +234,16 @@ end}. both -> [ConsoleHandler, ConsoleFileHandler]; _ -> [] end, - ConsoleHandlers ++ ErrorHandler + + SyslogHandler = case cuttlefish:conf_get("log.syslog", Conf) of + false -> []; + true -> [{lager_syslog_backend, + [cuttlefish:conf_get("log.syslog.identity", Conf), + cuttlefish:conf_get("log.syslog.facility", Conf), + cuttlefish:conf_get("log.syslog.level", Conf)]}] + end, + + ConsoleHandlers ++ ErrorHandler ++ SyslogHandler end }. @@ -240,33 +274,9 @@ end}. ]}. %%-------------------------------------------------------------------- -%% MQTT Protocol +%% Allow Anonymous and Default ACL %%-------------------------------------------------------------------- -%% @doc Set the Max ClientId Length Allowed. -{mapping, "mqtt.max_clientid_len", "emqttd.protocol", [ - {default, 1024}, - {datatype, integer} -]}. - -%% @doc Max Packet Size Allowed, 64K by default. -{mapping, "mqtt.max_packet_size", "emqttd.protocol", [ - {default, "64KB"}, - {datatype, bytesize} -]}. - -%% @doc Client Idle Timeout. -{mapping, "mqtt.client_idle_timeout", "emqttd.protocol", [ - {default, 30}, - {datatype, integer} -]}. - -{translation, "emqttd.protocol", fun(Conf) -> - [{max_clientid_len, cuttlefish:conf_get("mqtt.max_clientid_len", Conf)}, - {max_packet_size, cuttlefish:conf_get("mqtt.max_packet_size", Conf)}, - {client_idle_timeout, cuttlefish:conf_get("mqtt.client_idle_timeout", Conf)}] -end}. - %% @doc Allow Anonymous {mapping, "mqtt.allow_anonymous", "emqttd.allow_anonymous", [ {default, false}, @@ -285,10 +295,58 @@ end}. {datatype, {enum, [true, false]}} ]}. +%%-------------------------------------------------------------------- +%% MQTT Protocol +%%-------------------------------------------------------------------- + +%% @doc Set the Max ClientId Length Allowed. +{mapping, "mqtt.max_clientid_len", "emqttd.protocol", [ + {default, 1024}, + {datatype, integer} +]}. + +%% @doc Max Packet Size Allowed, 64K by default. +{mapping, "mqtt.max_packet_size", "emqttd.protocol", [ + {default, "64KB"}, + {datatype, bytesize} +]}. + +{translation, "emqttd.protocol", fun(Conf) -> + [{max_clientid_len, cuttlefish:conf_get("mqtt.max_clientid_len", Conf)}, + {max_packet_size, cuttlefish:conf_get("mqtt.max_packet_size", Conf)}] +end}. + +%%-------------------------------------------------------------------- +%% MQTT Client +%%-------------------------------------------------------------------- + +%% @doc Client Idle Timeout. +{mapping, "mqtt.client.idle_timeout", "emqttd.client", [ + {default, "30s"}, + {datatype, {duration, ms}} +]}. + +%% @doc Enable Stats of Client. +{mapping, "mqtt.client.enable_stats", "emqttd.client", [ + {default, off}, + {datatype, [{duration, ms}, flag]} +]}. + +%% @doc Client +{translation, "emqttd.client", fun(Conf) -> + [{client_idle_timeout, cuttlefish:conf_get("mqtt.client.idle_timeout", Conf)}, + {client_enable_stats, cuttlefish:conf_get("mqtt.client.enable_stats", Conf)}] +end}. + %%-------------------------------------------------------------------- %% MQTT Session %%-------------------------------------------------------------------- +%% @doc Upgrade QoS? +{mapping, "mqtt.session.upgrade_qos", "emqttd.session", [ + {default, off}, + {datatype, flag} +]}. %% @doc Max number of QoS 1 and 2 messages that can be “inflight” at one time. %% 0 means no limit {mapping, "mqtt.session.max_inflight", "emqttd.session", [ @@ -296,17 +354,10 @@ end}. {datatype, integer} ]}. - %% @doc Retry interval for redelivering QoS1/2 messages. {mapping, "mqtt.session.retry_interval", "emqttd.session", [ - {default, 60}, - {datatype, integer} -]}. - -%% @doc Awaiting PUBREL Timeout -{mapping, "mqtt.session.await_rel_timeout", "emqttd.session", [ - {default, 30}, - {datatype, integer} + {default, "20s"}, + {datatype, {duration, ms}} ]}. %% @doc Max Packets that Awaiting PUBREL, 0 means no limit @@ -315,25 +366,32 @@ end}. {datatype, integer} ]}. -%% @doc Statistics Collection Interval(seconds) -{mapping, "mqtt.session.collect_interval", "emqttd.session", [ - {default, 0}, - {datatype, integer} +%% @doc Awaiting PUBREL Timeout +{mapping, "mqtt.session.await_rel_timeout", "emqttd.session", [ + {default, "20s"}, + {datatype, {duration, ms}} ]}. -%% @doc Session expired after... -{mapping, "mqtt.session.expired_after", "emqttd.session", [ - {default, "2d"}, - {datatype, {duration, s}} +%% @doc Enable Stats +{mapping, "mqtt.session.enable_stats", "emqttd.session", [ + {default, off}, + {datatype, [{duration, ms}, flag]} +]}. + +%% @doc Session Expiry Interval +{mapping, "mqtt.session.expiry_interval", "emqttd.session", [ + {default, "2h"}, + {datatype, {duration, ms}} ]}. {translation, "emqttd.session", fun(Conf) -> - [{max_inflight, cuttlefish:conf_get("mqtt.session.max_inflight", Conf)}, - {retry_interval, cuttlefish:conf_get("mqtt.session.retry_interval", Conf)}, + [{upgrade_qos, cuttlefish:conf_get("mqtt.session.upgrade_qos", Conf)}, + {max_inflight, cuttlefish:conf_get("mqtt.session.max_inflight", Conf)}, + {retry_interval, cuttlefish:conf_get("mqtt.session.retry_interval", Conf)}, + {max_awaiting_rel, cuttlefish:conf_get("mqtt.session.max_awaiting_rel", Conf)}, {await_rel_timeout, cuttlefish:conf_get("mqtt.session.await_rel_timeout", Conf)}, - {max_awaiting_rel, cuttlefish:conf_get("mqtt.session.max_awaiting_rel", Conf)}, - {collect_interval, cuttlefish:conf_get("mqtt.session.collect_interval", Conf)}, - {expired_after, cuttlefish:conf_get("mqtt.session.expired_after", Conf)}] + {enable_stats, cuttlefish:conf_get("mqtt.session.enable_stats", Conf)}, + {expiry_interval, cuttlefish:conf_get("mqtt.session.expiry_interval", Conf)}] end}. %%-------------------------------------------------------------------- @@ -528,9 +586,13 @@ end}. {datatype, string} ]}. +{mapping, "mqtt.listener.ssl.tls_versions", "emqttd.listeners", [ + {datatype, string} +]}. + {mapping, "mqtt.listener.ssl.handshake_timeout", "emqttd.listeners", [ - {default, 15}, - {datatype, integer} + {default, "15s"}, + {datatype, {duration, ms}} ]}. {mapping, "mqtt.listener.ssl.keyfile", "emqttd.listeners", [ @@ -622,8 +684,16 @@ end}. {buffer, cuttlefish:conf_get(Prefix ++ ".buffer", Conf, undefined)}, {nodelay, cuttlefish:conf_get(Prefix ++ ".nodelay", Conf, true)}]) end, + + SplitFun = fun(undefined) -> undefined; (S) -> string:tokens(S, ",") end, + SslOpts = fun(Prefix) -> - Filter([{handshake_timeout, cuttlefish:conf_get(Prefix ++ ".handshake_timeout", Conf) * 1000}, + Versions = case SplitFun(cuttlefish:conf_get(Prefix ++ ".tls_versions", Conf, undefined)) of + undefined -> undefined; + L -> [list_to_atom(V) || V <- L] + end, + Filter([{versions, Versions}, + {handshake_timeout, cuttlefish:conf_get(Prefix ++ ".handshake_timeout", Conf), undefined}, {keyfile, cuttlefish:conf_get(Prefix ++ ".keyfile", Conf, undefined)}, {certfile, cuttlefish:conf_get(Prefix ++ ".certfile", Conf, undefined)}, {cacertfile, cuttlefish:conf_get(Prefix ++ ".cacertfile", Conf, undefined)},