Movex ExaBGP into separate module (#896)

This commit is contained in:
Pavel Odintsov 2020-12-06 16:54:32 +00:00 committed by GitHub
parent a7357e3ee0
commit 4b365bc901
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 117 additions and 101 deletions

View File

@ -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()

View File

@ -0,0 +1,104 @@
#include "exabgp_action.hpp"
#include <string>
#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;
}

View File

@ -0,0 +1,5 @@
#include <string>
#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);

View File

@ -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";

View File

@ -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);

View File

@ -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;

View File

@ -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,