From b2f26a585c87dc9d8f2e95c8fdc27db7f1288811 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Mon, 29 Jan 2024 21:11:11 +0100 Subject: [PATCH 1/7] Wip: Block ip --- nano/node/network.cpp | 28 ++++++++++++++++++++++++++++ nano/node/network.hpp | 3 +++ 2 files changed, 31 insertions(+) diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 9f33370cc1..a9a67de5f6 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -77,6 +77,10 @@ void nano::network::start () tcp_channels.start (); } ongoing_keepalive (); + + auto ip = boost::asio::ip::make_address ("144.76.30.235"); + node.logger.info (nano::log::type::network, "Blocking: {}", ip.to_string() ); + block_ip (ip); } void nano::network::stop () @@ -347,6 +351,24 @@ void nano::network::broadcast_confirm_req_many (std::deque const & channel) { + if (is_ip_blocked (channel->get_tcp_endpoint ().address ())) + { + node.logger.debug (nano::log::type::network, "Message from IP {} blocked.", channel->get_tcp_endpoint ().address ().to_string ()); + return; + } + node.stats.inc (nano::stat::type::message, to_stat_detail (message.header.type), nano::stat::dir::in); network_message_visitor visitor{ node, channel }; diff --git a/nano/node/network.hpp b/nano/node/network.hpp index f0785d9441..197ce481c0 100644 --- a/nano/node/network.hpp +++ b/nano/node/network.hpp @@ -100,6 +100,8 @@ class network final void broadcast_confirm_req_base (std::shared_ptr const &, std::shared_ptr>> const &, unsigned, bool = false); void broadcast_confirm_req_batched_many (std::unordered_map, std::deque>>, std::function = nullptr, unsigned = broadcast_interval_ms, bool = false); void broadcast_confirm_req_many (std::deque, std::shared_ptr>>>>, std::function = nullptr, unsigned = broadcast_interval_ms); + void block_ip (const boost::asio::ip::address & ip_address); + bool is_ip_blocked (const boost::asio::ip::address & ip_address) const; std::shared_ptr find_node_id (nano::account const &); std::shared_ptr find_channel (nano::endpoint const &); bool not_a_peer (nano::endpoint const &, bool); @@ -133,6 +135,7 @@ class network final bool verify_handshake_response (nano::node_id_handshake::response_payload const & response, nano::endpoint const & remote_endpoint); std::optional prepare_handshake_query (nano::endpoint const & remote_endpoint); nano::node_id_handshake::response_payload prepare_handshake_response (nano::node_id_handshake::query_payload const & query, bool v2) const; + std::unordered_set blocked_ips; private: void process_message (nano::message const &, std::shared_ptr const &); From ced8cf0172aa7d984e6020ff7f60d8a455a59f49 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Tue, 30 Jan 2024 17:13:34 +0100 Subject: [PATCH 2/7] Read blocked peers from config --- nano/node/network.cpp | 11 ++++++++--- nano/node/nodeconfig.cpp | 8 ++++++++ nano/node/nodeconfig.hpp | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/nano/node/network.cpp b/nano/node/network.cpp index a9a67de5f6..cb4060fdd1 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -78,9 +78,14 @@ void nano::network::start () } ongoing_keepalive (); - auto ip = boost::asio::ip::make_address ("144.76.30.235"); - node.logger.info (nano::log::type::network, "Blocking: {}", ip.to_string() ); - block_ip (ip); + auto blocked_peers = node.config.blocked_peers; + + for (const std::string & ip_string : blocked_peers) + { + auto ip = boost::asio::ip::make_address (ip_string); + block_ip (ip); + node.logger.info (nano::log::type::network, "Added blocking rule for ip {}", ip.to_string ()); + } } void nano::network::stop () diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index 61179c685c..aa8d008714 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -288,6 +288,14 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) }); } + if (toml.has_key ("blocked_peers")) + { + blocked_peers.clear (); + toml.array_entries_required ("blocked_peers", [this, &toml] (std::string entry) { + blocked_peers.push_back (entry); + }); + } + if (toml.has_key ("preconfigured_representatives")) { preconfigured_representatives.clear (); diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index d1a42fa370..5f4ff3fc24 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -54,6 +54,7 @@ class node_config std::vector> work_peers; std::vector> secondary_work_peers{ { "127.0.0.1", 8076 } }; /* Default of nano-pow-server */ std::vector preconfigured_peers; + std::vector blocked_peers{}; std::vector preconfigured_representatives; unsigned bootstrap_fraction_numerator{ 1 }; nano::amount receive_minimum{ nano::xrb_ratio }; From 14ec64a23d86d12e46fc1b7b19dfad9646a117c3 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:55:04 +0100 Subject: [PATCH 3/7] Small refactor --- nano/node/network.cpp | 40 ++++++++++++++++++++++++---------------- nano/node/network.hpp | 2 +- nano/node/nodeconfig.cpp | 2 ++ 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/nano/node/network.cpp b/nano/node/network.cpp index cb4060fdd1..b962abf5ef 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -78,14 +78,7 @@ void nano::network::start () } ongoing_keepalive (); - auto blocked_peers = node.config.blocked_peers; - - for (const std::string & ip_string : blocked_peers) - { - auto ip = boost::asio::ip::make_address (ip_string); - block_ip (ip); - node.logger.info (nano::log::type::network, "Added blocking rule for ip {}", ip.to_string ()); - } + Configure_blocked_peers (); } void nano::network::stop () @@ -356,16 +349,31 @@ void nano::network::broadcast_confirm_req_many (std::deque const &, std::shared_ptr>> const &, unsigned, bool = false); void broadcast_confirm_req_batched_many (std::unordered_map, std::deque>>, std::function = nullptr, unsigned = broadcast_interval_ms, bool = false); void broadcast_confirm_req_many (std::deque, std::shared_ptr>>>>, std::function = nullptr, unsigned = broadcast_interval_ms); - void block_ip (const boost::asio::ip::address & ip_address); + void Configure_blocked_peers (); bool is_ip_blocked (const boost::asio::ip::address & ip_address) const; std::shared_ptr find_node_id (nano::account const &); std::shared_ptr find_channel (nano::endpoint const &); diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index aa8d008714..bbf6521af3 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -144,6 +144,8 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const preconfigured_peers_l->push_back (*i); } + auto blocked_peers_l (toml.create_array ("blocked_peers", "A list of \"address\" (hostname or ipv4 or ipv6 notation ip address) that you want to ignore all requests from. \nExample: [\"192.168.0.1\",\"::ffff:10.0.0.1]\"")); + auto preconfigured_representatives_l (toml.create_array ("preconfigured_representatives", "A list of representative account addresses used when creating new accounts in internal wallets.")); for (auto i (preconfigured_representatives.begin ()), n (preconfigured_representatives.end ()); i != n; ++i) { From 611c6755eed2700ca7df057eb8b87038cde5c906 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Tue, 30 Jan 2024 19:03:58 +0100 Subject: [PATCH 4/7] Toml unit test --- nano/core_test/toml.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nano/core_test/toml.cpp b/nano/core_test/toml.cpp index b28c875750..0871684685 100644 --- a/nano/core_test/toml.cpp +++ b/nano/core_test/toml.cpp @@ -180,6 +180,7 @@ TEST (toml, daemon_config_deserialize_defaults) ASSERT_EQ (conf.node.peering_port, defaults.node.peering_port); ASSERT_EQ (conf.node.pow_sleep_interval, defaults.node.pow_sleep_interval); ASSERT_EQ (conf.node.preconfigured_peers, defaults.node.preconfigured_peers); + ASSERT_EQ (conf.node.blocked_peers, defaults.node.blocked_peers); ASSERT_EQ (conf.node.preconfigured_representatives, defaults.node.preconfigured_representatives); ASSERT_EQ (conf.node.receive_minimum, defaults.node.receive_minimum); ASSERT_EQ (conf.node.signature_checker_threads, defaults.node.signature_checker_threads); @@ -407,6 +408,7 @@ TEST (toml, daemon_config_deserialize_no_defaults) peering_port = 999 pow_sleep_interval= 999 preconfigured_peers = ["dev.org"] + blocked_peers = ["192.168.0.1"] preconfigured_representatives = ["nano_3arg3asgtigae3xckabaaewkx3bzsh7nwz7jkmjos79ihyaxwphhm6qgjps4"] receive_minimum = "999" signature_checker_threads = 999 @@ -597,6 +599,7 @@ TEST (toml, daemon_config_deserialize_no_defaults) ASSERT_NE (conf.node.peering_port, defaults.node.peering_port); ASSERT_NE (conf.node.pow_sleep_interval, defaults.node.pow_sleep_interval); ASSERT_NE (conf.node.preconfigured_peers, defaults.node.preconfigured_peers); + ASSERT_NE (conf.node.blocked_peers, defaults.node.blocked_peers); ASSERT_NE (conf.node.preconfigured_representatives, defaults.node.preconfigured_representatives); ASSERT_NE (conf.node.receive_minimum, defaults.node.receive_minimum); ASSERT_NE (conf.node.signature_checker_threads, defaults.node.signature_checker_threads); From 745763d297ceed906c0a47c50b91acf5927add5c Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Tue, 30 Jan 2024 19:25:09 +0100 Subject: [PATCH 5/7] Minor adjustments --- nano/node/network.cpp | 6 +++--- nano/node/nodeconfig.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nano/node/network.cpp b/nano/node/network.cpp index b962abf5ef..7e52649389 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -67,6 +67,8 @@ nano::network::~network () void nano::network::start () { + Configure_blocked_peers (); + if (!node.flags.disable_connection_cleanup) { ongoing_cleanup (); @@ -77,8 +79,6 @@ void nano::network::start () tcp_channels.start (); } ongoing_keepalive (); - - Configure_blocked_peers (); } void nano::network::stop () @@ -505,7 +505,7 @@ void nano::network::process_message (nano::message const & message, std::shared_ { if (is_ip_blocked (channel->get_tcp_endpoint ().address ())) { - node.logger.debug (nano::log::type::network, "Message from IP {} blocked.", channel->get_tcp_endpoint ().address ().to_string ()); + node.logger.debug (nano::log::type::network, "Ignoring message from IP {}", channel->get_tcp_endpoint ().address ().to_string ()); return; } diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index bbf6521af3..e207af52d9 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -144,7 +144,7 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const preconfigured_peers_l->push_back (*i); } - auto blocked_peers_l (toml.create_array ("blocked_peers", "A list of \"address\" (hostname or ipv4 or ipv6 notation ip address) that you want to ignore all requests from. \nExample: [\"192.168.0.1\",\"::ffff:10.0.0.1]\"")); + auto blocked_peers_l (toml.create_array ("blocked_peers", "A list of \"address\" (ipv4 or ipv6 notation ip address) that you want to ignore all requests from. \nExample: [\"192.168.0.1\",\"::ffff:10.0.0.1]\"")); auto preconfigured_representatives_l (toml.create_array ("preconfigured_representatives", "A list of representative account addresses used when creating new accounts in internal wallets.")); for (auto i (preconfigured_representatives.begin ()), n (preconfigured_representatives.end ()); i != n; ++i) From 08979619041ebea0033b40bed10e7e21efea5bda Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:08:45 +0100 Subject: [PATCH 6/7] Fixed example text --- nano/node/nodeconfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index e207af52d9..3b357578bd 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -144,7 +144,7 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const preconfigured_peers_l->push_back (*i); } - auto blocked_peers_l (toml.create_array ("blocked_peers", "A list of \"address\" (ipv4 or ipv6 notation ip address) that you want to ignore all requests from. \nExample: [\"192.168.0.1\",\"::ffff:10.0.0.1]\"")); + auto blocked_peers_l (toml.create_array ("blocked_peers", "A list of \"address\" (ipv4 or ipv6 notation ip address) that you want to ignore all requests from. \nExample: [\"192.168.0.1\",\"::ffff:10.0.0.1\"]")); auto preconfigured_representatives_l (toml.create_array ("preconfigured_representatives", "A list of representative account addresses used when creating new accounts in internal wallets.")); for (auto i (preconfigured_representatives.begin ()), n (preconfigured_representatives.end ()); i != n; ++i) From 0db8f91346c4d3a9be830854b6e3cedad54a90a1 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Thu, 1 Feb 2024 18:20:10 +0100 Subject: [PATCH 7/7] Moved ip blocking to tcp listener --- nano/core_test/toml.cpp | 2 +- nano/node/network.cpp | 41 -------------------------- nano/node/network.hpp | 3 -- nano/node/transport/tcp_server.cpp | 46 ++++++++++++++++++++++++++++++ nano/node/transport/tcp_server.hpp | 4 +++ 5 files changed, 51 insertions(+), 45 deletions(-) diff --git a/nano/core_test/toml.cpp b/nano/core_test/toml.cpp index 0871684685..5b9c7f5896 100644 --- a/nano/core_test/toml.cpp +++ b/nano/core_test/toml.cpp @@ -408,7 +408,7 @@ TEST (toml, daemon_config_deserialize_no_defaults) peering_port = 999 pow_sleep_interval= 999 preconfigured_peers = ["dev.org"] - blocked_peers = ["192.168.0.1"] + blocked_peers = ["192.168.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"] preconfigured_representatives = ["nano_3arg3asgtigae3xckabaaewkx3bzsh7nwz7jkmjos79ihyaxwphhm6qgjps4"] receive_minimum = "999" signature_checker_threads = 999 diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 7e52649389..9f33370cc1 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -67,8 +67,6 @@ nano::network::~network () void nano::network::start () { - Configure_blocked_peers (); - if (!node.flags.disable_connection_cleanup) { ongoing_cleanup (); @@ -349,39 +347,6 @@ void nano::network::broadcast_confirm_req_many (std::deque const & channel) { - if (is_ip_blocked (channel->get_tcp_endpoint ().address ())) - { - node.logger.debug (nano::log::type::network, "Ignoring message from IP {}", channel->get_tcp_endpoint ().address ().to_string ()); - return; - } - node.stats.inc (nano::stat::type::message, to_stat_detail (message.header.type), nano::stat::dir::in); network_message_visitor visitor{ node, channel }; diff --git a/nano/node/network.hpp b/nano/node/network.hpp index 0069c3b9b9..f0785d9441 100644 --- a/nano/node/network.hpp +++ b/nano/node/network.hpp @@ -100,8 +100,6 @@ class network final void broadcast_confirm_req_base (std::shared_ptr const &, std::shared_ptr>> const &, unsigned, bool = false); void broadcast_confirm_req_batched_many (std::unordered_map, std::deque>>, std::function = nullptr, unsigned = broadcast_interval_ms, bool = false); void broadcast_confirm_req_many (std::deque, std::shared_ptr>>>>, std::function = nullptr, unsigned = broadcast_interval_ms); - void Configure_blocked_peers (); - bool is_ip_blocked (const boost::asio::ip::address & ip_address) const; std::shared_ptr find_node_id (nano::account const &); std::shared_ptr find_channel (nano::endpoint const &); bool not_a_peer (nano::endpoint const &, bool); @@ -135,7 +133,6 @@ class network final bool verify_handshake_response (nano::node_id_handshake::response_payload const & response, nano::endpoint const & remote_endpoint); std::optional prepare_handshake_query (nano::endpoint const & remote_endpoint); nano::node_id_handshake::response_payload prepare_handshake_response (nano::node_id_handshake::query_payload const & query, bool v2) const; - std::unordered_set blocked_ips; private: void process_message (nano::message const &, std::shared_ptr const &); diff --git a/nano/node/transport/tcp_server.cpp b/nano/node/transport/tcp_server.cpp index af163701a5..f2b9f1733a 100644 --- a/nano/node/transport/tcp_server.cpp +++ b/nano/node/transport/tcp_server.cpp @@ -44,6 +44,7 @@ nano::transport::tcp_listener::tcp_listener (uint16_t port_a, nano::node & node_ void nano::transport::tcp_listener::start (std::function const &, boost::system::error_code const &)> callback_a) { + configure_blocked_peers (); nano::lock_guard lock{ mutex }; on = true; acceptor.open (local.protocol ()); @@ -136,6 +137,13 @@ void nano::transport::tcp_listener::on_connection (std::functionevict_dead_connections (); + if (this_l->is_ip_blocked (new_connection->remote.address ())) + { + this_l->node.logger.info (nano::log::type::tcp_listener, "Connection refused from blocked IP: {}", new_connection->remote_endpoint ().address ().to_string ()); + this_l->on_connection (std::move (cbk)); + return; + } + if (this_l->connections_per_address.size () >= this_l->max_inbound_connections) { this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_failure, nano::stat::dir::in); @@ -217,6 +225,44 @@ void nano::transport::tcp_listener::on_connection (std::function #include +#include namespace nano { @@ -35,6 +36,7 @@ class tcp_listener final : public std::enable_shared_from_this bootstrap_count{ 0 }; std::atomic realtime_count{ 0 }; + std::unordered_set blocked_ips; private: boost::asio::strand strand; @@ -48,6 +50,8 @@ class tcp_listener final : public std::enable_shared_from_this const & new_connection); bool limit_reached_for_incoming_subnetwork_connections (std::shared_ptr const & new_connection); + void configure_blocked_peers (); + bool is_ip_blocked (const boost::asio::ip::address & ip_address) const; }; std::unique_ptr collect_container_info (tcp_listener & bootstrap_listener, std::string const & name);