mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-26 17:38:45 +01:00
Add mod_fail2ban
This commit is contained in:
parent
bfd028beea
commit
2430e6691b
@ -623,9 +623,13 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
P, D, DGen)
|
||||
of
|
||||
{true, AuthModule} ->
|
||||
?INFO_MSG("(~w) Accepted legacy authentication for ~s by ~p",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID), AuthModule]),
|
||||
?INFO_MSG("(~w) Accepted legacy authentication for ~s by ~p from ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID), AuthModule,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[true, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
Conn = get_conn_type(StateData),
|
||||
Info = [{ip, StateData#state.ip}, {conn, Conn},
|
||||
{auth_module, AuthModule}],
|
||||
@ -660,12 +664,13 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
privacy_list = PrivList},
|
||||
fsm_next_state(session_established, NewStateData);
|
||||
_ ->
|
||||
IP = peerip(StateData#state.sockmod,
|
||||
StateData#state.socket),
|
||||
?INFO_MSG("(~w) Failed legacy authentication for "
|
||||
"~s from IP ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID), jlib:ip_to_list(IP)]),
|
||||
?INFO_MSG("(~w) Failed legacy authentication for ~s from ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID),
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
Err = jlib:make_error_reply(El, ?ERR_NOT_AUTHORIZED),
|
||||
send_element(StateData, Err),
|
||||
fsm_next_state(wait_for_auth, StateData)
|
||||
@ -680,9 +685,13 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
fsm_next_state(wait_for_auth, StateData);
|
||||
true ->
|
||||
?INFO_MSG("(~w) Forbidden legacy authentication "
|
||||
"for ~s",
|
||||
"for ~s from ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID)]),
|
||||
jlib:jid_to_string(JID),
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
|
||||
send_element(StateData, Err),
|
||||
fsm_next_state(wait_for_auth, StateData)
|
||||
@ -732,8 +741,12 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||
%AuthModule = xml:get_attr_s(auth_module, Props),
|
||||
AuthModule = proplists:get_value(auth_module, Props, undefined),
|
||||
?INFO_MSG("(~w) Accepted authentication for ~s "
|
||||
"by ~p",
|
||||
[StateData#state.socket, U, AuthModule]),
|
||||
"by ~p from ~s",
|
||||
[StateData#state.socket, U, AuthModule,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[true, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"success">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
@ -754,10 +767,13 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||
fsm_next_state(wait_for_sasl_response,
|
||||
StateData#state{sasl_state = NewSASLState});
|
||||
{error, Error, Username} ->
|
||||
IP = peerip(StateData#state.sockmod, StateData#state.socket),
|
||||
?INFO_MSG("(~w) Failed authentication for ~s@~s from IP ~s",
|
||||
[StateData#state.socket,
|
||||
Username, StateData#state.server, jlib:ip_to_list(IP)]),
|
||||
?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s",
|
||||
[StateData#state.socket,
|
||||
Username, StateData#state.server,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, Username, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"failure">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
@ -878,8 +894,12 @@ wait_for_sasl_response({xmlstreamelement, El},
|
||||
% AuthModule = xml:get_attr_s(auth_module, Props),
|
||||
AuthModule = proplists:get_value(auth_module, Props, <<>>),
|
||||
?INFO_MSG("(~w) Accepted authentication for ~s "
|
||||
"by ~p",
|
||||
[StateData#state.socket, U, AuthModule]),
|
||||
"by ~p from ~s",
|
||||
[StateData#state.socket, U, AuthModule,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[true, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"success">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
@ -897,8 +917,12 @@ wait_for_sasl_response({xmlstreamelement, El},
|
||||
% AuthModule = xml:get_attr_s(auth_module, Props),
|
||||
AuthModule = proplists:get_value(auth_module, Props, undefined),
|
||||
?INFO_MSG("(~w) Accepted authentication for ~s "
|
||||
"by ~p",
|
||||
[StateData#state.socket, U, AuthModule]),
|
||||
"by ~p from ~s",
|
||||
[StateData#state.socket, U, AuthModule,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[true, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"success">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
@ -921,10 +945,13 @@ wait_for_sasl_response({xmlstreamelement, El},
|
||||
fsm_next_state(wait_for_sasl_response,
|
||||
StateData#state{sasl_state = NewSASLState});
|
||||
{error, Error, Username} ->
|
||||
IP = peerip(StateData#state.sockmod, StateData#state.socket),
|
||||
?INFO_MSG("(~w) Failed authentication for ~s@~s from IP ~s",
|
||||
[StateData#state.socket,
|
||||
Username, StateData#state.server, jlib:ip_to_list(IP)]),
|
||||
?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s",
|
||||
[StateData#state.socket,
|
||||
Username, StateData#state.server,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, Username, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"failure">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
|
55
src/mod_fail2ban.erl
Normal file
55
src/mod_fail2ban.erl
Normal file
@ -0,0 +1,55 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% @copyright (C) 2014, Evgeny Khramtsov
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 15 Aug 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(mod_fail2ban).
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
%% API
|
||||
-export([start/2, stop/1, c2s_auth_result/4]).
|
||||
|
||||
-include("jlib.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
start(Host, _Opts) ->
|
||||
ets:new(failed_auth, [bag, named_table, public]),
|
||||
ejabberd_hooks:add(c2s_auth_result, Host, ?MODULE, c2s_auth_result, 100).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(c2s_auth_result, Host, ?MODULE, c2s_auth_result, 100).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
c2s_auth_result(true, User, Server, {Addr, _Port}) ->
|
||||
case jlib:make_jid(User, Server, <<"">>) of
|
||||
#jid{luser = LUser, lserver = LServer} ->
|
||||
US = {LUser, LServer},
|
||||
Objs = ets:lookup(failed_auth, Addr),
|
||||
case lists:filter(fun({_, US1, _}) -> US1 == US end, Objs) of
|
||||
[_|_] ->
|
||||
ets:match_delete(failed_auth, {'_', US, '_'});
|
||||
[] ->
|
||||
true
|
||||
end;
|
||||
_ ->
|
||||
false
|
||||
end;
|
||||
c2s_auth_result(false, User, Server, {Addr, _Port}) ->
|
||||
case jlib:make_jid(User, Server, <<"">>) of
|
||||
#jid{luser = LUser, lserver = LServer} ->
|
||||
US = {LUser, LServer},
|
||||
ets:insert(failed_auth, {Addr, US, now()}),
|
||||
Objs = ets:match_object(failed_auth, {'_', US, '_'}),
|
||||
Timeout = round(math:exp(length(Objs))),
|
||||
timer:sleep(timer:seconds(Timeout));
|
||||
_ ->
|
||||
ok
|
||||
end.
|
Loading…
Reference in New Issue
Block a user