mirror of
https://github.com/pavel-odintsov/fastnetmon
synced 2024-11-26 09:03:49 +01:00
Introduced detailed attack reporting logic
This commit is contained in:
parent
a427d8b6f0
commit
a813f7da83
@ -2475,3 +2475,39 @@ void print_simple_packet_buffer_to_string(const boost::circular_buffer<simple_pa
|
||||
}
|
||||
|
||||
|
||||
// Write circular buffer with simple packets to json document
|
||||
bool write_simple_packet_as_separate_fields_dump_to_json(const boost::circular_buffer<simple_packet_t>& simple_packets_buffer,
|
||||
nlohmann::json& packet_array) {
|
||||
extern log4cpp::Category& logger;
|
||||
|
||||
// Even if we have no data we need empty array here
|
||||
packet_array = nlohmann::json::array();
|
||||
|
||||
try {
|
||||
|
||||
if (simple_packets_buffer.size() == 0) {
|
||||
logger << log4cpp::Priority::INFO << "Packet buffer is blank";
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add all pack descriptions as strings array
|
||||
for (const simple_packet_t& packet : simple_packets_buffer) {
|
||||
nlohmann::json json_packet;
|
||||
|
||||
if (!serialize_simple_packet_to_json(packet, json_packet)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Append to document as normal STL container
|
||||
packet_array.push_back(json_packet);
|
||||
}
|
||||
|
||||
} catch (...) {
|
||||
logger << log4cpp::Priority::ERROR << "Cannot create packet list in JSON";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -171,3 +171,5 @@ bool read_ipv6_subnet_from_string(subnet_ipv6_cidr_mask_t& ipv6_address, const s
|
||||
bool subnet_belongs_to_patricia_tree(patricia_tree_t* patricia_tree, const subnet_cidr_mask_t& subnet);
|
||||
// Prepares textual dump of simple packets buffer
|
||||
void print_simple_packet_buffer_to_string(const boost::circular_buffer<simple_packet_t>& simple_packets_buffer, std::string& output);
|
||||
bool write_simple_packet_as_separate_fields_dump_to_json(const boost::circular_buffer<simple_packet_t>& simple_packets_buffer,
|
||||
nlohmann::json& packet_array);
|
||||
|
@ -256,6 +256,9 @@ std::vector<flow_spec_rule_t> static_flowspec_based_whitelist;
|
||||
std::string graphite_thread_execution_time_desc = "Time consumed by pushing data to Graphite";
|
||||
struct timeval graphite_thread_execution_time;
|
||||
|
||||
// Run stats thread
|
||||
bool usage_stats = true;
|
||||
|
||||
void init_global_ban_settings() {
|
||||
// ban Configuration params
|
||||
global_ban_settings.enable_ban_for_pps = false;
|
||||
@ -2052,9 +2055,6 @@ int main(int argc, char** argv) {
|
||||
set_boost_process_name(inaccurate_time_generator_thread, "fast_time");
|
||||
service_thread_group.add_thread(inaccurate_time_generator_thread);
|
||||
|
||||
// Run stats thread
|
||||
bool usage_stats = true;
|
||||
|
||||
if (configuration_map.count("disable_usage_report") != 0 && configuration_map["disable_usage_report"] == "on") {
|
||||
usage_stats = false;
|
||||
}
|
||||
|
@ -1011,7 +1011,8 @@ std::string get_attack_description_in_json_for_web_hooks(uint32_t client_ip,
|
||||
const subnet_ipv6_cidr_mask_t& client_ipv6,
|
||||
bool ipv6,
|
||||
const std::string& action_type,
|
||||
const attack_details_t& current_attack) {
|
||||
const attack_details_t& current_attack,
|
||||
const boost::circular_buffer<simple_packet_t>& simple_packets_buffer) {
|
||||
nlohmann::json callback_info;
|
||||
|
||||
callback_info["alert_scope"] = "host";
|
||||
@ -1034,6 +1035,18 @@ std::string get_attack_description_in_json_for_web_hooks(uint32_t client_ip,
|
||||
logger << log4cpp::Priority::ERROR << "Cannot generate attack details for get_attack_description_in_json_for_web_hooks";
|
||||
}
|
||||
|
||||
// We add these sections only if we have anything in packet dump
|
||||
if (simple_packets_buffer.size() != 0) {
|
||||
// Detailed per field packet dump
|
||||
nlohmann::json packet_dump_per_field;
|
||||
|
||||
if (write_simple_packet_as_separate_fields_dump_to_json(simple_packets_buffer, packet_dump_per_field)) {
|
||||
callback_info["packet_dump_detailed"] = packet_dump_per_field;
|
||||
} else {
|
||||
logger << log4cpp::Priority::ERROR << "Cannot generate detailed packet dump";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string json_as_text = callback_info.dump();
|
||||
|
||||
@ -1197,6 +1210,8 @@ void call_blackhole_actions_per_host(attack_action_t attack_action,
|
||||
const boost::circular_buffer<simple_packet_t>& simple_packets_buffer,
|
||||
const boost::circular_buffer<fixed_size_packet_storage_t>& raw_packets_buffer) {
|
||||
|
||||
extern bool usage_stats;
|
||||
|
||||
bool ipv4 = !ipv6;
|
||||
std::string client_ip_as_string = "";
|
||||
|
||||
@ -1218,7 +1233,7 @@ void call_blackhole_actions_per_host(attack_action_t attack_action,
|
||||
print_simple_packet_buffer_to_string(simple_packets_buffer, simple_packets_dump);
|
||||
|
||||
std::string basic_attack_information_in_json =
|
||||
get_attack_description_in_json_for_web_hooks(client_ip, subnet_ipv6_cidr_mask_t{}, false, action_name, current_attack);
|
||||
get_attack_description_in_json_for_web_hooks(client_ip, subnet_ipv6_cidr_mask_t{}, false, action_name, current_attack, simple_packets_buffer);
|
||||
|
||||
bool store_attack_details_to_file = true;
|
||||
|
||||
@ -1337,6 +1352,11 @@ void call_blackhole_actions_per_host(attack_action_t attack_action,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (usage_stats) {
|
||||
boost::thread attack_report_thread(send_attack_data_to_reporting_server, basic_attack_information_in_json);
|
||||
attack_report_thread.detach();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3173,6 +3193,7 @@ void send_usage_data_to_reporting_server() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void collect_stats() {
|
||||
extern unsigned int stats_thread_initial_call_delay;
|
||||
extern unsigned int stats_thread_sleep_time;
|
||||
@ -3451,3 +3472,42 @@ std::string get_human_readable_attack_detection_direction(attack_detection_direc
|
||||
}
|
||||
}
|
||||
|
||||
// Sends attack information to reporting server
|
||||
void send_attack_data_to_reporting_server(const std::string& attack_json_string) {
|
||||
extern std::string reporting_server;
|
||||
|
||||
// Build query
|
||||
std::stringstream request_stream;
|
||||
|
||||
request_stream << "https://" << reporting_server << "/attacks_v1";
|
||||
|
||||
uint32_t response_code = 0;
|
||||
std::string response_body;
|
||||
std::string error_text;
|
||||
|
||||
std::map<std::string, std::string> headers;
|
||||
|
||||
// I think we need to do it to make clear about format for remote app
|
||||
headers["Content-Type"] = "application/json";
|
||||
|
||||
// Just do it to know about DNS issues, execute_web_request can do DNS resolution on it's own
|
||||
std::string reporting_server_ip_address = dns_lookup(reporting_server);
|
||||
|
||||
if (reporting_server_ip_address.empty()) {
|
||||
logger << log4cpp::Priority::DEBUG << "Stats server resolver failed, please check your DNS";
|
||||
return;
|
||||
}
|
||||
|
||||
bool result = execute_web_request_secure(request_stream.str(), "post", attack_json_string, response_code,
|
||||
response_body, headers, error_text);
|
||||
|
||||
if (!result) {
|
||||
logger << log4cpp::Priority::DEBUG << "Can't collect attack stats data";
|
||||
return;
|
||||
}
|
||||
|
||||
if (response_code != 200) {
|
||||
logger << log4cpp::Priority::DEBUG << "Got code " << response_code << " from stats server instead of 200";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -106,3 +106,4 @@ void inaccurate_time_generator();
|
||||
void collect_stats();
|
||||
void start_prometheus_web_server();
|
||||
std::string get_human_readable_attack_detection_direction(attack_detection_direction_type_t attack_detection_direction);
|
||||
void send_attack_data_to_reporting_server(const std::string& attack_json_string);
|
||||
|
Loading…
Reference in New Issue
Block a user