diff --git a/apps/emqx/src/emqx.app.src b/apps/emqx/src/emqx.app.src index 5d2d8eb2c..3d1fe32d3 100644 --- a/apps/emqx/src/emqx.app.src +++ b/apps/emqx/src/emqx.app.src @@ -3,7 +3,7 @@ {id, "emqx"}, {description, "EMQX Core"}, % strict semver, bump manually! - {vsn, "5.0.10"}, + {vsn, "5.0.11"}, {modules, []}, {registered, []}, {applications, [ diff --git a/apps/emqx/src/emqx_banned.erl b/apps/emqx/src/emqx_banned.erl index cf81c735b..0639557f3 100644 --- a/apps/emqx/src/emqx_banned.erl +++ b/apps/emqx/src/emqx_banned.erl @@ -21,6 +21,7 @@ -include("emqx.hrl"). -include("logger.hrl"). -include("types.hrl"). +-include_lib("snabbkaffe/include/snabbkaffe.hrl"). %% Mnesia bootstrap -export([mnesia/1]). @@ -180,7 +181,7 @@ create(#{ create(Banned = #banned{who = Who}) -> case look_up(Who) of [] -> - mria:dirty_write(?BANNED_TAB, Banned), + insert_banned(Banned), {ok, Banned}; [OldBanned = #banned{until = Until}] -> %% Don't support shorten or extend the until time by overwrite. @@ -190,7 +191,7 @@ create(Banned = #banned{who = Who}) -> {error, {already_exist, OldBanned}}; %% overwrite expired one is ok. false -> - mria:dirty_write(?BANNED_TAB, Banned), + insert_banned(Banned), {ok, Banned} end end. @@ -266,3 +267,21 @@ expire_banned_items(Now) -> ok, ?BANNED_TAB ). + +insert_banned(Banned) -> + mria:dirty_write(?BANNED_TAB, Banned), + on_banned(Banned). + +on_banned(#banned{who = {clientid, ClientId}}) -> + %% kick the session if the client is banned by clientid + ?tp( + warning, + kick_session_due_to_banned, + #{ + clientid => ClientId + } + ), + emqx_cm:kick_session(ClientId), + ok; +on_banned(_) -> + ok. diff --git a/apps/emqx/test/emqx_banned_SUITE.erl b/apps/emqx/test/emqx_banned_SUITE.erl index d8827721f..afbf9a579 100644 --- a/apps/emqx/test/emqx_banned_SUITE.erl +++ b/apps/emqx/test/emqx_banned_SUITE.erl @@ -21,18 +21,20 @@ -include_lib("emqx/include/emqx.hrl"). -include_lib("eunit/include/eunit.hrl"). +-include_lib("snabbkaffe/include/snabbkaffe.hrl"). all() -> emqx_common_test_helpers:all(?MODULE). init_per_suite(Config) -> - application:load(emqx), + emqx_common_test_helpers:start_apps([]), ok = ekka:start(), Config. end_per_suite(_Config) -> ekka:stop(), mria:stop(), - mria_mnesia:delete_schema(). + mria_mnesia:delete_schema(), + emqx_common_test_helpers:stop_apps([]). t_add_delete(_) -> Banned = #banned{ @@ -111,3 +113,23 @@ t_unused(_) -> %% expiry timer timer:sleep(500), ok = emqx_banned:stop(). + +t_kick(_) -> + ClientId = <<"client">>, + snabbkaffe:start_trace(), + + Now = erlang:system_time(second), + Who = {clientid, ClientId}, + + emqx_banned:create(#{ + who => Who, + by => <<"test">>, + reason => <<"test">>, + at => Now, + until => Now + 120 + }), + + Trace = snabbkaffe:collect_trace(), + snabbkaffe:stop(), + emqx_banned:delete(Who), + ?assertEqual(1, length(?of_kind(kick_session_due_to_banned, Trace))). diff --git a/apps/emqx_retainer/test/emqx_retainer_SUITE.erl b/apps/emqx_retainer/test/emqx_retainer_SUITE.erl index 86eaa4255..f3e46aed9 100644 --- a/apps/emqx_retainer/test/emqx_retainer_SUITE.erl +++ b/apps/emqx_retainer/test/emqx_retainer_SUITE.erl @@ -640,26 +640,25 @@ test_disable_then_start(_Config) -> ok. t_deliver_when_banned(_) -> - ClientId = <<"c1">>, + Client1 = <<"c1">>, + Client2 = <<"c2">>, - {ok, C1} = emqtt:start_link([{clientid, ClientId}, {clean_start, true}, {proto_ver, v5}]), + {ok, C1} = emqtt:start_link([{clientid, Client1}, {clean_start, true}, {proto_ver, v5}]), {ok, _} = emqtt:connect(C1), lists:foreach( fun(I) -> Topic = erlang:list_to_binary(io_lib:format("retained/~p", [I])), - emqtt:publish( - C1, - Topic, - <<"this is a retained message">>, - [{qos, 0}, {retain, true}] - ) + Msg = emqx_message:make(Client2, 0, Topic, <<"this is a retained message">>), + Msg2 = emqx_message:set_flag(retain, Msg), + emqx:publish(Msg2) end, lists:seq(1, 3) ), Now = erlang:system_time(second), - Who = {clientid, ClientId}, + Who = {clientid, Client2}, + emqx_banned:create(#{ who => Who, by => <<"test">>, diff --git a/changes/v5.0.11-en.md b/changes/v5.0.11-en.md index e90415f69..55226faf1 100644 --- a/changes/v5.0.11-en.md +++ b/changes/v5.0.11-en.md @@ -7,6 +7,9 @@ - Security enhancement for the `subscribe` API [#9355](https://github.com/emqx/emqx/pull/9355). +- Enhance the `banned` feature [#9367](https://github.com/emqx/emqx/pull/9367). + Now the corresponding session will be kicked when client is banned by `clientid`. + ## Bug fixes - Return 404 for status of unknown authenticator in `/authenticator/{id}/status` [#9328](https://github.com/emqx/emqx/pull/9328). diff --git a/changes/v5.0.11-zh.md b/changes/v5.0.11-zh.md index 1cfcc722e..a84b2b25c 100644 --- a/changes/v5.0.11-zh.md +++ b/changes/v5.0.11-zh.md @@ -7,6 +7,9 @@ - 增强订阅 API 的安全性 [#9355](https://github.com/emqx/emqx/pull/9355)。 +- 增加 `封禁` 功能 [#9367](https://github.com/emqx/emqx/pull/9367)。 + 现在客户端通过 `clientid` 被封禁时将会踢掉对应的会话。 + ## 修复 - 通过 `/authenticator/{id}/status` 请求未知认证器的状态时,将会返回 404。