mirror of
https://github.com/pavel-odintsov/fastnetmon
synced 2024-11-26 09:03:49 +01:00
Reworked logic for IPv6 announces to sync it with Advanced edition in approach
This commit is contained in:
parent
3905a4a033
commit
a0b0d13f48
@ -8,22 +8,14 @@
|
||||
|
||||
#include "../gobgp_client/gobgp_client.hpp"
|
||||
|
||||
#include "../fastnetmon_configuration_scheme.hpp"
|
||||
|
||||
std::string gobgp_nexthop = "0.0.0.0";
|
||||
bool gobgp_announce_whole_subnet = false;
|
||||
bool gobgp_announce_host = false;
|
||||
|
||||
bgp_community_attribute_element_t bgp_community_host;
|
||||
bgp_community_attribute_element_t bgp_community_subnet;
|
||||
|
||||
// IPv6
|
||||
bool gobgp_announce_whole_subnet_ipv6 = false;
|
||||
bool gobgp_announce_host_ipv6 = false;
|
||||
|
||||
bgp_community_attribute_element_t bgp_community_host_ipv6;
|
||||
bgp_community_attribute_element_t bgp_community_subnet_ipv6;
|
||||
;
|
||||
|
||||
subnet_ipv6_cidr_mask_t ipv6_next_hop;
|
||||
extern fastnetmon_configuration_t fastnetmon_global_configuration;
|
||||
|
||||
void gobgp_action_init() {
|
||||
logger << log4cpp::Priority::INFO << "GoBGP action module loaded";
|
||||
@ -32,39 +24,34 @@ void gobgp_action_init() {
|
||||
gobgp_nexthop = configuration_map["gobgp_next_hop"];
|
||||
}
|
||||
|
||||
// Set IPv6 hop to safe default
|
||||
ipv6_next_hop.cidr_prefix_length = 128;
|
||||
read_ipv6_host_from_string("100::1", ipv6_next_hop.subnet_address);
|
||||
|
||||
if (configuration_map.count("gobgp_next_hop_ipv6")) {
|
||||
bool parsed_next_hop_result =
|
||||
read_ipv6_host_from_string(configuration_map["gobgp_next_hop_ipv6"], ipv6_next_hop.subnet_address);
|
||||
|
||||
if (!parsed_next_hop_result) {
|
||||
logger << log4cpp::Priority::ERROR
|
||||
<< "Can't parse specified IPv6 next hop to IPv6 address: " << configuration_map["gobgp_next_hop_ipv6"];
|
||||
}
|
||||
fastnetmon_global_configuration.gobgp_next_hop_ipv6 = configuration_map["gobgp_next_hop_ipv6"];
|
||||
}
|
||||
|
||||
logger << log4cpp::Priority::INFO << "IPv6 next hop: " << print_ipv6_cidr_subnet(ipv6_next_hop);
|
||||
if (configuration_map.count("gobgp_next_hop_host_ipv6")) {
|
||||
fastnetmon_global_configuration.gobgp_next_hop_host_ipv6 = configuration_map["gobgp_next_hop_host_ipv6"];
|
||||
}
|
||||
|
||||
if (configuration_map.count("gobgp_next_hop_subnet_ipv6")) {
|
||||
fastnetmon_global_configuration.gobgp_next_hop_subnet_ipv6 = configuration_map["gobgp_next_hop_subnet_ipv6"];
|
||||
}
|
||||
|
||||
if (configuration_map.count("gobgp_announce_host")) {
|
||||
gobgp_announce_host = configuration_map["gobgp_announce_host"] == "on";
|
||||
fastnetmon_global_configuration.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";
|
||||
fastnetmon_global_configuration.gobgp_announce_whole_subnet = configuration_map["gobgp_announce_whole_subnet"] == "on";
|
||||
}
|
||||
|
||||
if (configuration_map.count("gobgp_announce_host_ipv6")) {
|
||||
gobgp_announce_host_ipv6 = configuration_map["gobgp_announce_host_ipv6"] == "on";
|
||||
fastnetmon_global_configuration.gobgp_announce_host_ipv6 = configuration_map["gobgp_announce_host_ipv6"] == "on";
|
||||
}
|
||||
|
||||
if (configuration_map.count("gobgp_announce_whole_subnet_ipv6")) {
|
||||
gobgp_announce_whole_subnet_ipv6 = configuration_map["gobgp_announce_whole_subnet_ipv6"] == "on";
|
||||
fastnetmon_global_configuration.gobgp_announce_whole_subnet_ipv6 = configuration_map["gobgp_announce_whole_subnet_ipv6"] == "on";
|
||||
}
|
||||
|
||||
|
||||
// Set them to safe defaults
|
||||
bgp_community_host.asn_number = 65001;
|
||||
bgp_community_host.community_number = 666;
|
||||
@ -93,39 +80,116 @@ void gobgp_action_init() {
|
||||
logger << log4cpp::Priority::INFO << "GoBGP subnet IPv4 community: " << bgp_community_subnet.asn_number << ":"
|
||||
<< bgp_community_subnet.community_number;
|
||||
|
||||
// IPv6 communities
|
||||
bgp_community_host_ipv6.asn_number = 65001;
|
||||
bgp_community_host_ipv6.community_number = 666;
|
||||
|
||||
if (configuration_map.count("gobgp_community_host_ipv6")) {
|
||||
if (!read_bgp_community_from_string(configuration_map["gobgp_community_host_ipv6"], bgp_community_host_ipv6)) {
|
||||
logger << log4cpp::Priority::ERROR << "Cannot parse GoBGP community for IPv6 host "
|
||||
<< configuration_map["gobgp_community_host_ipv6"];
|
||||
}
|
||||
fastnetmon_global_configuration.gobgp_community_host_ipv6 = configuration_map["gobgp_community_host_ipv6"];
|
||||
}
|
||||
|
||||
logger << log4cpp::Priority::INFO << "GoBGP host IPv6 community: " << bgp_community_host_ipv6.asn_number << ":"
|
||||
<< bgp_community_host_ipv6.community_number;
|
||||
|
||||
// Set them to safe defaults
|
||||
bgp_community_subnet_ipv6.asn_number = 65001;
|
||||
bgp_community_subnet_ipv6.community_number = 666;
|
||||
|
||||
|
||||
if (configuration_map.count("gobgp_community_subnet_ipv6")) {
|
||||
if (!read_bgp_community_from_string(configuration_map["gobgp_community_subnet_ipv6"], bgp_community_subnet_ipv6)) {
|
||||
logger << log4cpp::Priority::ERROR << "Cannot parse GoBGP community for IPv6 subnet "
|
||||
<< configuration_map["gobgp_community_subnet_ipv6"];
|
||||
}
|
||||
fastnetmon_global_configuration.gobgp_community_subnet_ipv6 = configuration_map["gobgp_community_subnet_ipv6"];
|
||||
}
|
||||
|
||||
logger << log4cpp::Priority::INFO << "GoBGP subnet IPv6 community: " << bgp_community_subnet_ipv6.asn_number << ":"
|
||||
<< bgp_community_subnet_ipv6.community_number;
|
||||
}
|
||||
|
||||
void gobgp_action_shutdown() {
|
||||
}
|
||||
|
||||
void gobgp_ban_manage_ipv6(GrpcClient& gobgp_client,
|
||||
const subnet_ipv6_cidr_mask_t& client_ipv6,
|
||||
bool is_withdrawal,
|
||||
const attack_details_t& current_attack) {
|
||||
// TODO: that's very weird approach to use subnet_ipv6_cidr_mask_t for storing next hop which is HOST address
|
||||
// We need to rework all structures in stack of BGP logic to switch it to plain in6_addr
|
||||
|
||||
subnet_ipv6_cidr_mask_t ipv6_next_hop_legacy{};
|
||||
ipv6_next_hop_legacy.cidr_prefix_length = 128; //-V1048
|
||||
|
||||
bool parsed_next_hop_result =
|
||||
read_ipv6_host_from_string(fastnetmon_global_configuration.gobgp_next_hop_ipv6, ipv6_next_hop_legacy.subnet_address);
|
||||
|
||||
if (!parsed_next_hop_result) {
|
||||
logger << log4cpp::Priority::ERROR
|
||||
<< "Can't parse specified IPv6 next hop to IPv6 address: " << fastnetmon_global_configuration.gobgp_next_hop_ipv6;
|
||||
return;
|
||||
}
|
||||
|
||||
// Starting July 2024, 1.2.8 we have capability to specify different next hops for host and subnet
|
||||
subnet_ipv6_cidr_mask_t gobgp_next_hop_host_ipv6{};
|
||||
gobgp_next_hop_host_ipv6.cidr_prefix_length = 128; //-V1048
|
||||
|
||||
if (fastnetmon_global_configuration.gobgp_next_hop_host_ipv6 != "") {
|
||||
if (!read_ipv6_host_from_string(fastnetmon_global_configuration.gobgp_next_hop_host_ipv6,
|
||||
gobgp_next_hop_host_ipv6.subnet_address)) {
|
||||
logger << log4cpp::Priority::ERROR << "Can't parse specified IPv6 next hop gobgp_next_hop_host_ipv6 as IPv6 address: "
|
||||
<< fastnetmon_global_configuration.gobgp_next_hop_host_ipv6;
|
||||
// We do not stop processing here. If we failed then let's keep it zero
|
||||
}
|
||||
} else {
|
||||
// That's fine. It's expected to be empty on new installations
|
||||
}
|
||||
|
||||
// Starting July 2024, 1.2.8 we have capability to specify different next hops for host and subnet
|
||||
subnet_ipv6_cidr_mask_t gobgp_next_hop_subnet_ipv6{};
|
||||
gobgp_next_hop_subnet_ipv6.cidr_prefix_length = 128; //-V1048
|
||||
|
||||
if (fastnetmon_global_configuration.gobgp_next_hop_subnet_ipv6 != "") {
|
||||
if (!read_ipv6_host_from_string(fastnetmon_global_configuration.gobgp_next_hop_subnet_ipv6,
|
||||
gobgp_next_hop_subnet_ipv6.subnet_address)) {
|
||||
logger << log4cpp::Priority::ERROR << "Can't parse specified IPv6 next hop gobgp_next_hop_subnet_ipv6 as IPv6 address: "
|
||||
<< fastnetmon_global_configuration.gobgp_next_hop_subnet_ipv6;
|
||||
// We do not stop processing here. If we failed then let's keep it zero
|
||||
}
|
||||
} else {
|
||||
// That's fine. It's expected to be empty on new installations
|
||||
}
|
||||
|
||||
// For backward compatibility with old deployments which still use value gobgp_next_hop_ipv6 we check new value and if it's zero use old one
|
||||
if (is_zero_ipv6_address(gobgp_next_hop_host_ipv6.subnet_address)) {
|
||||
logger << log4cpp::Priority::INFO << "gobgp_next_hop_host_ipv6 is zero, will use global gobgp_next_hop_ipv6: "
|
||||
<< fastnetmon_global_configuration.gobgp_next_hop_ipv6;
|
||||
|
||||
gobgp_next_hop_host_ipv6.subnet_address = ipv6_next_hop_legacy.subnet_address;
|
||||
}
|
||||
|
||||
if (is_zero_ipv6_address(gobgp_next_hop_subnet_ipv6.subnet_address)) {
|
||||
logger << log4cpp::Priority::INFO << "gobgp_next_hop_subnet_ipv6 is zero, will use global gobgp_next_hop_ipv6: "
|
||||
<< fastnetmon_global_configuration.gobgp_next_hop_ipv6;
|
||||
|
||||
gobgp_next_hop_subnet_ipv6.subnet_address = ipv6_next_hop_legacy.subnet_address;
|
||||
}
|
||||
|
||||
if (fastnetmon_global_configuration.gobgp_announce_host_ipv6) {
|
||||
IPv6UnicastAnnounce unicast_ipv6_announce;
|
||||
|
||||
std::vector<std::string> host_ipv6_communities;
|
||||
|
||||
// This one is an old configuration option which can carry only single community
|
||||
host_ipv6_communities.push_back(fastnetmon_global_configuration.gobgp_community_host_ipv6);
|
||||
|
||||
for (auto community_string : host_ipv6_communities) {
|
||||
bgp_community_attribute_element_t bgp_community_host;
|
||||
|
||||
if (!read_bgp_community_from_string(community_string, bgp_community_host)) {
|
||||
logger << log4cpp::Priority::ERROR << "Could not decode BGP community for IPv6 host: " << community_string;
|
||||
// We may have multiple communities and other communities may be correct, skip only broken one
|
||||
continue;
|
||||
}
|
||||
|
||||
unicast_ipv6_announce.add_community(bgp_community_host);
|
||||
}
|
||||
|
||||
unicast_ipv6_announce.set_prefix(client_ipv6);
|
||||
unicast_ipv6_announce.set_next_hop(gobgp_next_hop_host_ipv6);
|
||||
|
||||
gobgp_client.AnnounceUnicastPrefixLowLevelIPv6(unicast_ipv6_announce, is_withdrawal);
|
||||
}
|
||||
|
||||
if (fastnetmon_global_configuration.gobgp_announce_whole_subnet_ipv6) {
|
||||
logger << log4cpp::Priority::ERROR << "Sorry but we do not support IPv6 per subnet announces";
|
||||
}
|
||||
}
|
||||
|
||||
void gobgp_ban_manage(const std::string& action,
|
||||
bool ipv6,
|
||||
uint32_t client_ip,
|
||||
@ -146,19 +210,9 @@ void gobgp_ban_manage(const std::string& action,
|
||||
}
|
||||
|
||||
if (ipv6) {
|
||||
if (gobgp_announce_whole_subnet_ipv6) {
|
||||
logger << log4cpp::Priority::ERROR << "Sorry but we do not support IPv6 per subnet announces";
|
||||
}
|
||||
|
||||
if (gobgp_announce_host_ipv6) {
|
||||
logger << log4cpp::Priority::INFO << action_name << " " << print_ipv6_cidr_subnet(client_ipv6) << " to GoBGP";
|
||||
uint32_t community_as_32bit_int =
|
||||
uint32_t(bgp_community_host_ipv6.asn_number << 16 | bgp_community_host_ipv6.community_number);
|
||||
|
||||
gobgp_client.AnnounceUnicastPrefixIPv6(client_ipv6, ipv6_next_hop, is_withdrawal, community_as_32bit_int);
|
||||
}
|
||||
gobgp_ban_manage_ipv6(gobgp_client, client_ipv6, is_withdrawal, current_attack);
|
||||
} else {
|
||||
if (gobgp_announce_whole_subnet) {
|
||||
if (fastnetmon_global_configuration.gobgp_announce_whole_subnet) {
|
||||
// By default use network from attack
|
||||
subnet_cidr_mask_t customer_network;
|
||||
customer_network.subnet_address = current_attack.customer_network.subnet_address;
|
||||
@ -178,7 +232,7 @@ void gobgp_ban_manage(const std::string& action,
|
||||
customer_network.cidr_prefix_length, community_as_32bit_int);
|
||||
}
|
||||
|
||||
if (gobgp_announce_host) {
|
||||
if (fastnetmon_global_configuration.gobgp_announce_host) {
|
||||
std::string ip_as_string = convert_ip_as_uint_to_string(client_ip);
|
||||
std::string ip_as_string_with_mask = ip_as_string + "/32";
|
||||
|
||||
|
@ -258,6 +258,8 @@ gobgp_community_subnet = 65001:777
|
||||
|
||||
# Configuration for IPv6 announces
|
||||
gobgp_next_hop_ipv6 = 100::1
|
||||
gobgp_next_hop_host_ipv6 = 100::1
|
||||
gobgp_next_hop_subnet_ipv6 = 100::1
|
||||
gobgp_announce_host_ipv6 = on
|
||||
gobgp_announce_whole_subnet_ipv6 = off
|
||||
|
||||
|
@ -34,5 +34,19 @@ class fastnetmon_configuration_t {
|
||||
unsigned int graphite_port{ 2003 };
|
||||
std::string graphite_prefix{ "fastnetmon" };
|
||||
unsigned int graphite_push_period{ 1 };
|
||||
|
||||
// GoBGP
|
||||
bool gobgp_announce_host{ false };
|
||||
bool gobgp_announce_whole_subnet{ false };
|
||||
|
||||
bool gobgp_announce_host_ipv6{ false };
|
||||
bool gobgp_announce_whole_subnet_ipv6{ false };
|
||||
|
||||
std::string gobgp_next_hop_ipv6{ "100::1" };
|
||||
std::string gobgp_next_hop_host_ipv6{ "::0" };
|
||||
std::string gobgp_next_hop_subnet_ipv6{ "::0" };
|
||||
|
||||
std::string gobgp_community_host_ipv6{ "65001:668" };
|
||||
std::string gobgp_community_subnet_ipv6{ "65001:667" };
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user