Completely workiing GoBGP integration. But compilation do not enabled by default

This commit is contained in:
Pavel Odintsov 2015-10-05 12:48:48 +02:00
parent c7996393cf
commit 204b41aedc
6 changed files with 85 additions and 21 deletions

@ -44,6 +44,7 @@ Features:
- Can trigger block script if certain IP loads network with a large amount of packets/bytes/flows per second
- Thresholds could be configured in per subnet basis with hostgroups feature
- Could [announce blocked IPs](docs/EXABGP_INTEGRATION.md) to BGP router with [ExaBGP](https://github.com/Exa-Networks/exabgp)
- GoBGP integration for unicast IPv4 announces
- Full integration with [Graphite](docs/GRAPHITE_INTEGRATION.md) and [InfluxDB](docs/INFLUXDB_INTEGRATION.md)
- Redis integration
- MongoDB integration

@ -5,7 +5,7 @@ cmake_minimum_required (VERSION 2.8)
# Debian 7 - 2.8.9
# CentOS 6 - 2.8.12
### set(ENABLE_GOBGP_SUPPORT "yes")
# set(ENABLE_GOBGP_SUPPORT "yes")
# We should set compiler before project() call
if (ENABLE_BUILD_IN_CPP_11_CUSTOM_ENVIRONMENT)

@ -38,9 +38,9 @@ class GrpcClient {
gobgpapi::Destination current_destination;
std::cout << "List of announced prefixes for route family: " << route_family << std::endl << std::endl;
logger << log4cpp::Priority::INFO << "List of announced prefixes for route family: " << route_family << std::endl << std::endl;
while (destinations_list->Read(&current_destination)) {
std::cout << "Prefix: " << current_destination.prefix() << std::endl;
logger << log4cpp::Priority::INFO << "Prefix: " << current_destination.prefix() << std::endl;
//std::cout << "Paths size: " << current_destination.paths_size() << std::endl;
@ -67,13 +67,13 @@ class GrpcClient {
gobgp_lib_path.path_attributes = my_path_attributes;
std::cout << "NLRI: " << decode_path(&gobgp_lib_path) << std::endl;
logger << log4cpp::Priority::INFO << "NLRI: " << decode_path(&gobgp_lib_path) << std::endl;
}
Status status = destinations_list->Finish();
if (!status.ok()) {
// error_message
std::cout << "Problem with RPC: " << status.error_code() << " message " << status.error_message() << std::endl;
logger << log4cpp::Priority::INFO << "Problem with RPC: " << status.error_code() << " message " << status.error_message() << std::endl;
} else {
// std::cout << "RPC working well" << std::endl;
}
@ -129,7 +129,7 @@ class GrpcClient {
bool write_result = send_stream->Write(request);
if (!write_result) {
std::cout << "Write to API failed\n";
logger << log4cpp::Priority::INFO << "Write to API failed\n";
}
// Finish all writes
@ -140,12 +140,12 @@ class GrpcClient {
if (status.ok()) {
//std::cout << "modpath executed correctly" << std::cout;
} else {
std::cout << "modpath failed with code: " << status.error_code()
logger << log4cpp::Priority::INFO << "modpath failed with code: " << status.error_code()
<< " message " << status.error_message() << std::endl;
}
}
void AnnounceUnicastPrefix(std::string announced_prefix, std::string announced_prefix_nexthop) {
void AnnounceUnicastPrefix(std::string announced_prefix, std::string announced_prefix_nexthop, bool is_withdrawal) {
const gobgpapi::ModPathArguments current_mod_path_arguments;
unsigned int AFI_IP = 1;
@ -153,8 +153,10 @@ class GrpcClient {
unsigned int ipv4_unicast_route_family = AFI_IP<<16 | SAFI_UNICAST;
gobgpapi::Path* current_path = new gobgpapi::Path;
// If you want withdraw, please use it
// current_path->set_is_withdraw(true);
if (is_withdrawal) {
current_path->set_is_withdraw(true);
}
/*
buf:
@ -172,8 +174,8 @@ class GrpcClient {
path* path_c_struct = serialize_path(ipv4_unicast_route_family, (char*)announce_line.c_str());
if (path_c_struct == NULL) {
std::cerr << "Could not generate path\n";
exit(-1);
logger << log4cpp::Priority::ERROR << "Could not generate path\n";
return;
}
// printf("Decoded NLRI output: %s, length %d raw string length: %d\n", decode_path(path_c_struct), path_c_struct->nlri.len, strlen(path_c_struct->nlri.value));
@ -201,7 +203,8 @@ class GrpcClient {
bool write_result = send_stream->Write(request);
if (!write_result) {
std::cout << "Write to API failed\n";
logger << log4cpp::Priority::ERROR << "Write to API failed\n";
return;
}
// Finish all writes
@ -212,8 +215,10 @@ class GrpcClient {
if (status.ok()) {
//std::cout << "modpath executed correctly" << std::cout;
} else {
std::cout << "modpath failed with code: " << status.error_code()
<< " message " << status.error_message() << std::endl;
logger << log4cpp::Priority::ERROR << "modpath failed with code: " << status.error_code()
<< " message " << status.error_message();
return;
}
}
@ -250,10 +255,25 @@ class GrpcClient {
};
GrpcClient* gobgp_client = NULL;
std::string gobgp_nexthop = "0.0.0.0";
bool gobgp_announce_whole_subnet = false;
bool gobgp_announce_host = false;
void gobgp_action_init() {
logger << log4cpp::Priority::INFO << "GoBGP action module loaded";
gobgp_client = new GrpcClient(grpc::CreateChannel("localhost:8080", grpc::InsecureCredentials()));
if (configuration_map.count("gobgp_next_hop")) {
gobgp_nexthop = configuration_map["gobgp_next_hop"];
}
if (configuration_map.count("gobgp_announce_host")) {
gobgp_announce_host = configuration_map["gobgp_announce_host"] == "on";
}
if (configuration_map.count("gobgp_announce_whole_subnet")) {
gobgp_announce_whole_subnet = configuration_map["gobgp_announce_whole_subnet"] == "on";
}
}
void gobgp_action_shutdown() {
@ -261,7 +281,23 @@ void gobgp_action_shutdown() {
}
void gobgp_ban_manage(std::string action, std::string ip_as_string, attack_details current_attack) {
gobgp_client->AnnounceUnicastPrefix("10.10.20.33/32", "10.10.1.99");
// std::string subnet_as_string_with_mask = convert_subnet_to_string(current_attack.customer_network);
// std::string ip_as_string_with_mask = ip_as_string + "/32";
bool is_withdrawal = false;
if (action == "ban") {
is_withdrawal = false;
} else {
is_withdrawal = true;
}
if (gobgp_announce_whole_subnet) {
std::string subnet_as_string_with_mask = convert_subnet_to_string(current_attack.customer_network);
gobgp_client->AnnounceUnicastPrefix(subnet_as_string_with_mask, gobgp_nexthop, is_withdrawal);
}
if (gobgp_announce_host) {
std::string ip_as_string_with_mask = ip_as_string + "/32";
gobgp_client->AnnounceUnicastPrefix(ip_as_string_with_mask, gobgp_nexthop, is_withdrawal);
}
}

@ -232,9 +232,11 @@ exabgp_announce_whole_subnet = off
# Please use ExaBGP v4 only (Git version), for more details: https://github.com/FastVPSEestiOu/fastnetmon/blob/master/docs/BGP_FLOW_SPEC.md
exabgp_flow_spec_announces = off
# It's not net finished option, please do not use it
# GoBGP intergation
gobgp = on
gobgp = off
gobgp_next_hop = 0.0.0.0
gobgp_announce_host = on
gobgp_announce_whole_subnet = off
# Graphite monitoring
# InfluxDB is also supported, please check our reference:

@ -3121,6 +3121,18 @@ void call_ban_handlers(uint32_t client_ip, attack_details& current_attack, std::
logger << log4cpp::Priority::INFO << "Call to ExaBGP for ban client is finished: " << client_ip_as_string;
}
#ifdef ENABLE_GOBGP
if (gobgp_enabled) {
logger << log4cpp::Priority::INFO << "Call GoBGP for ban client started: " << client_ip_as_string;
boost::thread gobgp_thread(gobgp_ban_manage, "ban", client_ip_as_string, current_attack);
gobgp_thread.detach();
logger << log4cpp::Priority::INFO << "Call to GoBGP for ban client is finished: " << client_ip_as_string;
}
#endif
#ifdef REDIS
if (redis_enabled) {
std::string redis_key_name = client_ip_as_string + "_information";
@ -3322,6 +3334,17 @@ void call_unban_handlers(uint32_t client_ip, attack_details& current_attack) {
logger << log4cpp::Priority::INFO << "Call to ExaBGP for unban client is finished: " << client_ip_as_string;
}
#ifdef ENABLE_GOBGP
if (gobgp_enabled) {
logger << log4cpp::Priority::INFO << "Call GoBGP for unban client started: " << client_ip_as_string;
boost::thread gobgp_thread(gobgp_ban_manage, "unban", client_ip_as_string, current_attack);
gobgp_thread.detach();
logger << log4cpp::Priority::INFO << "Call to GoBGP for unban client is finished: " << client_ip_as_string;
}
#endif
}
std::string print_ddos_attack_details() {

@ -7,6 +7,8 @@
#include "log4cpp/PatternLayout.hh"
#include "log4cpp/Priority.hh"
#include "fast_library.h"
// Get log4cpp logger from main programm
extern log4cpp::Category& logger;