Optional DNS based blocklist
If enabled, pulls IPs to block on blocklist.moneropulse.*, and blocks then for 8 days (so IPs dropping from the list will eventually get unblocked, and DNS failures don't result in instant clearing of the blocklist). Enable with --enable-dns-blocklist
This commit is contained in:
parent
54a4071473
commit
fb9ef24267
|
@ -197,6 +197,8 @@
|
||||||
|
|
||||||
#define RPC_CREDITS_PER_HASH_SCALE ((float)(1<<24))
|
#define RPC_CREDITS_PER_HASH_SCALE ((float)(1<<24))
|
||||||
|
|
||||||
|
#define DNS_BLOCKLIST_LIFETIME (86400 * 8)
|
||||||
|
|
||||||
// New constants are intended to go here
|
// New constants are intended to go here
|
||||||
namespace config
|
namespace config
|
||||||
{
|
{
|
||||||
|
|
|
@ -149,6 +149,7 @@ namespace nodetool
|
||||||
const command_line::arg_descriptor<std::string> arg_ban_list = {"ban-list", "Specify ban list file, one IP address per line"};
|
const command_line::arg_descriptor<std::string> arg_ban_list = {"ban-list", "Specify ban list file, one IP address per line"};
|
||||||
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port = {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true};
|
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port = {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true};
|
||||||
const command_line::arg_descriptor<bool> arg_no_sync = {"no-sync", "Don't synchronize the blockchain with other peers", false};
|
const command_line::arg_descriptor<bool> arg_no_sync = {"no-sync", "Don't synchronize the blockchain with other peers", false};
|
||||||
|
const command_line::arg_descriptor<bool> arg_enable_dns_blocklist = {"enable-dns-blocklist", "Apply realtime blocklist from DNS", false};
|
||||||
|
|
||||||
const command_line::arg_descriptor<bool> arg_no_igd = {"no-igd", "Disable UPnP port mapping"};
|
const command_line::arg_descriptor<bool> arg_no_igd = {"no-igd", "Disable UPnP port mapping"};
|
||||||
const command_line::arg_descriptor<std::string> arg_igd = {"igd", "UPnP port mapping (disabled, enabled, delayed)", "delayed"};
|
const command_line::arg_descriptor<std::string> arg_igd = {"igd", "UPnP port mapping (disabled, enabled, delayed)", "delayed"};
|
||||||
|
|
|
@ -287,7 +287,7 @@ namespace nodetool
|
||||||
uint32_t get_max_out_public_peers() const;
|
uint32_t get_max_out_public_peers() const;
|
||||||
void change_max_in_public_peers(size_t count);
|
void change_max_in_public_peers(size_t count);
|
||||||
uint32_t get_max_in_public_peers() const;
|
uint32_t get_max_in_public_peers() const;
|
||||||
virtual bool block_host(epee::net_utils::network_address address, time_t seconds = P2P_IP_BLOCKTIME);
|
virtual bool block_host(epee::net_utils::network_address address, time_t seconds = P2P_IP_BLOCKTIME, bool add_only = false);
|
||||||
virtual bool unblock_host(const epee::net_utils::network_address &address);
|
virtual bool unblock_host(const epee::net_utils::network_address &address);
|
||||||
virtual bool block_subnet(const epee::net_utils::ipv4_network_subnet &subnet, time_t seconds = P2P_IP_BLOCKTIME);
|
virtual bool block_subnet(const epee::net_utils::ipv4_network_subnet &subnet, time_t seconds = P2P_IP_BLOCKTIME);
|
||||||
virtual bool unblock_subnet(const epee::net_utils::ipv4_network_subnet &subnet);
|
virtual bool unblock_subnet(const epee::net_utils::ipv4_network_subnet &subnet);
|
||||||
|
@ -369,6 +369,7 @@ namespace nodetool
|
||||||
bool peer_sync_idle_maker();
|
bool peer_sync_idle_maker();
|
||||||
bool do_handshake_with_peer(peerid_type& pi, p2p_connection_context& context, bool just_take_peerlist = false);
|
bool do_handshake_with_peer(peerid_type& pi, p2p_connection_context& context, bool just_take_peerlist = false);
|
||||||
bool do_peer_timed_sync(const epee::net_utils::connection_context_base& context, peerid_type peer_id);
|
bool do_peer_timed_sync(const epee::net_utils::connection_context_base& context, peerid_type peer_id);
|
||||||
|
bool update_dns_blocklist();
|
||||||
|
|
||||||
bool make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist);
|
bool make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist);
|
||||||
bool make_new_connection_from_peerlist(network_zone& zone, bool use_white_list);
|
bool make_new_connection_from_peerlist(network_zone& zone, bool use_white_list);
|
||||||
|
@ -474,6 +475,7 @@ namespace nodetool
|
||||||
epee::math_helper::once_a_time_seconds<60*30, false> m_peerlist_store_interval;
|
epee::math_helper::once_a_time_seconds<60*30, false> m_peerlist_store_interval;
|
||||||
epee::math_helper::once_a_time_seconds<60> m_gray_peerlist_housekeeping_interval;
|
epee::math_helper::once_a_time_seconds<60> m_gray_peerlist_housekeeping_interval;
|
||||||
epee::math_helper::once_a_time_seconds<3600, false> m_incoming_connections_interval;
|
epee::math_helper::once_a_time_seconds<3600, false> m_incoming_connections_interval;
|
||||||
|
epee::math_helper::once_a_time_seconds<7000> m_dns_blocklist_interval;
|
||||||
|
|
||||||
std::list<epee::net_utils::network_address> m_priority_peers;
|
std::list<epee::net_utils::network_address> m_priority_peers;
|
||||||
std::vector<epee::net_utils::network_address> m_exclusive_peers;
|
std::vector<epee::net_utils::network_address> m_exclusive_peers;
|
||||||
|
@ -512,6 +514,8 @@ namespace nodetool
|
||||||
cryptonote::network_type m_nettype;
|
cryptonote::network_type m_nettype;
|
||||||
|
|
||||||
epee::net_utils::ssl_support_t m_ssl_support;
|
epee::net_utils::ssl_support_t m_ssl_support;
|
||||||
|
|
||||||
|
bool m_enable_dns_blocklist;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int64_t default_limit_up = P2P_DEFAULT_LIMIT_RATE_UP; // kB/s
|
const int64_t default_limit_up = P2P_DEFAULT_LIMIT_RATE_UP; // kB/s
|
||||||
|
@ -533,6 +537,7 @@ namespace nodetool
|
||||||
extern const command_line::arg_descriptor<std::string> arg_ban_list;
|
extern const command_line::arg_descriptor<std::string> arg_ban_list;
|
||||||
extern const command_line::arg_descriptor<bool> arg_p2p_hide_my_port;
|
extern const command_line::arg_descriptor<bool> arg_p2p_hide_my_port;
|
||||||
extern const command_line::arg_descriptor<bool> arg_no_sync;
|
extern const command_line::arg_descriptor<bool> arg_no_sync;
|
||||||
|
extern const command_line::arg_descriptor<bool> arg_enable_dns_blocklist;
|
||||||
|
|
||||||
extern const command_line::arg_descriptor<bool> arg_no_igd;
|
extern const command_line::arg_descriptor<bool> arg_no_igd;
|
||||||
extern const command_line::arg_descriptor<std::string> arg_igd;
|
extern const command_line::arg_descriptor<std::string> arg_igd;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <boost/optional/optional.hpp>
|
#include <boost/optional/optional.hpp>
|
||||||
#include <boost/thread/thread.hpp>
|
#include <boost/thread/thread.hpp>
|
||||||
#include <boost/uuid/uuid_io.hpp>
|
#include <boost/uuid/uuid_io.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
@ -120,6 +121,7 @@ namespace nodetool
|
||||||
command_line::add_arg(desc, arg_ban_list);
|
command_line::add_arg(desc, arg_ban_list);
|
||||||
command_line::add_arg(desc, arg_p2p_hide_my_port);
|
command_line::add_arg(desc, arg_p2p_hide_my_port);
|
||||||
command_line::add_arg(desc, arg_no_sync);
|
command_line::add_arg(desc, arg_no_sync);
|
||||||
|
command_line::add_arg(desc, arg_enable_dns_blocklist);
|
||||||
command_line::add_arg(desc, arg_no_igd);
|
command_line::add_arg(desc, arg_no_igd);
|
||||||
command_line::add_arg(desc, arg_igd);
|
command_line::add_arg(desc, arg_igd);
|
||||||
command_line::add_arg(desc, arg_out_peers);
|
command_line::add_arg(desc, arg_out_peers);
|
||||||
|
@ -226,7 +228,7 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::block_host(epee::net_utils::network_address addr, time_t seconds)
|
bool node_server<t_payload_net_handler>::block_host(epee::net_utils::network_address addr, time_t seconds, bool add_only)
|
||||||
{
|
{
|
||||||
if(!addr.is_blockable())
|
if(!addr.is_blockable())
|
||||||
return false;
|
return false;
|
||||||
|
@ -240,7 +242,11 @@ namespace nodetool
|
||||||
else
|
else
|
||||||
limit = now + seconds;
|
limit = now + seconds;
|
||||||
const std::string host_str = addr.host_str();
|
const std::string host_str = addr.host_str();
|
||||||
|
auto it = m_blocked_hosts.find(host_str);
|
||||||
|
if (it == m_blocked_hosts.end())
|
||||||
m_blocked_hosts[host_str] = limit;
|
m_blocked_hosts[host_str] = limit;
|
||||||
|
else if (it->second < limit || !add_only)
|
||||||
|
it->second = limit;
|
||||||
|
|
||||||
// drop any connection to that address. This should only have to look into
|
// drop any connection to that address. This should only have to look into
|
||||||
// the zone related to the connection, but really make sure everything is
|
// the zone related to the connection, but really make sure everything is
|
||||||
|
@ -497,6 +503,8 @@ namespace nodetool
|
||||||
if (command_line::has_arg(vm, arg_no_sync))
|
if (command_line::has_arg(vm, arg_no_sync))
|
||||||
m_payload_handler.set_no_sync(true);
|
m_payload_handler.set_no_sync(true);
|
||||||
|
|
||||||
|
m_enable_dns_blocklist = command_line::get_arg(vm, arg_enable_dns_blocklist);
|
||||||
|
|
||||||
if ( !set_max_out_peers(public_zone, command_line::get_arg(vm, arg_out_peers) ) )
|
if ( !set_max_out_peers(public_zone, command_line::get_arg(vm, arg_out_peers) ) )
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
|
@ -1971,6 +1979,52 @@ namespace nodetool
|
||||||
m_gray_peerlist_housekeeping_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::gray_peerlist_housekeeping, this));
|
m_gray_peerlist_housekeeping_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::gray_peerlist_housekeeping, this));
|
||||||
m_peerlist_store_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::store_config, this));
|
m_peerlist_store_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::store_config, this));
|
||||||
m_incoming_connections_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::check_incoming_connections, this));
|
m_incoming_connections_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::check_incoming_connections, this));
|
||||||
|
m_dns_blocklist_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::update_dns_blocklist, this));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
template<class t_payload_net_handler>
|
||||||
|
bool node_server<t_payload_net_handler>::update_dns_blocklist()
|
||||||
|
{
|
||||||
|
if (!m_enable_dns_blocklist)
|
||||||
|
return true;
|
||||||
|
if (m_nettype != cryptonote::MAINNET)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
static const std::vector<std::string> dns_urls = {
|
||||||
|
"blocklist.moneropulse.se"
|
||||||
|
, "blocklist.moneropulse.org"
|
||||||
|
, "blocklist.moneropulse.net"
|
||||||
|
, "blocklist.moneropulse.no"
|
||||||
|
, "blocklist.moneropulse.fr"
|
||||||
|
, "blocklist.moneropulse.de"
|
||||||
|
, "blocklist.moneropulse.ch"
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> records;
|
||||||
|
if (!tools::dns_utils::load_txt_records_from_dns(records, dns_urls))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
unsigned good = 0, bad = 0;
|
||||||
|
for (const auto& record : records)
|
||||||
|
{
|
||||||
|
std::vector<std::string> ips;
|
||||||
|
boost::split(ips, record, boost::is_any_of(";"));
|
||||||
|
for (const auto &ip: ips)
|
||||||
|
{
|
||||||
|
const expect<epee::net_utils::network_address> parsed_addr = net::get_network_address(ip, 0);
|
||||||
|
if (!parsed_addr)
|
||||||
|
{
|
||||||
|
MWARNING("Invalid IP address from DNS blocklist: " << ip << " - " << parsed_addr.error());
|
||||||
|
++bad;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
block_host(*parsed_addr, DNS_BLOCKLIST_LIFETIME, true);
|
||||||
|
++good;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (good > 0)
|
||||||
|
MINFO(good << " addresses added to the blocklist");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace nodetool
|
||||||
virtual uint64_t get_public_connections_count()=0;
|
virtual uint64_t get_public_connections_count()=0;
|
||||||
virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0;
|
virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0;
|
||||||
virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0;
|
virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0;
|
||||||
virtual bool block_host(epee::net_utils::network_address address, time_t seconds = 0)=0;
|
virtual bool block_host(epee::net_utils::network_address address, time_t seconds = 0, bool add_only = false)=0;
|
||||||
virtual bool unblock_host(const epee::net_utils::network_address &address)=0;
|
virtual bool unblock_host(const epee::net_utils::network_address &address)=0;
|
||||||
virtual std::map<std::string, time_t> get_blocked_hosts()=0;
|
virtual std::map<std::string, time_t> get_blocked_hosts()=0;
|
||||||
virtual std::map<epee::net_utils::ipv4_network_subnet, time_t> get_blocked_subnets()=0;
|
virtual std::map<epee::net_utils::ipv4_network_subnet, time_t> get_blocked_subnets()=0;
|
||||||
|
@ -108,7 +108,7 @@ namespace nodetool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
virtual bool block_host(epee::net_utils::network_address address, time_t seconds)
|
virtual bool block_host(epee::net_utils::network_address address, time_t seconds, bool add_only)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue