mirror of
https://github.com/znc/znc.git
synced 2026-05-09 06:44:40 +02:00
fail2ban: Add number of allowed failed logins
This adds a new, second argument to fail2ban which is the number of failed logins one is allowed before being banned. Each login attempt resets the timeout. This value defaults to 2. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1489 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
+28
-9
@@ -14,13 +14,21 @@ public:
|
||||
virtual ~CFailToBanMod() {}
|
||||
|
||||
virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
|
||||
unsigned int timeout = sArgs.ToUInt();
|
||||
CString sTimeout = sArgs.Token(0);
|
||||
CString sAttempts = sArgs.Token(1);
|
||||
unsigned int timeout = sTimeout.ToUInt();
|
||||
|
||||
if (sAttempts.empty())
|
||||
m_uiAllowedFailed = 2;
|
||||
else
|
||||
m_uiAllowedFailed = sAttempts.ToUInt();;
|
||||
|
||||
if (sArgs.empty()) {
|
||||
timeout = 1;
|
||||
} else if (timeout == 0 && sArgs != "0") {
|
||||
} else if (timeout == 0 || m_uiAllowedFailed == 0 || !sArgs.Token(2, true).empty()) {
|
||||
sMessage = "Invalid argument, must be the number of minutes "
|
||||
"IPs are blocked after a failed login";
|
||||
"IPs are blocked after a failed login and can be "
|
||||
"followed by number of allowed failed login attempts";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -30,6 +38,10 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void Add(const CString& sHost, unsigned int count) {
|
||||
m_Cache.AddItem(sHost, count, m_Cache.GetTTL());
|
||||
}
|
||||
|
||||
virtual void OnModCommand(const CString& sCommand) {
|
||||
PutModule("This module can only be configured through its arguments.");
|
||||
PutModule("The module argument is the number of minutes an IP");
|
||||
@@ -37,19 +49,24 @@ public:
|
||||
}
|
||||
|
||||
virtual void OnClientConnect(CClient* pClient, const CString& sHost, unsigned short uPort) {
|
||||
if (sHost.empty() || !m_Cache.HasItem(sHost)) {
|
||||
unsigned int *pCount = m_Cache.GetItem(sHost);
|
||||
if (sHost.empty() || pCount == NULL || *pCount < m_uiAllowedFailed) {
|
||||
return;
|
||||
}
|
||||
|
||||
// refresh their ban
|
||||
m_Cache.AddItem(sHost);
|
||||
Add(sHost, *pCount);
|
||||
|
||||
pClient->PutClient("ERROR :Closing link [Please try again later - reconnecting too fast]");
|
||||
pClient->Close(Csock::CLT_AFTERWRITE);
|
||||
}
|
||||
|
||||
virtual void OnFailedLogin(const CString& sUsername, const CString& sRemoteIP) {
|
||||
m_Cache.AddItem(sRemoteIP);
|
||||
unsigned int *pCount = m_Cache.GetItem(sRemoteIP);
|
||||
if (pCount)
|
||||
Add(sRemoteIP, *pCount + 1);
|
||||
else
|
||||
Add(sRemoteIP, 1);
|
||||
}
|
||||
|
||||
virtual EModRet OnLoginAttempt(CSmartPtr<CAuthBase> Auth) {
|
||||
@@ -59,8 +76,9 @@ public:
|
||||
if (sRemoteIP.empty())
|
||||
return CONTINUE;
|
||||
|
||||
if (m_Cache.HasItem(sRemoteIP)) {
|
||||
// OnFailedLoginAttempt() will refresh their ban
|
||||
unsigned int *pCount = m_Cache.GetItem(sRemoteIP);
|
||||
if (pCount && *pCount >= m_uiAllowedFailed) {
|
||||
// OnFailedLogin() will refresh their ban
|
||||
Auth->RefuseLogin("Please try again later - reconnecting too fast");
|
||||
return HALT;
|
||||
}
|
||||
@@ -69,7 +87,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TCacheMap<CString> m_Cache;
|
||||
TCacheMap<CString, unsigned int> m_Cache;
|
||||
unsigned int m_uiAllowedFailed;
|
||||
};
|
||||
|
||||
GLOBALMODULEDEFS(CFailToBanMod, "Block IPs for some time after a failed login")
|
||||
|
||||
Reference in New Issue
Block a user