Add trys for fail before ban

dev v0.2
marcelb 11 months ago
parent 8b7b0435cd
commit a66b2f18f6
  1. 3
      .gitignore
  2. 6
      .vscode/tasks.json
  3. 32
      lib/ipban.hpp
  4. 32
      src/ipban.cpp
  5. 1
      test/ipban.db
  6. BIN
      test/test
  7. 35
      test/test.cpp

3
.gitignore vendored

@ -1,2 +1,3 @@
example example
exec exec
test/*.o

@ -7,9 +7,11 @@
"args": [ "args": [
"-fdiagnostics-color=always", "-fdiagnostics-color=always",
"-g", "-g",
"${file}", "${fileDirname}/test.cpp",
"${fileDirname}/../src/*.cpp",
"${fileDirname}/../exec/src/*.cpp",
"-o", "-o",
"${fileDirname}/${fileBasenameNoExtension}" "${fileDirname}/test.o"
], ],
"options": { "options": {
"cwd": "${fileDirname}" "cwd": "${fileDirname}"

@ -3,6 +3,7 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <map>
#include <string> #include <string>
#include <future> #include <future>
#include <mutex> #include <mutex>
@ -29,16 +30,27 @@ struct _ban {
time_t _time; time_t _time;
}; };
/**
* Pomoćna struktura - za praćenje broja pogrešaka
*/
struct _fail {
time_t first_fail;
uint n_fails = 0;
};
/** /**
* Biblioteka za ban IP adrese kroz UFW vatrozid na određeno vrijeme * Biblioteka za ban IP adrese kroz UFW vatrozid na određeno vrijeme
* Automatski uklanja zabranu po isteku vremena * Automatski uklanja zabranu po isteku vremena
* Posjeduje vlastiti DB mehanizam za zaštitu od nepovratnog ban-a * Posjeduje vlastiti DB mehanizam za zaštitu od nepovratnog ban-a
*/ */
class ipban { class ipban {
mutex io; mutex io, f_io;
time_t ban_duration; time_t ban_duration;
uint fail_interval;
uint fail_limit;
string db_file; string db_file;
vector<_ban> banned; vector<_ban> banned;
map<string, struct _fail> failed;
future<void> unban_bot; future<void> unban_bot;
bool run_unban_bot = true; bool run_unban_bot = true;
// interface možda bude trebao za ban // interface možda bude trebao za ban
@ -71,10 +83,11 @@ class ipban {
public: public:
/** /**
* Konstruktor, prima zadanu vrijednost trajanja ban-a u minutama * Konstruktor, prima zadanu vrijednost trajanja ban-a u minutama,
* vrijeme praćenja pogreške adrese, broj dozvoljenih pogreški
* i putanju datoteke baze podataka * i putanju datoteke baze podataka
*/ */
ipban(const uint& _duration, const string& db_file = "ipban.db"); // u minutama? ipban(const uint& _duration, const uint& _fail_interval = 30, const uint& _fail_limit = 3, const string& db_file = "ipban.db"); // u minutama?
/** /**
* Metoda koja banuje proslijeđenu IP adresu, dodaje je u vector banned, ažurira bazu * Metoda koja banuje proslijeđenu IP adresu, dodaje je u vector banned, ažurira bazu
@ -82,6 +95,19 @@ class ipban {
*/ */
bool ban(const string& ip); bool ban(const string& ip);
/**
* Inkrementalno povećaj broj grešaka za prosljeđenu adresu
* ako se prekorači broj dozvoljenih grešaka u intervalu - adresa se banuje
*/
void fail(const string& ip);
/**
* Uklanja greške za prosljeđenu adresu
*/
bool unfail(const string& ip);
/** /**
* Destruktor, uklanja sve zabrane. * Destruktor, uklanja sve zabrane.
*/ */

@ -1,7 +1,9 @@
#include "../lib/ipban.hpp" #include "../lib/ipban.hpp"
marcelb::ipban::ipban(const uint& _duration, const string& _db_file) { marcelb::ipban::ipban(const uint& _duration, const uint& _fail_interval, const uint& _fail_limit, const string& _db_file) {
ban_duration = _duration*60; ban_duration = _duration*60;
fail_interval = _fail_interval*60;
fail_limit = _fail_limit;
db_file = _db_file; db_file = _db_file;
load_db(); load_db();
@ -13,6 +15,15 @@ marcelb::ipban::ipban(const uint& _duration, const string& _db_file) {
unban(banned.begin() + i); unban(banned.begin() + i);
} }
} }
for (auto _failed = failed.begin(); _failed != failed.end(); ) {
if (difftime(time(NULL), _failed->second.first_fail) >= fail_interval && _failed != failed.end()) {
f_io.lock();
_failed = failed.erase(_failed);
f_io.unlock();
} else {
++_failed;
}
}
} }
return; return;
}); });
@ -106,6 +117,25 @@ bool marcelb::ipban::ufw_unban(const string& ip) {
return false; return false;
} }
void marcelb::ipban::fail(const string& ip) {
lock_guard<mutex> _io(f_io);
if (failed[ip].n_fails == 0) {
failed[ip].n_fails = 1;
failed[ip].first_fail = time(NULL);
} else if (++failed[ip].n_fails >= fail_limit) {
ban(ip);
failed.erase(ip);
}
}
bool marcelb::ipban::unfail(const string& ip) {
lock_guard<mutex> _io(f_io);
return failed.erase(ip);;
}
static void marcelb::sleep_if(const uint& _time, const bool& _condition) { static void marcelb::sleep_if(const uint& _time, const bool& _condition) {
time_t start_time = time(NULL); time_t start_time = time(NULL);
do { do {

@ -1 +0,0 @@
90.163.88.49-1702323353

Binary file not shown.

@ -23,15 +23,32 @@ int main() {
ipban myban(1); ipban myban(1);
// myban.ban("192.168.2.74"); // myban.ban("192.168.2.74");
// sleep(300); // sleep(300);
uint i=0; // uint i=0;
while (i<10) { // while (i<10) {
string ip = generateRandomIP(); // string ip = generateRandomIP();
cout << "Ban " << ip << endl; // cout << "Ban " << ip << endl;
myban.ban(ip); // myban.ban(ip);
sleep(30); // sleep(30);
i++; // i++;
} // }
myban.fail("192.168.2.74");
sleep(2);
myban.fail("192.168.2.74");
sleep(200);
// myban.fail("192.168.2.74");
// sleep(120);
// myban.unfail("192.168.2.74");
// sleep(2);
// myban.fail("192.168.2.74");
// sleep(120);
return 0; return 0;
} }
Loading…
Cancel
Save