Overview
An implementation may restrict access to Server resources based on information provided by the Client such as User Name, Client Identifier, the hostname/IP address of the Client, or the outcome of authentication mechanisms.
MQTT Client
A MQTT Client identified by IpAddr, ClientId and Username.
-record(mqtt_client, {
clientid :: binary(),
username :: binary() | undefined,
ipaddr :: inet:ip_address()
}).
Access Rule
Rule
{allow, all}.
{deny, all}.
{allow | deny, Who, Access, TopicFilters}.
Who :: all | ClientId | {client, ClientId} | {ipaddr, IpAddr} | {user, Username}
ClientId :: string() | all
IpAddr :: string()
Username :: string() | all
Access :: publish | subscribe | pubsub
TopicFilter :: [Topic]
Topic :: string()
Examples
{allow, {ipaddr, "127.0.0.1"}, subscribe, ["$SYS/#", "#"]}.
{allow, {user, "testuser"}, subscribe, ["a/b/c", "d/e/f/#"]}.
{allow, {user, "admin"}, pubsub, ["a/b/c", "d/e/f/#"]}.
{allow, {client, "testClient"}, subscribe, ["testTopics/testClient"]}.
{allow, all, subscribe, ["clients/%c"]}.
{allow, all, pubsub, ["users/%u/#"]}.
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
{deny, all}.
'eq' Tag
{deny, all, subscribe, [{eq, "$SYS/#"}, {eq, "#"}]}.
Means all cannot subscribe "$SYS/#", "#". But:
{deny, all, subscribe, ["$SYS/#", "#"]}.
Means that all cannot subscribe any topics.
etc/acl.config
Default config only allow localhost to subscribe '$SYS/#', '#':
%%%-----------------------------------------------------------------------------
%%
%% [ACL Design](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, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
{deny, all, subscribe, [{eq, "$SYS/#"}, {eq, "#"}]}.
{allow, all}.
etc/app.config
{access, [
%% Authetication. , Anonymous Default
......
%% ACL config
{acl, [
%% User internal ACL module
{internal, [{file, "etc/acl.config"}, {nomatch, allow}]}
]}
Access API
Defined in emqttd_access_control.erl:
-spec check_acl(Client, PubSub, Topic) -> allow | deny when
Client :: mqtt_client(),
PubSub :: pubsub(),
Topic :: binary().
check_acl(Client, PubSub, Topic) when PubSub =:= publish orelse PubSub =:= subscribe ->
......
emqttd_acl_mod behaviour
-callback init(AclOpts :: list()) -> {ok, State :: any()}.
-callback check_acl({Client, PubSub, Topic}, State :: any()) -> allow | deny | ignore when
Client :: mqtt_client(),
PubSub :: pubsub(),
Topic :: binary().
-callback reload_acl(State :: any()) -> ok | {error, any()}.
-callback description() -> string().
Version: 1.0(Draft) Author: Feng Lee feng@emqx.io