From d4df2ddf251107e3952e46fab75ddca35ce670d6 Mon Sep 17 00:00:00 2001 From: firest Date: Fri, 3 Feb 2023 15:30:37 +0800 Subject: [PATCH 1/2] feat(banned): session will be kicked when client is banned by `clientid` --- src/emqx_banned.erl | 33 +++++++++++++++++++++++++++------ test/emqx_banned_SUITE.erl | 30 +++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/emqx_banned.erl b/src/emqx_banned.erl index ba5259c52..ce5c9c2be 100644 --- a/src/emqx_banned.erl +++ b/src/emqx_banned.erl @@ -21,6 +21,7 @@ -include("emqx.hrl"). -include("logger.hrl"). -include("types.hrl"). +-include_lib("snabbkaffe/include/snabbkaffe.hrl"). -logger_header("[Banned]"). @@ -95,13 +96,15 @@ create(#{who := Who, reason := Reason, at := At, until := Until}) -> - mnesia:dirty_write(?BANNED_TAB, #banned{who = Who, - by = By, - reason = Reason, - at = At, - until = Until}); + insert_banned(#banned{ + who = Who, + by = By, + reason = Reason, + at = At, + until = Until + }); create(Banned) when is_record(Banned, banned) -> - mnesia:dirty_write(?BANNED_TAB, Banned). + insert_banned(Banned). -spec(delete({clientid, emqx_types:clientid()} | {username, emqx_types:username()} @@ -162,3 +165,21 @@ expire_banned_items(Now) -> mnesia:delete_object(?BANNED_TAB, B, sticky_write); (_, _Acc) -> ok end, ok, ?BANNED_TAB). + +insert_banned(Banned) -> + mnesia: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/test/emqx_banned_SUITE.erl b/test/emqx_banned_SUITE.erl index 3630b7516..f409b1f96 100644 --- a/test/emqx_banned_SUITE.erl +++ b/test/emqx_banned_SUITE.erl @@ -21,11 +21,12 @@ -include_lib("emqx/include/emqx.hrl"). -include_lib("eunit/include/eunit.hrl"). +-include_lib("snabbkaffe/include/snabbkaffe.hrl"). all() -> emqx_ct:all(?MODULE). init_per_suite(Config) -> - application:load(emqx), + emqx_ct_helpers:start_apps([]), ok = ekka:start(), %% for coverage ok = emqx_banned:mnesia(copy), @@ -34,7 +35,8 @@ init_per_suite(Config) -> end_per_suite(_Config) -> ekka:stop(), ekka_mnesia:ensure_stopped(), - ekka_mnesia:delete_schema(). + ekka_mnesia:delete_schema(), + emqx_ct_helpers:stop_apps([]). t_add_delete(_) -> Banned = #banned{who = {clientid, <<"TestClient">>}, @@ -84,7 +86,10 @@ t_check(_) -> ?assertEqual(0, emqx_banned:info(size)). t_unused(_) -> - {ok, Banned} = emqx_banned:start_link(), + Banned = case emqx_banned:start_link() of + {ok, Pid} -> Pid; + {error, {already_started, Pid}} -> Pid + end, ok = emqx_banned:create(#banned{who = {clientid, <<"BannedClient">>}, until = erlang:system_time(second)}), ?assertEqual(ignored, gen_server:call(Banned, unexpected_req)), @@ -93,3 +98,22 @@ t_unused(_) -> timer:sleep(500), %% expiry timer 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))). From 9140f50456f0c1f383c982d9c8ae1c6075c75054 Mon Sep 17 00:00:00 2001 From: firest Date: Fri, 3 Feb 2023 15:36:25 +0800 Subject: [PATCH 2/2] chore: update changes --- changes/v4.4.15-en.md | 2 ++ changes/v4.4.15-zh.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/changes/v4.4.15-en.md b/changes/v4.4.15-en.md index 1dfe74aac..49024bdd5 100644 --- a/changes/v4.4.15-en.md +++ b/changes/v4.4.15-en.md @@ -10,6 +10,8 @@ - Security enhancement for retained messages [#9790](https://github.com/emqx/emqx/pull/9790). The retained messages will not be published if the publisher client is banned. +- Now the corresponding session will be kicked when client is banned by `clientid` [#9904](https://github.com/emqx/emqx/pull/9904). + ## Bug fixes - Fix the problem that new MQTT TLS connections failed to establish after release hot upgrade [#9810](https://github.com/emqx/emqx/pull/9810). diff --git a/changes/v4.4.15-zh.md b/changes/v4.4.15-zh.md index a4bb0a50d..4a0a6cf74 100644 --- a/changes/v4.4.15-zh.md +++ b/changes/v4.4.15-zh.md @@ -10,6 +10,8 @@ - 增强 `保留消息` 的安全性 [#9790](https://github.com/emqx/emqx/pull/9790)。 现在投递保留消息前,会先过滤掉来源客户端被封禁了的那些消息。 +- 现在客户端通过 `clientid` 被封禁时将会踢掉对应的会话 [#9904](https://github.com/emqx/emqx/pull/9904)。 + ## 修复 - 修复版本热升级之后,新的 MQTT TLS 连接建立失败的问题 [#9810](https://github.com/emqx/emqx/pull/9810)。