mirror of
https://github.com/znc/znc.git
synced 2026-08-07 01:13:25 +02:00
Merge pull request #992 from jpnurmi/fail2ban
fail2ban: configurability & commands
This commit is contained in:
@@ -334,6 +334,18 @@ public:
|
||||
m_mItems.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns all entries
|
||||
*/
|
||||
std::map<K,V> GetItems() {
|
||||
Cleanup();
|
||||
std::map<K,V> mItems;
|
||||
for (const auto& it : m_mItems) {
|
||||
mItems[it.first] = it.second.second;
|
||||
}
|
||||
return mItems;
|
||||
}
|
||||
|
||||
// Setters
|
||||
void SetTTL(unsigned int u) { m_uTTL = u; }
|
||||
// !Setters
|
||||
|
||||
+99
-5
@@ -18,7 +18,14 @@
|
||||
|
||||
class CFailToBanMod : public CModule {
|
||||
public:
|
||||
MODCONSTRUCTOR(CFailToBanMod) {}
|
||||
MODCONSTRUCTOR(CFailToBanMod) {
|
||||
AddHelpCommand();
|
||||
AddCommand("Timeout", static_cast<CModCommand::ModCmdFunc>(&CFailToBanMod::OnTimeoutCommand), "(<minutes>)", "The number of minutes IPs are blocked after a failed login.");
|
||||
AddCommand("Attempts", static_cast<CModCommand::ModCmdFunc>(&CFailToBanMod::OnAttemptsCommand), "(<count>)", "The number of allowed failed login attempts.");
|
||||
AddCommand("Ban", static_cast<CModCommand::ModCmdFunc>(&CFailToBanMod::OnBanCommand), "<hosts>", "Ban the specified hosts.");
|
||||
AddCommand("Unban", static_cast<CModCommand::ModCmdFunc>(&CFailToBanMod::OnUnbanCommand), "<hosts>", "Unban the specified hosts.");
|
||||
AddCommand("List", static_cast<CModCommand::ModCmdFunc>(&CFailToBanMod::OnListCommand), "", "List banned hosts.");
|
||||
}
|
||||
virtual ~CFailToBanMod() {}
|
||||
|
||||
bool OnLoad(const CString& sArgs, CString& sMessage) override {
|
||||
@@ -54,10 +61,97 @@ public:
|
||||
m_Cache.AddItem(sHost, count, m_Cache.GetTTL());
|
||||
}
|
||||
|
||||
void OnModCommand(const CString& sCommand) override {
|
||||
PutModule("This module can only be configured through its arguments.");
|
||||
PutModule("The module argument is the number of minutes an IP");
|
||||
PutModule("is blocked after a failed login.");
|
||||
bool Remove(const CString& sHost) {
|
||||
return m_Cache.RemItem(sHost);
|
||||
}
|
||||
|
||||
void OnTimeoutCommand(const CString& sCommand) {
|
||||
CString sArg = sCommand.Token(1);
|
||||
|
||||
if (!sArg.empty()) {
|
||||
unsigned int uTimeout = sArg.ToUInt();
|
||||
if (uTimeout == 0) {
|
||||
PutModule("Usage: Timeout (<minutes>)");
|
||||
} else {
|
||||
m_Cache.SetTTL(uTimeout * 60 * 1000);
|
||||
PutModule("Timeout: " + CString(uTimeout) + " min");
|
||||
}
|
||||
} else {
|
||||
PutModule("Timeout: " + CString(m_Cache.GetTTL() / 60 / 1000) + " min");
|
||||
}
|
||||
}
|
||||
|
||||
void OnAttemptsCommand(const CString& sCommand) {
|
||||
CString sArg = sCommand.Token(1);
|
||||
|
||||
if (!sArg.empty()) {
|
||||
unsigned int uiAttempts = sArg.ToUInt();
|
||||
if (uiAttempts == 0) {
|
||||
PutModule("Usage: Attempts (<count>)");
|
||||
} else {
|
||||
m_uiAllowedFailed = uiAttempts;
|
||||
PutModule("Attempts: " + CString(uiAttempts));
|
||||
}
|
||||
} else {
|
||||
PutModule("Attempts: " + CString(m_uiAllowedFailed));
|
||||
}
|
||||
}
|
||||
|
||||
void OnBanCommand(const CString& sCommand) {
|
||||
CString sHosts = sCommand.Token(1, true);
|
||||
|
||||
if (sHosts.empty()) {
|
||||
PutStatus("Usage: Ban <hosts>");
|
||||
return;
|
||||
}
|
||||
|
||||
VCString vsHosts;
|
||||
sHosts.Replace(",", " ");
|
||||
sHosts.Split(" ", vsHosts, false, "", "", true, true);
|
||||
|
||||
for (const CString& sHost : vsHosts) {
|
||||
Add(sHost, 0);
|
||||
PutModule("Banned: " + sHost);
|
||||
}
|
||||
}
|
||||
|
||||
void OnUnbanCommand(const CString& sCommand) {
|
||||
CString sHosts = sCommand.Token(1, true);
|
||||
|
||||
if (sHosts.empty()) {
|
||||
PutStatus("Usage: Unban <hosts>");
|
||||
return;
|
||||
}
|
||||
|
||||
VCString vsHosts;
|
||||
sHosts.Replace(",", " ");
|
||||
sHosts.Split(" ", vsHosts, false, "", "", true, true);
|
||||
|
||||
for (const CString& sHost : vsHosts) {
|
||||
if (Remove(sHost)) {
|
||||
PutModule("Unbanned: " + sHost);
|
||||
} else {
|
||||
PutModule("Ignored: " + sHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnListCommand(const CString& sCommand) {
|
||||
CTable Table;
|
||||
Table.AddColumn("Host");
|
||||
Table.AddColumn("Attempts");
|
||||
|
||||
for (const auto& it : m_Cache.GetItems()) {
|
||||
Table.AddRow();
|
||||
Table.SetCell("Host", it.first);
|
||||
Table.SetCell("Attempts", CString(it.second));
|
||||
}
|
||||
|
||||
if (Table.empty()) {
|
||||
PutModule("No bans");
|
||||
} else {
|
||||
PutModule(Table);
|
||||
}
|
||||
}
|
||||
|
||||
void OnClientConnect(CZNCSock* pClient, const CString& sHost, unsigned short uPort) override {
|
||||
|
||||
Reference in New Issue
Block a user