Summary
@gavinandresen reported a Tor-based DoS against one of his nodes a few days ago. He found his node had run out of connection slots and his peers were almost all Tor exits, additionally, his node had stopped following the block chain (likely an inv/getdata exploit but not known for sure).
There are other patches tackling the inv/getdata issue. This patch tackles the other problem, of a jammed node using all its resources to accept connections from a DoS attacker. It lays the foundation for a resource scheduling approach to handling DoS attacks, which runs in parallel to the existing blacklist-on-badness approach.
Approach
A notion of IP groups is introduced. An IP group is a logically related set of subnets with a name and a score. The score of an ungrouped IP is zero. When a node reaches nMaxConnections, the IP of a newly accepted connection is checked against the groups and its priority thus calculated. If the priority is higher than an existing connection, that connection is dropped to make room for the new connection. If it is equal or lower then the existing behaviour of rejecting the new connection is used.
Next, a list of Tor exits is compiled into the binary (a later patch could make the download dynamic, or overridable with a local file). Tor exits get a score of -10 by default, reflecting their tendency to be used for attacks. Thus if a peer is connected to by lots of Tor exits, those connections will be serviced, but clearnet clients will take priority and if need be, kick out one of the Tor connections to make room.
This behaviour is much preferable to the more obvious solution of requiring node operators to manually ban all Tor exits during the type of attack Gavin witnessed.
Future evolution
This patch creates a base that can be evolved in future. For example, the protocol could allow peers to effectively 'buy' priority by proving ownership of coin age. This would allow e.g. an SPV wallet connecting via Tor to take priority over a DoS attack from the clearnet, thus inverting things. However such a protocol is not in this patch.
Smaller improvements might be:
- Allow loading of IP groups from a file, so people witnessing a jamming attack from other netblocks can easily de-prioritise them.
- Refresh the Tor exits list from https://check.torproject.org/ from time to time.
- Queue transactions and signature checks according to peer priority, to fix the "ban every Tor exit by sending bad signatures" attack.
- Boost the priority for peers that engage in useful behaviour, like relaying valid blocks and transactions (possibly only with an open port?).
- Slowly lower the priority for connections that seem to be idle. Thus new connections would kick out long term idle connections. This is more a solution to temporary organic load spikes than DoS attacks because of course this rule would be trivially gamed by an attacker who just disconnects and reconnects every so often.