Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection slot exhaustion DoS mitigation #6374

Merged
merged 15 commits into from
Sep 3, 2015
Merged

Connection slot exhaustion DoS mitigation #6374

merged 15 commits into from
Sep 3, 2015

Conversation

pstratem
Copy link
Contributor

@pstratem pstratem commented Jul 4, 2015

Connection slots are a limited resource which can be the target of DoS attacks.

This issue was introduced in 2011 by 5a3e82f.

In mitigating this issue it is important to take steps to avoid network partitioning.

I have taken the approach of protecting connections with various properties from eviction.

Of the nodes still available for eviction the most recently connected node from the CNetAddr with the most connections is selected and evicted.

The largest class of protected connections is those which have been connected for the longest time.
The intent is to maintain the strong bias towards these connections which exists today and thus avoid any risk of network partition.

@laanwj laanwj added the P2P label Jul 5, 2015
@pstratem
Copy link
Contributor Author

pstratem commented Jul 5, 2015

This has been tested by setting up a node and then connected to it from the same source ip in a loop.

Additional testing is needed around multiple source ips.

@laanwj
Copy link
Member

laanwj commented Jul 5, 2015

Concept ACK

This does need extensive testing in various scenarios - e.g. what happens with Tor hidden service connections, which all appear to come from one IP (localhost) address.

@pstratem
Copy link
Contributor Author

pstratem commented Jul 5, 2015

Tested with multiple inbound connections from 128+ source ips.

Long lived connections were stable and the newer connections dropped.

@petertodd
Copy link
Contributor

@pstratem How did you actually test that?

We could make good use of automated scripts to make such testing relocatable.

@pstratem
Copy link
Contributor Author

pstratem commented Jul 6, 2015

@petertodd python script that connects to the node in a loop running on top of torify and me sitting there hitting "new identity" in vidalia a bunch until i had unique ips connecting...

not exactly an automated process

@pstratem
Copy link
Contributor Author

@laanwj Missed the second part of your comment.

This wont ever evict localhost connections, so inbound connections to a hidden service wont ever be disconnected by this.

That's actually not optimal, but unfortunately getting info on inbound hidden service connections requires interfacing with tors control port.

That's definitely out of scope for this patch set.

@laanwj
Copy link
Member

laanwj commented Jul 28, 2015

@pstratem Absolutely - I wasn't implying that you'd have to interact with Tor's control port in this pull, just that it's a requirement that it didn't make the current situation worse.

Needs a trivial rebase in net.cpp due to #5288.

CloseSocket(hSocket);
delete pnode;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleting CNodes happens in the "Delete disconnected nodes" loop, which first makes sure that no one is using the node anymore. Adding a delete pnode here seems like a danger for race conditions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is deleting the CNode which was created at 984 and which was not added to vNodes.

Not deleting it here would be a memory leak.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bah.
I wonder if we could use e.g. boost::scoped_ptr or auto_ptr to avoid this. It's too easy to get memory leaks with manual deallocation along a subset of code paths, especially when factoring in exceptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively I could just add it to vNodes and rely on the normal cleanup logic.

@TheBlueMatt
Copy link
Contributor

Spoke with @pstratem about this for a bit and we agreed this should be refactored so that the connection acceptance stuff is in a separate function. Also after this change the nWhiteConnections variable is set in init but goes unused.

@pstratem
Copy link
Contributor Author

@TheBlueMatt I've simply removed the whiteconnections option in favor of protecting any inbound whitelisted connection. This is safe as outbound connections are never disconnected.

