From d32f894e3ccc4f5f54b2b6fb5fef1182a91e2bc2 Mon Sep 17 00:00:00 2001 From: Pavel Odintsov Date: Thu, 3 Sep 2015 13:09:16 +0200 Subject: [PATCH] We are resurrected hardware locking plugin from PF_RING. We have added action plugin interfase; --- src/CMakeLists.txt | 10 ++- src/actions/pfring_hardware_filter_action.cpp | 60 ++++++++++++++ src/actions/pfring_hardware_filter_action.h | 8 ++ src/fastnetmon.conf | 4 + src/fastnetmon.cpp | 82 +++++-------------- src/fastnetmon_actions.h | 11 +++ 6 files changed, 110 insertions(+), 65 deletions(-) create mode 100644 src/actions/pfring_hardware_filter_action.cpp create mode 100644 src/actions/pfring_hardware_filter_action.h create mode 100644 src/fastnetmon_actions.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 080ce0d..977c240 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -110,10 +110,9 @@ if (ENABLE_PFRING_SUPPORT) endif() include_directories(${PFRING_INCLUDE_DIRS}) -endif() -# If you need hardware locking features -# add_definitions(-DHWFILTER_LOCKING) + message(STATUS "We have enabled PF_RING's hardware filtering option") +endif() # Our LPM library add_library(patricia STATIC libpatricia/patricia.c) @@ -203,6 +202,9 @@ if (ENABLE_PFRING_SUPPORT) target_link_libraries(pfring_plugin ${PFRING_LIBRARIES}) target_link_libraries(pfring_plugin numa) target_link_libraries(pfring_plugin ${CMAKE_THREAD_LIBS_INIT}) + + # Add action for hardware filetring + add_library(pfring_hardware_filter_action STATIC actions/pfring_hardware_filter_action.cpp) endif() # example plugin @@ -329,6 +331,8 @@ target_link_libraries(fastnetmon fast_library) if (ENABLE_PFRING_SUPPORT) target_link_libraries(fastnetmon pfring_plugin) + # Link hardware filter too + target_link_libraries(fastnetmon pfring_hardware_filter_action) endif() if (ENABLE_SNABBSWITCH_SUPPORT) diff --git a/src/actions/pfring_hardware_filter_action.cpp b/src/actions/pfring_hardware_filter_action.cpp new file mode 100644 index 0000000..f81a2b2 --- /dev/null +++ b/src/actions/pfring_hardware_filter_action.cpp @@ -0,0 +1,60 @@ +#include "pfring.h" + +#include +#include +#include + +#include "../fastnetmon_actions.h" + +// Got it from global namespace +extern pfring* pf_ring_descr; + +void pfring_hardware_filter_action_block(std::string client_ip_as_string) { + /* 6 - tcp, 17 - udp, 0 - other (non tcp and non udp) */ + std::vector banned_protocols; + banned_protocols.push_back(17); + banned_protocols.push_back(6); + banned_protocols.push_back(0); + + int rule_number = 10; + + // Iterate over incoming and outgoing direction + for (int rule_direction = 0; rule_direction < 2; rule_direction++) { + for (std::vector::iterator banned_protocol = banned_protocols.begin(); + banned_protocol != banned_protocols.end(); ++banned_protocol) { + + /* On 82599 NIC we can ban traffic using hardware filtering rules */ + + // Difference between fie tuple and perfect filters: + // http://www.ntop.org/products/pf_ring/hardware-packet-filtering/ + + hw_filtering_rule rule; + intel_82599_five_tuple_filter_hw_rule* ft_rule; + + ft_rule = &rule.rule_family.five_tuple_rule; + + memset(&rule, 0, sizeof(rule)); + rule.rule_family_type = intel_82599_five_tuple_rule; + rule.rule_id = rule_number++; + ft_rule->queue_id = -1; // drop traffic + ft_rule->proto = *banned_protocol; + + std::string hw_filter_rule_direction = ""; + if (rule_direction == 0) { + hw_filter_rule_direction = "outgoing"; + ft_rule->s_addr = ntohl(inet_addr(client_ip_as_string.c_str())); + } else { + hw_filter_rule_direction = "incoming"; + ft_rule->d_addr = ntohl(inet_addr(client_ip_as_string.c_str())); + } + + if (pfring_add_hw_rule(pf_ring_descr, &rule) != 0) { + logger << log4cpp::Priority::ERROR + << "Can't add hardware filtering rule for protocol: " << *banned_protocol + << " in direction: " << hw_filter_rule_direction; + } + + rule_number++; + } + } +} diff --git a/src/actions/pfring_hardware_filter_action.h b/src/actions/pfring_hardware_filter_action.h new file mode 100644 index 0000000..9d38739 --- /dev/null +++ b/src/actions/pfring_hardware_filter_action.h @@ -0,0 +1,8 @@ +#ifndef PFRING_HARDWARE_FILTER_ACTION_H +#define PFRING_HARDWARE_FILTER_ACTION_H + +#include + +void pfring_hardware_filter_action_block(std::string client_ip_as_string); + +#endif diff --git a/src/fastnetmon.conf b/src/fastnetmon.conf index 9e4f5af..edb921a 100644 --- a/src/fastnetmon.conf +++ b/src/fastnetmon.conf @@ -170,6 +170,10 @@ redis_host = 127.0.0.1 # You could specify custom prefix here redis_prefix = mydc1 +# If you are using PF_RING non ZC version you could block traffic on host with hardware filters +# Please be aware! We could not remove blocks with this action plugin +pfring_hardware_filters_enabled = off + # ExaBGP could announce blocked IPs with BGP protocol exabgp = off exabgp_command_pipe = /var/run/exabgp.cmd diff --git a/src/fastnetmon.cpp b/src/fastnetmon.cpp index d5dae3d..6b7e611 100644 --- a/src/fastnetmon.cpp +++ b/src/fastnetmon.cpp @@ -54,6 +54,10 @@ #include "afpacket_plugin/afpacket_collector.h" #endif +#ifdef PF_RING +#include "actions/pfring_hardware_filter_action.h" +#endif + // 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" @@ -109,6 +113,8 @@ unsigned int recalculate_speed_timeout = 1; // Send or not any details about attack for ban script call over stdin bool notify_script_pass_details = true; +bool pfring_hardware_filters_enabled = false; + bool notify_script_enabled = true; // We could collect attack dumps in pcap format @@ -362,10 +368,6 @@ bool process_outgoing_traffic = true; void init_current_instance_of_ndpi(); #endif -#ifdef HWFILTER_LOCKING -void block_all_traffic_with_82599_hardware_filtering(std::string client_ip_as_string); -#endif - std::string get_attack_description_in_json(uint32_t client_ip, attack_details& current_attack); logging_configuration_t read_logging_settings(configuration_map_t configuration_map); std::string get_amplification_attack_type(amplification_attack_type_t attack_type); @@ -946,6 +948,10 @@ bool load_configuration_file() { } } + if (configuration_map.count("pfring_hardware_filters_enabled") != 0) { + pfring_hardware_filters_enabled = configuration_map["pfring_hardware_filters_enabled"] == "on"; + } + if (configuration_map.count("netflow") != 0) { if (configuration_map["netflow"] == "on") { enable_netflow_collection = true; @@ -2850,12 +2856,6 @@ void call_ban_handlers(uint32_t client_ip, attack_details& current_attack, std:: std::string pps_as_string = convert_int_to_string(current_attack.attack_power); std::string data_direction_as_string = get_direction_name(current_attack.attack_direction); -#ifdef HWFILTER_LOCKING - logger << log4cpp::Priority::INFO - << "We will block traffic to/from this IP with hardware filters"; - block_all_traffic_with_82599_hardware_filtering(client_ip_as_string); -#endif - bool store_attack_details_to_file = true; std::string basic_attack_information = get_attack_description(client_ip, current_attack); @@ -2868,6 +2868,16 @@ void call_ban_handlers(uint32_t client_ip, attack_details& current_attack, std:: print_attack_details_to_file(full_attack_description, client_ip_as_string, current_attack); } + if (pfring_hardware_filters_enabled) { +#ifdef PF_RING + logger << log4cpp::Priority::INFO + << "We will block traffic to/from this IP with hardware filters"; + pfring_hardware_filter_action_block(client_ip_as_string); +#else + logger << log4cpp::Priority::ERROR << "You haven't compiled PF_RING hardware filters support"; +#endif + } + if (notify_script_enabled) { std::string script_call_params = notify_script_path + " " + client_ip_as_string + " " + data_direction_as_string + " " + pps_as_string + @@ -2929,58 +2939,6 @@ void call_ban_handlers(uint32_t client_ip, attack_details& current_attack, std:: #endif } -#ifdef HWFILTER_LOCKING -void block_all_traffic_with_82599_hardware_filtering(std::string client_ip_as_string) { - /* 6 - tcp, 17 - udp, 0 - other (non tcp and non udp) */ - std::vector banned_protocols; - banned_protocols.push_back(17); - banned_protocols.push_back(6); - banned_protocols.push_back(0); - - int rule_number = 10; - - // Iterate over incoming and outgoing direction - for (int rule_direction = 0; rule_direction < 2; rule_direction++) { - for (std::vector::iterator banned_protocol = banned_protocols.begin(); - banned_protocol != banned_protocols.end(); ++banned_protocol) { - - /* On 82599 NIC we can ban traffic using hardware filtering rules */ - - // Difference between fie tuple and perfect filters: - // http://www.ntop.org/products/pf_ring/hardware-packet-filtering/ - - hw_filtering_rule rule; - intel_82599_five_tuple_filter_hw_rule* ft_rule; - - ft_rule = &rule.rule_family.five_tuple_rule; - - memset(&rule, 0, sizeof(rule)); - rule.rule_family_type = intel_82599_five_tuple_rule; - rule.rule_id = rule_number++; - ft_rule->queue_id = -1; // drop traffic - ft_rule->proto = *banned_protocol; - - std::string hw_filter_rule_direction = ""; - if (rule_direction == 0) { - hw_filter_rule_direction = "outgoing"; - ft_rule->s_addr = ntohl(inet_addr(client_ip_as_string.c_str())); - } else { - hw_filter_rule_direction = "incoming"; - ft_rule->d_addr = ntohl(inet_addr(client_ip_as_string.c_str())); - } - - if (pfring_add_hw_rule(pf_ring_descr, &rule) != 0) { - logger << log4cpp::Priority::ERROR - << "Can't add hardware filtering rule for protocol: " << *banned_protocol - << " in direction: " << hw_filter_rule_direction; - } - - rule_number++; - } - } -} -#endif - /* Thread for cleaning up ban list */ void cleanup_ban_list() { // If we use very small ban time we should call ban_cleanup thread more often diff --git a/src/fastnetmon_actions.h b/src/fastnetmon_actions.h new file mode 100644 index 0000000..3ee00b1 --- /dev/null +++ b/src/fastnetmon_actions.h @@ -0,0 +1,11 @@ +#include "log4cpp/Category.hh" +#include "log4cpp/Appender.hh" +#include "log4cpp/FileAppender.hh" +#include "log4cpp/OstreamAppender.hh" +#include "log4cpp/Layout.hh" +#include "log4cpp/BasicLayout.hh" +#include "log4cpp/PatternLayout.hh" +#include "log4cpp/Priority.hh" + +// Get log4cpp logger from main programm +extern log4cpp::Category& logger;