forked from bitcoinxt/bitcoinxt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce the beginnings of anti-DoS resource scheduling.
Peers now have a priority that attempts to estimate their importance. Currently it is just based on IP address. The default score is zero. In future it may take into account things like how many blocks were relayed, etc. When a node reaches its max connection slots, it will attempt to find a peer with a lower priority than the one trying to connect and disconnect it, to stay below the max connection limit. Peer priorities are based on matching the connecting IP against a set of IP groups. For now, the only IP group is one that gives Tor exits a score of -10. This is to address DoS attacks that are being reported on the main network in which an attacker builds many connections via Tor to use up all the connection slots and jam the node for clearnet users. It's a more robust approach than simply banning abused proxies altogether. For simplicity, a generated list of exits is compiled into the binary. A future enhancement would be to load IP groups from an external file and/or load from HTTPS urls (would require a new dependency on cpp-netlib). Other anonymizing proxy networks that are attractive to DoS attackers may also be added as alternative IP groups, as a quick fix. Eventually peer priority can be calculated in a more free floating and dynamic manner and the hardcoded IP approach may become unneeded.
- Loading branch information
Showing
10 changed files
with
1,296 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#!/usr/bin/env python | ||
|
||
# Script to generate a C++ source file containing known Tor exits. | ||
# This is used to help nodes treat Tor traffic homogenously. | ||
|
||
import urllib2, time | ||
|
||
data = urllib2.urlopen("https://check.torproject.org/exit-addresses").read() | ||
exitlines = [line for line in data.split('\n') if line.startswith("ExitAddress")] | ||
ipstrs = [line.split()[1] for line in exitlines] | ||
ipstrs.sort() | ||
|
||
contents = """// Generated at %s by gen-tor-ips.py: DO NOT EDIT | ||
static const char *pszTorExits[] = { | ||
"0.1.2.3", // For unit testing | ||
%s | ||
NULL | ||
}; | ||
""" % (time.asctime(), "\n".join([" \"%s\"," % ip for ip in ipstrs])) | ||
|
||
print contents |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright (c) 2009-2015 The Bitcoin Core developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include <boost/foreach.hpp> | ||
#include "ipgroups.h" | ||
#include "sync.h" | ||
|
||
#include "torips.h" | ||
#include "util.h" | ||
|
||
static CCriticalSection cs_groups; | ||
static std::vector<CIPGroup*> groups; | ||
|
||
// Returns NULL if the IP does not belong to any group. | ||
CIPGroup *FindGroupForIP(CNetAddr ip) { | ||
if (!ip.IsValid()) { | ||
LogPrintf("IP is not valid: %s\n", ip.ToString()); | ||
return NULL; | ||
} | ||
|
||
LOCK(cs_groups); | ||
BOOST_FOREACH(CIPGroup *group, groups) | ||
{ | ||
BOOST_FOREACH(const CSubNet &subNet, group->subnets) | ||
{ | ||
if (subNet.Match(ip)) | ||
return group; | ||
} | ||
} | ||
return NULL; | ||
} | ||
|
||
void InitIPGroups() { | ||
// Load Tor Exits as a group. | ||
CIPGroup *ipGroup = new CIPGroup("tor"); | ||
ipGroup->priority = -10; | ||
for (const char **ptr = pszTorExits; *ptr; ptr++) { | ||
std::string ip(*ptr); | ||
ip = ip + "/32"; | ||
ipGroup->subnets.push_back(CSubNet(ip)); | ||
} | ||
LOCK(cs_groups); | ||
groups.push_back(ipGroup); // Deliberately leak it. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright (c) 2009-2015 The Bitcoin Core developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#ifndef BITCOIN_CIPGROUPS_H | ||
#define BITCOIN_CIPGROUPS_H | ||
|
||
#include "netbase.h" | ||
|
||
// A group of logically related IP addresses. Useful for banning or deprioritising | ||
// sources of abusive traffic/DoS attacks. | ||
struct CIPGroup { | ||
std::vector<CSubNet> subnets; | ||
std::string name; | ||
// A priority score indicates how important this group of IP addresses is to this node. | ||
// Importance determines which group wins when the node is out of resources. Any IP | ||
// that is not in a group gets a default priority of zero. Therefore, groups with a priority | ||
// of less than zero will be ignored or disconnected in order to make room for ungrouped | ||
// IPs, and groups with a higher priority will be serviced before ungrouped IPs. | ||
int priority; | ||
|
||
CIPGroup(const std::string &name_) : name(name_), priority(0) {} | ||
}; | ||
|
||
// Returns NULL if the IP does not belong to any group. | ||
CIPGroup *FindGroupForIP(CNetAddr ip); | ||
|
||
void InitIPGroups(); | ||
|
||
#endif //BITCOIN_CIPGROUPS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Copyright (c) 2015- The Bitcoin Core developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include <boost/test/unit_test_suite.hpp> | ||
#include <ipgroups.h> | ||
#include <boost/test/test_tools.hpp> | ||
|
||
BOOST_AUTO_TEST_SUITE(ipgroups_tests); | ||
|
||
BOOST_AUTO_TEST_CASE(ipgroup) | ||
{ | ||
InitIPGroups(); | ||
BOOST_CHECK(FindGroupForIP(CNetAddr("0.0.0.0")) == NULL); | ||
CIPGroup *group = FindGroupForIP(CNetAddr("0.1.2.3")); | ||
BOOST_CHECK_EQUAL(group->name, "tor"); | ||
|
||
// If/when we have the ability to load labelled subnets from a file or persisted datastore, test that here. | ||
} | ||
|
||
BOOST_AUTO_TEST_SUITE_END() | ||
|
Oops, something went wrong.