BOOST_FOREACH(CNode *node, vEvictionCandidates) {
mapAddrCounts[node->addr].push_back(node);

if (mapAddrCounts[node->addr].size() > nMostConnections) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size_t to unsigned int is safe? You could use size_t for nMostConnections also.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is almost certainly safe because the values are heavily constrained, however it's not an issue to switch to size_t so I will

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Diapolo aren't there warnings for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dcousens they're both unsigned, so no

@dcousens
Copy link
Contributor

Concept ACK

@laanwj
Copy link
Member

laanwj commented Aug 17, 2015

I think i'm missing a thing: how does this change make whiteconnections redundant? There is no information in the commit message.

@pstratem
Copy link
Contributor Author

@laanwj All whitelisted connections are protected. Which makes a parameter for protecting a specific number of whitelisted connections redundant.

continue;
if (node->addr.IsLocal())
continue;
vEvictionCandidates.push_back(node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dont you need to increment the use count on the node here?

@sipa
Copy link
Member

sipa commented Aug 25, 2015

@pstratem I'm going through the commits one by one.

@pstratem
Copy link
Contributor Author

@sipa ah ok then

@sipa
Copy link
Member

sipa commented Aug 25, 2015

Concept ACK. I think that calling AddRef/Release without holding cs_vNodes should not be done.

I think the biases can be improved still - for example by computing a score per node based on ping time, and then penalizing the scores of nodes from the same netgroup if there are multiple. But that can be done later.

@pstratem
Copy link
Contributor Author

@sipa this is definitely intended mostly as a framework, the initial rules are an improvement but certainly not intended to be the final set of rules.

@laanwj
Copy link
Member

laanwj commented Sep 3, 2015

utACK

@laanwj laanwj merged commit 027de94 into bitcoin:master Sep 3, 2015
laanwj added a commit that referenced this pull request Sep 3, 2015
027de94 Use network group instead of CNetAddr in final pass to select node to disconnect (Patrick Strateman)
000c18a Fix comment (Patrick Strateman)
fed3094 Acquire cs_vNodes before changing refrence counts (Patrick Strateman)
69ee1aa CNodeRef copy constructor and assignment operator (Patrick Strateman)
dc81dd0 Return false early if vEvictionCandidates is empty (Patrick Strateman)
17f3533 Better support for nodes with non-standard nMaxConnections (Patrick Strateman)
1317cd1 RAII wrapper for CNode* (Patrick Strateman)
df23937 Add comments to AttemptToEvictConnection (Patrick Strateman)
a8f6e45 Remove redundant whiteconnections option (Patrick Strateman)
b105ba3 Prefer to disconnect peers in favor of whitelisted peers (Patrick Strateman)
2c70153 AttemptToEvictConnection (Patrick Strateman)
4bac601 Record nMinPingUsecTime (Patrick Strateman)
ae037b7 Refactor: Move failure conditions to the top of AcceptConnection (Patrick Strateman)
1ef4817 Refactor: Bail early in AcceptConnection (Patrick Strateman)
541a1dd Refactor: AcceptConnection (Patrick Strateman)
str4d pushed a commit to str4d/zcash that referenced this pull request Nov 9, 2017
Zcash: Was "Added -whiteconnections=<n> option" from bitcoin/bitcoin#5288. The
option was later removed in bitcoin/bitcoin#6374 which we merged in zcash#1258. This
commit contains the difference between the two.
str4d pushed a commit to str4d/zcash that referenced this pull request Apr 5, 2018
Zcash: Was "Added -whiteconnections=<n> option" from bitcoin/bitcoin#5288. The
option was later removed in bitcoin/bitcoin#6374 which we merged in zcash#1258. This
commit contains the difference between the two.
random-zebra added a commit to PIVX-Project/PIVX that referenced this pull request Jul 1, 2020
6f41b3e [QA] Missing mempool sync in pos_coldStaking and zc_publicspends tests (random-zebra)
efaf727 net: correctly initialize nMinPingUsecTime (Wladimir J. van der Laan)
61c8ffe Do not add random inbound peers to addrman. (Gregory Maxwell)
e6a1726 Added feeler connections increasing good addrs in the tried table. (Ethan Heilman)
070b6fb Actually only use filterInventoryKnown with MSG_TX inventory messages. (Gregory Maxwell)
9ac6b28 Only use filterInventoryKnown with MSG_TX inventory messages. (Patick Strateman)
01273db Rename setInventoryKnown filterInventoryKnown (Patick Strateman)
4f11eb2 Remove mruset as it is no longer used. (Gregory Maxwell)
2e3b05c Replace setInventoryKnown with a rolling bloom filter. (Gregory Maxwell)
409aa83 Replace trickle nodes with per-node/message Poisson delays (Pieter Wuille)
93e8c46 Move recentRejects initialization to top of InitBlockIndex (Wladimir J. van der Laan)
9a59420 Keep track of recently rejected transactions (Peter Todd)
34ee777 Only use randomly created nonces in CRollingBloomFilter. (Pieter Wuille)
338d346 Make CRollingBloomFilter set nTweak for you (Peter Todd)
dcd15bc Reuse vector hashing code for uint256 (Pieter Wuille)
3230143 Add uint256 support to CRollingBloomFilter (Peter Todd)
128d644 Better mruset unit test (Pieter Wuille)
89740ed Use ring buffer of set iterators instead of deque of copies in mruset (Pieter Wuille)
14c88ee Replace mruset setAddrKnown with CRollingBloomFilter addrKnown (Gavin Andresen)
e0bebbd Rolling bloom filter class (Gavin Andresen)
7c03bd5 Add correct bool combiner for net signals (Pieter Wuille)
5cb5fd6 Stop exporting ConnectNode (Fuzzbawls)
819295d Stop using ConnectNode in layer 2 code (Fuzzbawls)
851b6b4 net: No need to export DumpBanlist (Cory Fields)
4486d4e net: make Ban/Unban/ClearBan functionality consistent (Cory Fields)
a5e278d net: Drop CNodeRef for AttemptToEvictConnection (Cory Fields)
9fd357d net: use the exposed GetNodeSignals() rather than g_signals directly (Cory Fields)
7962bcc net: remove unused set (Cory Fields)
fabf358 Use network group instead of CNetAddr in final pass to select node to disconnect (Patrick Strateman)
7f030fe Fix comment (Patrick Strateman)
18af800 Acquire cs_vNodes before changing refrence counts (Patrick Strateman)
7aa827f CNodeRef copy constructor and assignment operator (Patrick Strateman)
b3f95e7 Return false early if vEvictionCandidates is empty (Patrick Strateman)
85886c9 Better support for nodes with non-standard nMaxConnections (Patrick Strateman)
9c9e55b RAII wrapper for CNode* (Patrick Strateman)
e92780d Add comments to AttemptToEvictConnection (Patrick Strateman)
0ca7ce3 Prefer to disconnect peers in favor of whitelisted peers (Patrick Strateman)
a1c4aaf AttemptToEvictConnection (Patrick Strateman)
aa7ce9b Record nMinPingUsecTime (Patrick Strateman)
fd7bab0 Refactor: Move failure conditions to the top of AcceptConnection (Patrick Strateman)
fcb732b Refactor: Bail early in AcceptConnection (Patrick Strateman)
411766d Refactor: AcceptConnection (Patrick Strateman)

Pull request description:

  This is a culmination of several upstream PRs touching the P2P/Networking code, and resulting in a state just prior to the P2P/Network encapsulation, which will be it's own PR.

  Backported upstream PRs included here:
  - bitcoin#5859
  - bitcoin#6064
  - bitcoin#6374
  - bitcoin#6498
  - bitcoin#6636
  - bitcoin#7133
  - bitcoin#7125
  - bitcoin#7906
  - bitcoin#8282
  - bitcoin#8594

ACKs for top commit:
  random-zebra:
    Great job. ACK 6f41b3e and merging...
  furszy:
    Have been running it the past days and all is looking good, ACK 6f41b3e .

Tree-SHA512: 1cc4b1271516f000a06141b5b069f3ee00f3eb77056e40d2c021c484f749d9d8db2b76ce490f63572372705b646fad342666f6f90ca5fc69abcacf7b207d058f
zkbot added a commit to zcash/zcash that referenced this pull request Feb 17, 2021
Use SipHash for node eviction

Backport of bitcoin/bitcoin#8173

Commits are listed in stack order.

- pick bitcoin/bitcoin@eebc232187
- pick bitcoin/bitcoin@888483098e
- pick bitcoin/bitcoin@c31b24f745
- pick bitcoin/bitcoin@9bf156bb9e
- pick bitcoin/bitcoin@053930ffc4
   - missing bitcoin/bitcoin#5697 (not a candidate for direct inclusion), using pieces directly
   - conflicts with #1258 which it removes part of (this is ok)
      - ignore bitcoin/bitcoin#6374
      - requires bitcoin/bitcoin#7906, or at least bitcoin/bitcoin@cca221fd21
         - pick bitcoin/bitcoin@cca221fd21
   - conflicts with bitcoin/bitcoin#7181, not needed until later if at all
str4d pushed a commit to str4d/zcash that referenced this pull request Feb 18, 2021
Zcash: Was "Added -whiteconnections=<n> option" from bitcoin/bitcoin#5288. The
option was later removed in bitcoin/bitcoin#6374 which we merged in zcash#1258. This
commit contains the difference between the two.
zkbot added a commit to zcash/zcash that referenced this pull request Feb 19, 2021
Bitcoin 0.12 misc P2P/Net PRs

Cherry-picked from the following upstream PRs:

- bitcoin/bitcoin#5288
  - Only the reorg, option was removed in bitcoin/bitcoin#6374 which we merged in #1258
- bitcoin/bitcoin#6561
- bitcoin/bitcoin#6728
- bitcoin/bitcoin#6829
- bitcoin/bitcoin#6974
- bitcoin/bitcoin#7075
- bitcoin/bitcoin#7166

Part of #2074.
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants