From 085074ac41314ad7ae38710e7218d8b7bffb9bdd Mon Sep 17 00:00:00 2001 From: firest Date: Tue, 15 Nov 2022 14:08:58 +0800 Subject: [PATCH 1/2] feat(banned): kick session when it is banned by clientid --- apps/emqx/src/emqx_banned.erl | 23 ++++++++++++++-- apps/emqx/test/emqx_banned_SUITE.erl | 26 +++++++++++++++++-- .../test/emqx_retainer_SUITE.erl | 17 ++++++------ 3 files changed, 53 insertions(+), 13 deletions(-) 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">>, From b1889fa203685a7a9999cc4f9bc7c843a74e7765 Mon Sep 17 00:00:00 2001 From: firest Date: Tue, 15 Nov 2022 14:48:35 +0800 Subject: [PATCH 2/2] chore: bump emqx version && update changes --- apps/emqx/src/emqx.app.src | 2 +- changes/v5.0.11-en.md | 3 +++ changes/v5.0.11-zh.md | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) 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/changes/v5.0.11-en.md b/changes/v5.0.11-en.md index f35d11719..652879cc8 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 c16c3193a..9ec1e0414 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。