fix(ldap): fixed that the connection to the LDAP connector could be disconnected after a period of time

This commit is contained in:
firest 2024-02-28 21:46:03 +08:00
parent eaa0bfd120
commit b9f644c355
2 changed files with 39 additions and 15 deletions

View File

@ -39,11 +39,12 @@
-export([namespace/0, roots/0, fields/1, desc/1]). -export([namespace/0, roots/0, fields/1, desc/1]).
-export([do_get_status/1]). -export([do_get_status/1, get_status_with_poolname/1]).
-define(LDAP_HOST_OPTIONS, #{ -define(LDAP_HOST_OPTIONS, #{
default_port => 389 default_port => 389
}). }).
-define(REDACT_VAL, "******").
-type params_tokens() :: #{atom() => list()}. -type params_tokens() :: #{atom() => list()}.
-type state() :: -type state() ::
@ -154,18 +155,19 @@ on_start(
false -> false ->
Config2 Config2
end, end,
Options = [ Options = [
{pool_size, PoolSize}, {pool_size, PoolSize},
{auto_reconnect, ?AUTO_RECONNECT_INTERVAL}, {auto_reconnect, ?AUTO_RECONNECT_INTERVAL},
{options, Config3} {options, Config3}
], ],
case emqx_resource_pool:start(InstId, ?MODULE, Options) of case emqx_resource_pool:start(InstId, ?MODULE, [{log_tag, "eldap_info"} | Options]) of
ok -> ok ->
emqx_ldap_bind_worker:on_start( emqx_ldap_bind_worker:on_start(
InstId, InstId,
Config, Config,
Options, [{log_tag, "eldap_bind_info"} | Options],
prepare_template(Config, #{pool_name => InstId}) prepare_template(Config, #{pool_name => InstId})
); );
{error, Reason} -> {error, Reason} ->
@ -193,7 +195,15 @@ on_query(InstId, {query, Data, Attrs, Timeout}, State) ->
on_query(InstId, {bind, _DN, _Data} = Req, State) -> on_query(InstId, {bind, _DN, _Data} = Req, State) ->
emqx_ldap_bind_worker:on_query(InstId, Req, State). emqx_ldap_bind_worker:on_query(InstId, Req, State).
on_get_status(_InstId, #{pool_name := PoolName} = _State) -> on_get_status(InstId, #{pool_name := PoolName} = State) ->
case get_status_with_poolname(PoolName) of
connected ->
emqx_ldap_bind_worker:on_get_status(InstId, State);
disconnected ->
disconnected
end.
get_status_with_poolname(PoolName) ->
case emqx_resource_pool:health_check_workers(PoolName, fun ?MODULE:do_get_status/1) of case emqx_resource_pool:health_check_workers(PoolName, fun ?MODULE:do_get_status/1) of
true -> true ->
connected; connected;
@ -209,7 +219,7 @@ do_get_status(Conn) ->
%% if the server is down, the result is {error, ldap_closed} %% if the server is down, the result is {error, ldap_closed}
%% otherwise is {error, invalidDNSyntax/timeout} %% otherwise is {error, invalidDNSyntax/timeout}
{error, ldap_closed} =/= {error, ldap_closed} =/=
eldap:search(Conn, [{base, "checkalive"}, {filter, eldap:'approxMatch'("", "")}]). eldap:search(Conn, [{base, "cn=checkalive"}, {filter, eldap:'approxMatch'("", "")}]).
%% =================================================================== %% ===================================================================
@ -222,7 +232,8 @@ connect(Options) ->
} = } =
Conf = proplists:get_value(options, Options), Conf = proplists:get_value(options, Options),
OpenOpts = maps:to_list(maps:with([port, sslopts], Conf)), OpenOpts = maps:to_list(maps:with([port, sslopts], Conf)),
case eldap:open([Host], [{log, fun log/3}, {timeout, RequestTimeout} | OpenOpts]) of LogTag = proplists:get_value(log_tag, Options),
case eldap:open([Host], [{log, mk_log_func(LogTag)}, {timeout, RequestTimeout} | OpenOpts]) of
{ok, Handle} = Ret -> {ok, Handle} = Ret ->
%% TODO: teach `eldap` to accept 0-arity closures as passwords. %% TODO: teach `eldap` to accept 0-arity closures as passwords.
case eldap:simple_bind(Handle, Username, emqx_secret:unwrap(Password)) of case eldap:simple_bind(Handle, Username, emqx_secret:unwrap(Password)) of
@ -313,14 +324,21 @@ do_ldap_query(
end. end.
%% Note: the value of the `_Level` here always is 2 %% Note: the value of the `_Level` here always is 2
log(_Level, Format, Args) -> mk_log_func(LogTag) ->
?SLOG( fun(_Level, Format, Args) ->
info, ?SLOG(
#{ info,
msg => "eldap_info", #{
log => io_lib:format(Format, Args) msg => LogTag,
} log => io_lib:format(Format, [redact_ldap_log(Arg) || Arg <- Args])
). }
)
end.
redact_ldap_log({'BindRequest', Version, Name, {simple, _}}) ->
{'BindRequest', Version, Name, {simple, ?REDACT_VAL}};
redact_ldap_log(Arg) ->
Arg.
prepare_template(Config, State) -> prepare_template(Config, State) ->
maps:fold(fun prepare_template/3, State, Config). maps:fold(fun prepare_template/3, State, Config).

View File

@ -24,7 +24,8 @@
-export([ -export([
on_start/4, on_start/4,
on_stop/2, on_stop/2,
on_query/3 on_query/3,
on_get_status/2
]). ]).
%% ecpool connect & reconnect %% ecpool connect & reconnect
@ -103,6 +104,11 @@ on_query(
{error, {unrecoverable_error, Reason}} {error, {unrecoverable_error, Reason}}
end. end.
on_get_status(_InstId, #{bind_pool_name := PoolName}) ->
emqx_ldap:get_status_with_poolname(PoolName);
on_get_status(_InstId, _) ->
connected.
%% =================================================================== %% ===================================================================
connect(Conf) -> connect(Conf) ->