认证与访问控制设计

EMQ X 消息服务器支持可扩展的认证与访问控制,通过挂载 client.authenticate and client.check_acl 两个钩子实现。

编写鉴权钩子回调函数

挂载回调函数到 client.authenticate 钩子:

  1. emqx:hook('client.authenticate', fun ?MODULE:on_client_authenticate/1, []).

钩子回调函数必须接受一个 Credentials 参数,并且返回一个新的 Credentials:

  1. on_client_authenticate(Credentials = #{password := Password}) ->
  2. {ok, Credentials#{result => success}}.

Credentials 结构体是一个包含鉴权信息的 map:

  1. #{
  2. client_id => ClientId, %% 客户端 ID
  3. username => Username, %% 用户名
  4. peername => Peername, %% 客户端的 IP 地址和端口
  5. password => Password, %% 密码 (可选)
  6. result => Result %% 鉴权结果,success 表示认证成功,
  7. %% bad_username_or_password 或者 not_authorized 表示失败.
  8. }

编写 ACL 钩子回调函数

挂载回调函数到 client.authenticate 钩子:

  1. emqx:hook('client.check_acl', fun ?MODULE:on_client_check_acl/4, []).

回调函数必须可接受 Credentials , AccessType , Topic , ACLResult 这几个参数, 然后返回一个新的 ACLResult:

  1. on_client_check_acl(#{client_id := ClientId}, AccessType, Topic, ACLResult) ->
  2. {ok, allow}.

AccessType 可以是 publishsubscribe 之一。 Topic 是 MQTT topic。 ACLResult 要么是 allow ,要么是 deny

emqx_mod_acl_internal 模块实现了基于 etc/acl.conf 文件的 ACL 机制,etc/acl.conf 文件的默认内容:

  1. %%%-----------------------------------------------------------------------------
  2. %%%
  3. %%% -type who() :: all | binary() |
  4. %%% {ipaddr, esockd_access:cidr()} |
  5. %%% {client, binary()} |
  6. %%% {user, binary()}.
  7. %%%
  8. %%% -type access() :: subscribe | publish | pubsub.
  9. %%%
  10. %%% -type topic() :: binary().
  11. %%%
  12. %%% -type rule() :: {allow, all} |
  13. %%% {allow, who(), access(), list(topic())} |
  14. %%% {deny, all} |
  15. %%% {deny, who(), access(), list(topic())}.
  16. %%%
  17. %%%-----------------------------------------------------------------------------
  18. {allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
  19. {allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
  20. {deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
  21. {allow, all}.

由 emqx 提供的 Auth/ACL 插件:

PluginAuthentication
emqx_auth_usernameUsername and Password
emqx_auth_clientidClientID and Password
emqx_auth_ldapLDAP
emqx_auth_httpHTTP API
emqx_auth_mysqlMySQL
emqx_auth_pgsqlPostgreSQL
emqx_auth_redisRedis
emqx_auth_mongoMongoDB
emqx_auth_jwtJWT