diff --git a/.gitignore b/.gitignore index 0d18f04..682f224 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ example -exec \ No newline at end of file +exec +test/*.o \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 05054c5..28e311b 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,9 +7,11 @@ "args": [ "-fdiagnostics-color=always", "-g", - "${file}", + "${fileDirname}/test.cpp", + "${fileDirname}/../src/*.cpp", + "${fileDirname}/../exec/src/*.cpp", "-o", - "${fileDirname}/${fileBasenameNoExtension}" + "${fileDirname}/test.o" ], "options": { "cwd": "${fileDirname}" diff --git a/lib/ipban.hpp b/lib/ipban.hpp index fca01ad..65e1a45 100644 --- a/lib/ipban.hpp +++ b/lib/ipban.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -29,16 +30,27 @@ struct _ban { 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 * Automatski uklanja zabranu po isteku vremena * Posjeduje vlastiti DB mehanizam za zaštitu od nepovratnog ban-a */ class ipban { - mutex io; + mutex io, f_io; time_t ban_duration; + uint fail_interval; + uint fail_limit; string db_file; vector<_ban> banned; + map failed; future unban_bot; bool run_unban_bot = true; // interface možda bude trebao za ban @@ -71,10 +83,11 @@ class ipban { 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 */ - 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 @@ -82,6 +95,19 @@ class ipban { */ 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. */ diff --git a/src/ipban.cpp b/src/ipban.cpp index ff745c8..113f62d 100644 --- a/src/ipban.cpp +++ b/src/ipban.cpp @@ -1,7 +1,9 @@ #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; + fail_interval = _fail_interval*60; + fail_limit = _fail_limit; db_file = _db_file; load_db(); @@ -13,6 +15,15 @@ marcelb::ipban::ipban(const uint& _duration, const string& _db_file) { 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; }); @@ -106,6 +117,25 @@ bool marcelb::ipban::ufw_unban(const string& ip) { return false; } + +void marcelb::ipban::fail(const string& ip) { + lock_guard _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 _io(f_io); + return failed.erase(ip);; +} + + static void marcelb::sleep_if(const uint& _time, const bool& _condition) { time_t start_time = time(NULL); do { diff --git a/test/ipban.db b/test/ipban.db index e150c3a..e69de29 100644 --- a/test/ipban.db +++ b/test/ipban.db @@ -1 +0,0 @@ -90.163.88.49-1702323353 diff --git a/test/test b/test/test index 885e984..16cd707 100755 Binary files a/test/test and b/test/test differ diff --git a/test/test.cpp b/test/test.cpp index 7ff08f9..05e3be0 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -23,15 +23,32 @@ int main() { ipban myban(1); // myban.ban("192.168.2.74"); // sleep(300); - uint i=0; - - while (i<10) { - string ip = generateRandomIP(); - cout << "Ban " << ip << endl; - myban.ban(ip); - sleep(30); - i++; - } + // uint i=0; + + // while (i<10) { + // string ip = generateRandomIP(); + // cout << "Ban " << ip << endl; + // myban.ban(ip); + // sleep(30); + // 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; } \ No newline at end of file