From 4b365bc901c8c6172c5497de367e0801e92b10fe Mon Sep 17 00:00:00 2001 From: Pavel Odintsov Date: Sun, 6 Dec 2020 16:54:32 +0000 Subject: [PATCH] Movex ExaBGP into separate module (#896) --- src/CMakeLists.txt | 6 +- src/actions/exabgp_action.cpp | 104 ++++++++++++++++++++++++++++++++++ src/actions/exabgp_action.hpp | 5 ++ src/bgp_protocol.cpp | 5 -- src/bgp_protocol.hpp | 2 - src/fastnetmon_logic.cpp | 95 +------------------------------ src/fastnetmon_logic.hpp | 1 - 7 files changed, 117 insertions(+), 101 deletions(-) create mode 100644 src/actions/exabgp_action.cpp create mode 100644 src/actions/exabgp_action.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 34621de6..bbfd774d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -304,6 +304,8 @@ if (ENABLE_PF_RING_SUPPORT) target_link_libraries(pfring_plugin ${CMAKE_THREAD_LIBS_INIT}) endif() +add_library(exabgp_action STATIC actions/exabgp_action.cpp) + if (ENABLE_GOBGP_SUPPORT) set(PROTOCOL_BUFFERS_CUSTOM_INSTALL_PATH "${FASTNETMON_LIBRARIES_GLOBAL_PATH}/protobuf_3.11.4") @@ -601,7 +603,7 @@ target_link_libraries(fastnetmon fastnetmon_pcap_format) target_link_libraries(fastnetmon ipfix_rfc) -target_link_libraries(fastnetmon_logic bgp_protocol fast_dpi) +target_link_libraries(fastnetmon_logic bgp_protocol fast_dpi exabgp_action) # Link to our functions target_link_libraries(fastnetmon fast_library) @@ -620,6 +622,8 @@ if (ENABLE_GOBGP_SUPPORT) target_link_libraries(fastnetmon gobgp_action) endif() +target_link_libraries(fastnetmon exabgp_action) + if (ENABLE_AFPACKET_SUPPORT) target_link_libraries(fastnetmon afpacket_plugin) endif() diff --git a/src/actions/exabgp_action.cpp b/src/actions/exabgp_action.cpp new file mode 100644 index 00000000..11bd0698 --- /dev/null +++ b/src/actions/exabgp_action.cpp @@ -0,0 +1,104 @@ +#include "exabgp_action.hpp" + +#include + +#include "../fast_library.h" + +#include "../all_logcpp_libraries.h" + +extern bool exabgp_enabled; +extern std::string exabgp_community; +extern std::string exabgp_community_subnet; +extern std::string exabgp_community_host; +extern std::string exabgp_command_pipe; +extern std::string exabgp_next_hop; +extern bool exabgp_announce_host; +extern bool exabgp_flow_spec_announces; +extern bool exabgp_announce_whole_subnet; + +extern log4cpp::Category& logger; + +// Low level ExaBGP ban management +void exabgp_prefix_ban_manage(std::string action, + std::string prefix_as_string_with_mask, + std::string exabgp_next_hop, + std::string exabgp_community) { + + /* Buffer for BGP message */ + char bgp_message[256]; + + if (action == "ban") { + sprintf(bgp_message, "announce route %s next-hop %s community %s\n", + prefix_as_string_with_mask.c_str(), exabgp_next_hop.c_str(), exabgp_community.c_str()); + } else { + sprintf(bgp_message, "withdraw route %s next-hop %s\n", prefix_as_string_with_mask.c_str(), + exabgp_next_hop.c_str()); + } + + logger << log4cpp::Priority::INFO << "ExaBGP announce message: " << bgp_message; + + int exabgp_pipe = open(exabgp_command_pipe.c_str(), O_WRONLY); + + if (exabgp_pipe <= 0) { + logger << log4cpp::Priority::ERROR << "Can't open ExaBGP pipe " << exabgp_command_pipe + << " Ban is not executed"; + return; + } + + int wrote_bytes = write(exabgp_pipe, bgp_message, strlen(bgp_message)); + + if (wrote_bytes != strlen(bgp_message)) { + logger << log4cpp::Priority::ERROR << "Can't write message to ExaBGP pipe"; + } + + close(exabgp_pipe); +} + +void exabgp_ban_manage(std::string action, std::string ip_as_string, attack_details_t current_attack) { + // We will announce whole subent here + if (exabgp_announce_whole_subnet) { + std::string subnet_as_string_with_mask = convert_subnet_to_string(current_attack.customer_network); + + exabgp_prefix_ban_manage(action, subnet_as_string_with_mask, exabgp_next_hop, exabgp_community_subnet); + } + + // And we could announce single host here (/32) + if (exabgp_announce_host) { + std::string ip_as_string_with_mask = ip_as_string + "/32"; + + exabgp_prefix_ban_manage(action, ip_as_string_with_mask, exabgp_next_hop, exabgp_community_host); + } +} + + +bool exabgp_flow_spec_ban_manage(std::string action, std::string flow_spec_rule_as_text) { + std::string announce_action; + + if (action == "ban") { + announce_action = "announce"; + } else { + announce_action = "withdraw"; + } + + // Trailing \n is very important! + std::string bgp_message = announce_action + " " + flow_spec_rule_as_text + "\n"; + + int exabgp_pipe = open(exabgp_command_pipe.c_str(), O_WRONLY); + + if (exabgp_pipe <= 0) { + logger << log4cpp::Priority::ERROR << "Can't open ExaBGP pipe for flow spec announce " << exabgp_command_pipe; + return false; + } + + int wrote_bytes = write(exabgp_pipe, bgp_message.c_str(), bgp_message.size()); + + if (wrote_bytes != bgp_message.size()) { + logger << log4cpp::Priority::ERROR << "Can't write message to ExaBGP pipe"; + return false; + } + + close(exabgp_pipe); + return true; +} + + diff --git a/src/actions/exabgp_action.hpp b/src/actions/exabgp_action.hpp new file mode 100644 index 00000000..33d24f45 --- /dev/null +++ b/src/actions/exabgp_action.hpp @@ -0,0 +1,5 @@ +#include +#include "../fastnetmon_types.h" + +void exabgp_ban_manage(std::string action, std::string ip_as_string, attack_details_t current_attack); +bool exabgp_flow_spec_ban_manage(std::string action, std::string flow_spec_rule_as_text); diff --git a/src/bgp_protocol.cpp b/src/bgp_protocol.cpp index a027fc84..e171a773 100644 --- a/src/bgp_protocol.cpp +++ b/src/bgp_protocol.cpp @@ -27,11 +27,6 @@ std::ostream& operator<<(std::ostream& os, bgp_flow_spec_protocol_t const& proto } } -void exabgp_flow_spec_rule_ban_manage(std::string action, flow_spec_rule_t flow_spec_rule) { - // "announce flow route {\\n match {\\n source 10.0.0.1/32;\\nsource-port =" + str(i) + - // ";\\n destination 1.2.3.4/32;\\n }\\n then {\\n discard;\\n }\\n }\\n\n") -} - std::ostream& operator<<(std::ostream& os, flow_spec_tcp_flags_t const& tcp_flag) { if (tcp_flag == FLOW_TCP_FLAG_SYN) { return os << "syn"; diff --git a/src/bgp_protocol.hpp b/src/bgp_protocol.hpp index 20299c15..5c6f8668 100644 --- a/src/bgp_protocol.hpp +++ b/src/bgp_protocol.hpp @@ -538,7 +538,5 @@ class exabgp_flow_spec_rule_t : public flow_spec_rule_t { std::string sentence_separator; }; -void exabgp_flow_spec_rule_ban_manage(std::string action, flow_spec_rule_t flow_spec_rule); - bool read_bgp_community_from_string(std::string community_as_string, bgp_community_attribute_element_t& bgp_community_attribute_element); bool is_bgp_community_valid(std::string community_as_string); diff --git a/src/fastnetmon_logic.cpp b/src/fastnetmon_logic.cpp index 01031ab8..b4405688 100644 --- a/src/fastnetmon_logic.cpp +++ b/src/fastnetmon_logic.cpp @@ -32,6 +32,8 @@ #include "actions/gobgp_action.h" #endif +#include "actions/exabgp_action.hpp" + // Yes, maybe it's not an good idea but with this we can guarantee working code in example plugin #include "example_plugin/example_collector.h" @@ -142,12 +144,6 @@ extern map_for_subnet_counters_t PerSubnetAverageSpeedMap; extern bool enable_subnet_counters; extern ban_settings_t global_ban_settings; extern bool exabgp_enabled; -extern std::string exabgp_community; -extern std::string exabgp_community_subnet; -extern std::string exabgp_community_host; -extern std::string exabgp_command_pipe; -extern std::string exabgp_next_hop; -extern bool exabgp_announce_host; extern bool exabgp_flow_spec_announces; extern bool gobgp_enabled; extern map_of_vector_counters_t SubnetVectorMapSpeedAverage; @@ -1334,7 +1330,7 @@ void launch_bgp_flow_spec_rule(amplification_attack_type_t attack_type, std::str } } else { // We have already blocked this attack - logger << log4cpp::Priority::INFO << "The same rule was already sent to ExaBGP formerly"; + logger << log4cpp::Priority::INFO << "The same rule was already sent to ExaBGP previously"; } } else { logger << log4cpp::Priority::INFO << "exabgp_flow_spec_announces disabled. We will not talk to ExaBGP"; @@ -1676,91 +1672,6 @@ ban_settings_t get_ban_settings_for_this_subnet(subnet_cidr_mask_t subnet, std:: return hostgroup_settings_itr->second; } - -void exabgp_ban_manage(std::string action, std::string ip_as_string, attack_details_t current_attack) { - // We will announce whole subent here - if (exabgp_announce_whole_subnet) { - std::string subnet_as_string_with_mask = convert_subnet_to_string(current_attack.customer_network); - - exabgp_prefix_ban_manage(action, subnet_as_string_with_mask, exabgp_next_hop, exabgp_community_subnet); - } - - // And we could announce single host here (/32) - if (exabgp_announce_host) { - std::string ip_as_string_with_mask = ip_as_string + "/32"; - - exabgp_prefix_ban_manage(action, ip_as_string_with_mask, exabgp_next_hop, exabgp_community_host); - } -} - - -// Low level ExaBGP ban management -void exabgp_prefix_ban_manage(std::string action, - std::string prefix_as_string_with_mask, - std::string exabgp_next_hop, - std::string exabgp_community) { - - /* Buffer for BGP message */ - char bgp_message[256]; - - if (action == "ban") { - sprintf(bgp_message, "announce route %s next-hop %s community %s\n", - prefix_as_string_with_mask.c_str(), exabgp_next_hop.c_str(), exabgp_community.c_str()); - } else { - sprintf(bgp_message, "withdraw route %s next-hop %s\n", prefix_as_string_with_mask.c_str(), - exabgp_next_hop.c_str()); - } - - logger << log4cpp::Priority::INFO << "ExaBGP announce message: " << bgp_message; - - int exabgp_pipe = open(exabgp_command_pipe.c_str(), O_WRONLY); - - if (exabgp_pipe <= 0) { - logger << log4cpp::Priority::ERROR << "Can't open ExaBGP pipe " << exabgp_command_pipe - << " Ban is not executed"; - return; - } - - int wrote_bytes = write(exabgp_pipe, bgp_message, strlen(bgp_message)); - - if (wrote_bytes != strlen(bgp_message)) { - logger << log4cpp::Priority::ERROR << "Can't write message to ExaBGP pipe"; - } - - close(exabgp_pipe); -} - -bool exabgp_flow_spec_ban_manage(std::string action, std::string flow_spec_rule_as_text) { - std::string announce_action; - - if (action == "ban") { - announce_action = "announce"; - } else { - announce_action = "withdraw"; - } - - // Trailing \n is very important! - std::string bgp_message = announce_action + " " + flow_spec_rule_as_text + "\n"; - - int exabgp_pipe = open(exabgp_command_pipe.c_str(), O_WRONLY); - - if (exabgp_pipe <= 0) { - logger << log4cpp::Priority::ERROR << "Can't open ExaBGP pipe for flow spec announce " << exabgp_command_pipe; - return false; - } - - int wrote_bytes = write(exabgp_pipe, bgp_message.c_str(), bgp_message.size()); - - if (wrote_bytes != bgp_message.size()) { - logger << log4cpp::Priority::ERROR << "Can't write message to ExaBGP pipe"; - return false; - } - - close(exabgp_pipe); - return true; -} - - #ifdef REDIS void store_data_in_redis(std::string key_name, std::string attack_details) { redisReply* reply = NULL; diff --git a/src/fastnetmon_logic.hpp b/src/fastnetmon_logic.hpp index 040d4c49..4351705e 100644 --- a/src/fastnetmon_logic.hpp +++ b/src/fastnetmon_logic.hpp @@ -88,7 +88,6 @@ uint64_t convert_conntrack_hash_struct_to_integer(packed_conntrack_hash_t* struc bool process_flow_tracking_table(conntrack_main_struct_t& conntrack_element, std::string client_ip); bool exec_with_stdin_params(std::string cmd, std::string params); ban_settings_t get_ban_settings_for_this_subnet(subnet_cidr_mask_t subnet, std::string& host_group_name); -void exabgp_ban_manage(std::string action, std::string ip_as_string, attack_details_t current_attack); void exabgp_prefix_ban_manage(std::string action, std::string prefix_as_string_with_mask, std::string exabgp_next_hop,