-
Notifications
You must be signed in to change notification settings - Fork 36.5k
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
net: Feeler connections to increase online addrs in the tried table. #8282
Conversation
This pull request implements the feeler functionality in #6355. |
tests need some love... |
@paveljanik I am currently working on fixes these days, however I am running into issues with the rpc-tests. When I run rpc-tests locally both with this pull request and against bitcoin/master I get intermittent failures. I run against bitcoin/master
tests fail
I rerun it and sometimes different tests fail
Also sometimes it just crashes.
|
If you get a timeout, you may try to run the test directly Usually none of this should be a problem on travis, as a fresh vm is used every time, so you may want to look into the failure on travis. |
You should assert that nodes in the existing tests are not marked a feel connection and thus get disconnected. |
From my first glance at a failing travis test, it seems that perhaps |
@sdaftuar @MarcoFalke I'm working on a simple unittest to make sure that fFeelers is false by default and never happens when fIncoming = true. Should be pushed by EOD. |
I added a simple test and an assert to ensure that that fFeelers are set false by default and don't get assigned to incoming connection. |
Summary: To test feeler connections I ran two nodes on EC2 for ~one month. One node ran this pull request, the second node ran default Bitcoin. According to this test feeler connections (this pull request) increase the size of the tried table by about an order of magnitude and consequently increase the eclipse resistance of a node by an order of magnitude. I also measured the impact of a future pull request test-before-evict where IPs are not evicted from the tried table if they are online. Tried TableOne node ran this pull request for 32 days (July 1st to August 1st), the second node ran default Bitcoin for 35 Days (June 28 to August 1st). On August 1st I disconnected the nodes and graphed the results. I tested which nodes in the tried table were online on August 1st.
Security BenefitTo determine the security benefit of these larger numbers of IPs in the tried table I modeled the attack presented in Eclipse Attacks on Bitcoin’s Peer-to-Peer Network. Full details on how this was carried out are given at bottom of this comment. Default node: 595 attacker IPs for ~50% attack success. The node running feeler connections has 10 times as many online IP addresses in its tried table making an attack 10 times harder (i.e. requiring the an attacker require 10 times as many IP addresses in different /16s). Adding test-before-evict increases resistance of the node by an additional 3000 attacker IP addresses. Below I graph the attack over even greater attacker resources (i.e. more attacker controled IP addresses). Note that test-before-evict maintains some security far longer even against an attacker with 50,000 IPs. If this node had a larger tried table test-before-evict could greatly boost a nodes resistance to eclipse attacks. Modeling an Eclipse AttackUsing the peers.dat file from the default node and the feeler connections node I reconstructed their tried tables (I ignore the new table in our attacks as it is trivial to fill it with trash IP addresses). The attack test was run as follows:
For each value X of number of attacker IPs I ran the attack 1000 times. For each of these 1000 runs I calculated the attack success probability by performing the selection of 8 outgoing connections 10 times. I used the peers.dat file from the feelers connection node and the default node to build the model of the tried table for the attack. I simulated the impact of enabling test-before-evict would have if turned on just prior to the attack (this should not be different than if the node has been running test-before-evict all along) by preventing the attacker from evicting an IP in the tried table if that node was online. |
@@ -1609,6 +1614,7 @@ void ThreadOpenConnections() | |||
|
|||
// Initiate network connections | |||
int64_t nStart = GetTime(); | |||
int64_t nLastFeeler = GetTime(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to call GetTime() again.
Thanks a lot for the thorough analysis! Concept ACK with a few nits. I'm surprised by how little code was needed. |
How will feeler endpoints view us when we disconnect just after their |
@paveljanik Similar to oneshot connections that are used for DNS seeding over tor. |
// Add small amount of random noise before connection to avoid syncronization. | ||
int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000); | ||
MilliSleep(randsleep); | ||
LogPrint("net", "Making feeler connection to %s\n",addrConnect.ToString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space after ,
please.
Concept ACK. Nice work and interesting reading! |
bool fInboundIn = false; | ||
|
||
// Test that fFeeler is false by default. | ||
CNode* pnode1 = new CNode(hSocket, addr, pszDest, fInboundIn); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New compile warning here:
+test/net_tests.cpp:154:31: warning: variable 'hSocket' is uninitialized when used here [-Wuninitialized]
+ CNode* pnode1 = new CNode(hSocket, addr, pszDest, fInboundIn);
+ ^~~~~~~
+test/net_tests.cpp:148:19: note: initialize the variable 'hSocket' to silence this warning
+ SOCKET hSocket;
+ ^
+ = 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This compile warning has been fixed.
@@ -60,6 +63,7 @@ | |||
|
|||
namespace { | |||
const int MAX_OUTBOUND_CONNECTIONS = 8; | |||
const int MAX_FEELER_CONNECTIONS = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This constant seems not to be used other than to effectively increase MAX_OUTBOUND_CONNECTIONS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm perhaps reading the code incorrectly, but it seems that it will only ever make one feeler connection at a time, regardless of the value of this constant. I.e., increasing this value does not cause it to make concurrent feeler connections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reread the pull request and my understanding is still that MAX_FEELER_CONNECTIONS > 1 allows concurrent feeler connections. I have run tests in response to your comment which appear to show multiple concurrent feeler connections.
Would you be willing to write out your thought process which led you to the conclusion above in case there is something I am missing?
One potential niggle with feeler connections is that they cause the node_id to go up rather quickly. I think for feeler connections it might be worthwhile not incrementing the node_id since the connection is so short-lived. Perhaps the feeler connections can have a node_id of zero, or something like this? |
@@ -41,6 +41,8 @@ namespace boost { | |||
static const int PING_INTERVAL = 2 * 60; | |||
/** Time after which to disconnect, after waiting for a ping response (or inactivity). */ | |||
static const int TIMEOUT_INTERVAL = 20 * 60; | |||
/** Run the feeler connection loop once every 2 minutes or 120 seconds. **/ | |||
static const int FEELER_INTERVAL = 120; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this in net.h rather than in net.cpp? net.cpp would cause less impact on compile times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put FEELER_INTERVAL in net.h since that is where all the other net.* timing intervals static const variables are and because putting static const variables in *.h appears to be the convention in the Bitcoind networking code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bitcoin's code review process has consistently been the most thoughtful and thorough code review process I've encountered. I want to thank all the reviewers for spending their time to read my code and help improve Bitcoin. My pull requests are better for it. I realize reviewers might want to take more time to read it over carefully, but in terms of allocating my time for this week is there any particular issue that I should resolve in the next few days? |
Tests if addresses are online or offline by briefly connecting to them. These short lived connections are referred to as feeler connections. Feeler connections are designed to increase the number of fresh online addresses in tried by selecting and connecting to addresses in new. One feeler connection is attempted on average once every two minutes. This change was suggested as Countermeasure 4 in Eclipse Attacks on Bitcoin’s Peer-to-Peer Network, Ethan Heilman, Alison Kendler, Aviv Zohar, Sharon Goldberg. ePrint Archive Report 2015/263. March 2015. Backport for 0.12 from bitcoin#8282
…tried table. dbb1f64 Added feeler connections increasing good addrs in the tried table. (Ethan Heilman)
e68172e Add test-before-evict discipline to addrman (Ethan Heilman) Pull request description: This change implement countermeasures 3 (test-before-evict) suggested in our paper: ["Eclipse Attacks on Bitcoin’s Peer-to-Peer Network"](http://cs-people.bu.edu/heilman/eclipse/). # Design: A collision occurs when an address, addr1, is being moved to the tried table from the new table, but maps to a position in the tried table which already contains an address (addr2). The current behavior is that addr1 would evict addr2 from the tried table. This change ensures that during a collision, addr1 is not inserted into tried but instead inserted into a buffer (setTriedCollisions). The to-be-evicted address, addr2, is then tested by [a feeler connection](#8282). If addr2 is found to be online, we remove addr1 from the buffer and addr2 is not evicted, on the other hand if addr2 is found be offline it is replaced by addr1. An additional small advantage of this change is that, as no more than ten addresses can be in the test buffer at once, and addresses are only cleared one at a time from the test buffer (at 2 minute intervals), thus an attacker is forced to wait at least two minutes to insert a new address into tried after filling up the test buffer. This rate limits an attacker attempting to launch an eclipse attack. # Risk mitigation: - To prevent this functionality from being used as a DoS vector, we limit the number of addresses which are to be tested to ten. If we have more than ten addresses to test, we drop new addresses being added to tried if they would evict an address. Since the feeler thread only creates one new connection every 2 minutes the additional network overhead is limited. - An address in tried gains immunity from tests for 4 hours after it has been tested or successfully connected to. # Tests: This change includes additional addrman unittests which test this behavior. I ran an instance of this change with a much smaller tried table (2 buckets of 64 addresses) so that collisions were much more likely and observed evictions. ``` 2016-10-27 07:20:26 Swapping 208.12.64.252:8333 for 68.62.95.247:8333 in tried table 2016-10-27 07:20:26 Moving 208.12.64.252:8333 to tried ``` I documented tests we ran against similar earlier versions of this change in #6355. # Security Benefit This is was originally posted in PR #8282 see [this comment for full details](#8282 (comment)). To determine the security benefit of these larger numbers of IPs in the tried table I modeled the attack presented in [Eclipse Attacks on Bitcoin’s Peer-to-Peer Network](https://eprint.iacr.org/2015/263). ![attackergraph40000-10-1000short-line](https://cloud.githubusercontent.com/assets/274814/17366828/372af458-595b-11e6-81e5-2c9f97282305.png) **Default node:** 595 attacker IPs for ~50% attack success. **Default node + test-before-evict:** 620 attacker IPs for ~50% attack success. **Feeler node:** 5540 attacker IPs for ~50% attack success. **Feeler node + test-before-evict:** 8600 attacker IPs for ~50% attack success. The node running feeler connections has 10 times as many online IP addresses in its tried table making an attack 10 times harder (i.e. requiring the an attacker require 10 times as many IP addresses in different /16s). Adding test-before-evict increases resistance of the node by an additional 3000 attacker IP addresses. Below I graph the attack over even greater attacker resources (i.e. more attacker controled IP addresses). Note that test-before-evict maintains some security far longer even against an attacker with 50,000 IPs. If this node had a larger tried table test-before-evict could greatly boost a nodes resistance to eclipse attacks. ![attacker graph long view](https://cloud.githubusercontent.com/assets/274814/17367108/96f46d64-595c-11e6-91cd-edba160598e7.png) Tree-SHA512: fdad4d26aadeaad9bcdc71929b3eb4e1f855b3ee3541fbfbe25dca8d7d0a1667815402db0cb4319db6bd3fcd32d67b5bbc0e12045c4252d62d6239b7d77c4395
e68172e Add test-before-evict discipline to addrman (Ethan Heilman) Pull request description: This change implement countermeasures 3 (test-before-evict) suggested in our paper: ["Eclipse Attacks on Bitcoin’s Peer-to-Peer Network"](http://cs-people.bu.edu/heilman/eclipse/). # Design: A collision occurs when an address, addr1, is being moved to the tried table from the new table, but maps to a position in the tried table which already contains an address (addr2). The current behavior is that addr1 would evict addr2 from the tried table. This change ensures that during a collision, addr1 is not inserted into tried but instead inserted into a buffer (setTriedCollisions). The to-be-evicted address, addr2, is then tested by [a feeler connection](bitcoin#8282). If addr2 is found to be online, we remove addr1 from the buffer and addr2 is not evicted, on the other hand if addr2 is found be offline it is replaced by addr1. An additional small advantage of this change is that, as no more than ten addresses can be in the test buffer at once, and addresses are only cleared one at a time from the test buffer (at 2 minute intervals), thus an attacker is forced to wait at least two minutes to insert a new address into tried after filling up the test buffer. This rate limits an attacker attempting to launch an eclipse attack. # Risk mitigation: - To prevent this functionality from being used as a DoS vector, we limit the number of addresses which are to be tested to ten. If we have more than ten addresses to test, we drop new addresses being added to tried if they would evict an address. Since the feeler thread only creates one new connection every 2 minutes the additional network overhead is limited. - An address in tried gains immunity from tests for 4 hours after it has been tested or successfully connected to. # Tests: This change includes additional addrman unittests which test this behavior. I ran an instance of this change with a much smaller tried table (2 buckets of 64 addresses) so that collisions were much more likely and observed evictions. ``` 2016-10-27 07:20:26 Swapping 208.12.64.252:8333 for 68.62.95.247:8333 in tried table 2016-10-27 07:20:26 Moving 208.12.64.252:8333 to tried ``` I documented tests we ran against similar earlier versions of this change in dashpay#6355. # Security Benefit This is was originally posted in PR bitcoin#8282 see [this comment for full details](bitcoin#8282 (comment)). To determine the security benefit of these larger numbers of IPs in the tried table I modeled the attack presented in [Eclipse Attacks on Bitcoin’s Peer-to-Peer Network](https://eprint.iacr.org/2015/263). ![attackergraph40000-10-1000short-line](https://cloud.githubusercontent.com/assets/274814/17366828/372af458-595b-11e6-81e5-2c9f97282305.png) **Default node:** 595 attacker IPs for ~50% attack success. **Default node + test-before-evict:** 620 attacker IPs for ~50% attack success. **Feeler node:** 5540 attacker IPs for ~50% attack success. **Feeler node + test-before-evict:** 8600 attacker IPs for ~50% attack success. The node running feeler connections has 10 times as many online IP addresses in its tried table making an attack 10 times harder (i.e. requiring the an attacker require 10 times as many IP addresses in different /16s). Adding test-before-evict increases resistance of the node by an additional 3000 attacker IP addresses. Below I graph the attack over even greater attacker resources (i.e. more attacker controled IP addresses). Note that test-before-evict maintains some security far longer even against an attacker with 50,000 IPs. If this node had a larger tried table test-before-evict could greatly boost a nodes resistance to eclipse attacks. ![attacker graph long view](https://cloud.githubusercontent.com/assets/274814/17367108/96f46d64-595c-11e6-91cd-edba160598e7.png) Tree-SHA512: fdad4d26aadeaad9bcdc71929b3eb4e1f855b3ee3541fbfbe25dca8d7d0a1667815402db0cb4319db6bd3fcd32d67b5bbc0e12045c4252d62d6239b7d77c4395
e68172e Add test-before-evict discipline to addrman (Ethan Heilman) Pull request description: This change implement countermeasures 3 (test-before-evict) suggested in our paper: ["Eclipse Attacks on Bitcoin’s Peer-to-Peer Network"](http://cs-people.bu.edu/heilman/eclipse/). # Design: A collision occurs when an address, addr1, is being moved to the tried table from the new table, but maps to a position in the tried table which already contains an address (addr2). The current behavior is that addr1 would evict addr2 from the tried table. This change ensures that during a collision, addr1 is not inserted into tried but instead inserted into a buffer (setTriedCollisions). The to-be-evicted address, addr2, is then tested by [a feeler connection](bitcoin#8282). If addr2 is found to be online, we remove addr1 from the buffer and addr2 is not evicted, on the other hand if addr2 is found be offline it is replaced by addr1. An additional small advantage of this change is that, as no more than ten addresses can be in the test buffer at once, and addresses are only cleared one at a time from the test buffer (at 2 minute intervals), thus an attacker is forced to wait at least two minutes to insert a new address into tried after filling up the test buffer. This rate limits an attacker attempting to launch an eclipse attack. # Risk mitigation: - To prevent this functionality from being used as a DoS vector, we limit the number of addresses which are to be tested to ten. If we have more than ten addresses to test, we drop new addresses being added to tried if they would evict an address. Since the feeler thread only creates one new connection every 2 minutes the additional network overhead is limited. - An address in tried gains immunity from tests for 4 hours after it has been tested or successfully connected to. # Tests: This change includes additional addrman unittests which test this behavior. I ran an instance of this change with a much smaller tried table (2 buckets of 64 addresses) so that collisions were much more likely and observed evictions. ``` 2016-10-27 07:20:26 Swapping 208.12.64.252:8333 for 68.62.95.247:8333 in tried table 2016-10-27 07:20:26 Moving 208.12.64.252:8333 to tried ``` I documented tests we ran against similar earlier versions of this change in dashpay#6355. # Security Benefit This is was originally posted in PR bitcoin#8282 see [this comment for full details](bitcoin#8282 (comment)). To determine the security benefit of these larger numbers of IPs in the tried table I modeled the attack presented in [Eclipse Attacks on Bitcoin’s Peer-to-Peer Network](https://eprint.iacr.org/2015/263). ![attackergraph40000-10-1000short-line](https://cloud.githubusercontent.com/assets/274814/17366828/372af458-595b-11e6-81e5-2c9f97282305.png) **Default node:** 595 attacker IPs for ~50% attack success. **Default node + test-before-evict:** 620 attacker IPs for ~50% attack success. **Feeler node:** 5540 attacker IPs for ~50% attack success. **Feeler node + test-before-evict:** 8600 attacker IPs for ~50% attack success. The node running feeler connections has 10 times as many online IP addresses in its tried table making an attack 10 times harder (i.e. requiring the an attacker require 10 times as many IP addresses in different /16s). Adding test-before-evict increases resistance of the node by an additional 3000 attacker IP addresses. Below I graph the attack over even greater attacker resources (i.e. more attacker controled IP addresses). Note that test-before-evict maintains some security far longer even against an attacker with 50,000 IPs. If this node had a larger tried table test-before-evict could greatly boost a nodes resistance to eclipse attacks. ![attacker graph long view](https://cloud.githubusercontent.com/assets/274814/17367108/96f46d64-595c-11e6-91cd-edba160598e7.png) Tree-SHA512: fdad4d26aadeaad9bcdc71929b3eb4e1f855b3ee3541fbfbe25dca8d7d0a1667815402db0cb4319db6bd3fcd32d67b5bbc0e12045c4252d62d6239b7d77c4395
e68172e Add test-before-evict discipline to addrman (Ethan Heilman) Pull request description: This change implement countermeasures 3 (test-before-evict) suggested in our paper: ["Eclipse Attacks on Bitcoin’s Peer-to-Peer Network"](http://cs-people.bu.edu/heilman/eclipse/). # Design: A collision occurs when an address, addr1, is being moved to the tried table from the new table, but maps to a position in the tried table which already contains an address (addr2). The current behavior is that addr1 would evict addr2 from the tried table. This change ensures that during a collision, addr1 is not inserted into tried but instead inserted into a buffer (setTriedCollisions). The to-be-evicted address, addr2, is then tested by [a feeler connection](bitcoin#8282). If addr2 is found to be online, we remove addr1 from the buffer and addr2 is not evicted, on the other hand if addr2 is found be offline it is replaced by addr1. An additional small advantage of this change is that, as no more than ten addresses can be in the test buffer at once, and addresses are only cleared one at a time from the test buffer (at 2 minute intervals), thus an attacker is forced to wait at least two minutes to insert a new address into tried after filling up the test buffer. This rate limits an attacker attempting to launch an eclipse attack. # Risk mitigation: - To prevent this functionality from being used as a DoS vector, we limit the number of addresses which are to be tested to ten. If we have more than ten addresses to test, we drop new addresses being added to tried if they would evict an address. Since the feeler thread only creates one new connection every 2 minutes the additional network overhead is limited. - An address in tried gains immunity from tests for 4 hours after it has been tested or successfully connected to. # Tests: This change includes additional addrman unittests which test this behavior. I ran an instance of this change with a much smaller tried table (2 buckets of 64 addresses) so that collisions were much more likely and observed evictions. ``` 2016-10-27 07:20:26 Swapping 208.12.64.252:8333 for 68.62.95.247:8333 in tried table 2016-10-27 07:20:26 Moving 208.12.64.252:8333 to tried ``` I documented tests we ran against similar earlier versions of this change in dashpay#6355. # Security Benefit This is was originally posted in PR bitcoin#8282 see [this comment for full details](bitcoin#8282 (comment)). To determine the security benefit of these larger numbers of IPs in the tried table I modeled the attack presented in [Eclipse Attacks on Bitcoin’s Peer-to-Peer Network](https://eprint.iacr.org/2015/263). ![attackergraph40000-10-1000short-line](https://cloud.githubusercontent.com/assets/274814/17366828/372af458-595b-11e6-81e5-2c9f97282305.png) **Default node:** 595 attacker IPs for ~50% attack success. **Default node + test-before-evict:** 620 attacker IPs for ~50% attack success. **Feeler node:** 5540 attacker IPs for ~50% attack success. **Feeler node + test-before-evict:** 8600 attacker IPs for ~50% attack success. The node running feeler connections has 10 times as many online IP addresses in its tried table making an attack 10 times harder (i.e. requiring the an attacker require 10 times as many IP addresses in different /16s). Adding test-before-evict increases resistance of the node by an additional 3000 attacker IP addresses. Below I graph the attack over even greater attacker resources (i.e. more attacker controled IP addresses). Note that test-before-evict maintains some security far longer even against an attacker with 50,000 IPs. If this node had a larger tried table test-before-evict could greatly boost a nodes resistance to eclipse attacks. ![attacker graph long view](https://cloud.githubusercontent.com/assets/274814/17367108/96f46d64-595c-11e6-91cd-edba160598e7.png) Tree-SHA512: fdad4d26aadeaad9bcdc71929b3eb4e1f855b3ee3541fbfbe25dca8d7d0a1667815402db0cb4319db6bd3fcd32d67b5bbc0e12045c4252d62d6239b7d77c4395
e68172e Add test-before-evict discipline to addrman (Ethan Heilman) Pull request description: This change implement countermeasures 3 (test-before-evict) suggested in our paper: ["Eclipse Attacks on Bitcoin’s Peer-to-Peer Network"](http://cs-people.bu.edu/heilman/eclipse/). # Design: A collision occurs when an address, addr1, is being moved to the tried table from the new table, but maps to a position in the tried table which already contains an address (addr2). The current behavior is that addr1 would evict addr2 from the tried table. This change ensures that during a collision, addr1 is not inserted into tried but instead inserted into a buffer (setTriedCollisions). The to-be-evicted address, addr2, is then tested by [a feeler connection](bitcoin#8282). If addr2 is found to be online, we remove addr1 from the buffer and addr2 is not evicted, on the other hand if addr2 is found be offline it is replaced by addr1. An additional small advantage of this change is that, as no more than ten addresses can be in the test buffer at once, and addresses are only cleared one at a time from the test buffer (at 2 minute intervals), thus an attacker is forced to wait at least two minutes to insert a new address into tried after filling up the test buffer. This rate limits an attacker attempting to launch an eclipse attack. # Risk mitigation: - To prevent this functionality from being used as a DoS vector, we limit the number of addresses which are to be tested to ten. If we have more than ten addresses to test, we drop new addresses being added to tried if they would evict an address. Since the feeler thread only creates one new connection every 2 minutes the additional network overhead is limited. - An address in tried gains immunity from tests for 4 hours after it has been tested or successfully connected to. # Tests: This change includes additional addrman unittests which test this behavior. I ran an instance of this change with a much smaller tried table (2 buckets of 64 addresses) so that collisions were much more likely and observed evictions. ``` 2016-10-27 07:20:26 Swapping 208.12.64.252:8333 for 68.62.95.247:8333 in tried table 2016-10-27 07:20:26 Moving 208.12.64.252:8333 to tried ``` I documented tests we ran against similar earlier versions of this change in dashpay#6355. # Security Benefit This is was originally posted in PR bitcoin#8282 see [this comment for full details](bitcoin#8282 (comment)). To determine the security benefit of these larger numbers of IPs in the tried table I modeled the attack presented in [Eclipse Attacks on Bitcoin’s Peer-to-Peer Network](https://eprint.iacr.org/2015/263). ![attackergraph40000-10-1000short-line](https://cloud.githubusercontent.com/assets/274814/17366828/372af458-595b-11e6-81e5-2c9f97282305.png) **Default node:** 595 attacker IPs for ~50% attack success. **Default node + test-before-evict:** 620 attacker IPs for ~50% attack success. **Feeler node:** 5540 attacker IPs for ~50% attack success. **Feeler node + test-before-evict:** 8600 attacker IPs for ~50% attack success. The node running feeler connections has 10 times as many online IP addresses in its tried table making an attack 10 times harder (i.e. requiring the an attacker require 10 times as many IP addresses in different /16s). Adding test-before-evict increases resistance of the node by an additional 3000 attacker IP addresses. Below I graph the attack over even greater attacker resources (i.e. more attacker controled IP addresses). Note that test-before-evict maintains some security far longer even against an attacker with 50,000 IPs. If this node had a larger tried table test-before-evict could greatly boost a nodes resistance to eclipse attacks. ![attacker graph long view](https://cloud.githubusercontent.com/assets/274814/17367108/96f46d64-595c-11e6-91cd-edba160598e7.png) Tree-SHA512: fdad4d26aadeaad9bcdc71929b3eb4e1f855b3ee3541fbfbe25dca8d7d0a1667815402db0cb4319db6bd3fcd32d67b5bbc0e12045c4252d62d6239b7d77c4395
e68172e Add test-before-evict discipline to addrman (Ethan Heilman) Pull request description: This change implement countermeasures 3 (test-before-evict) suggested in our paper: ["Eclipse Attacks on Bitcoin’s Peer-to-Peer Network"](http://cs-people.bu.edu/heilman/eclipse/). # Design: A collision occurs when an address, addr1, is being moved to the tried table from the new table, but maps to a position in the tried table which already contains an address (addr2). The current behavior is that addr1 would evict addr2 from the tried table. This change ensures that during a collision, addr1 is not inserted into tried but instead inserted into a buffer (setTriedCollisions). The to-be-evicted address, addr2, is then tested by [a feeler connection](bitcoin#8282). If addr2 is found to be online, we remove addr1 from the buffer and addr2 is not evicted, on the other hand if addr2 is found be offline it is replaced by addr1. An additional small advantage of this change is that, as no more than ten addresses can be in the test buffer at once, and addresses are only cleared one at a time from the test buffer (at 2 minute intervals), thus an attacker is forced to wait at least two minutes to insert a new address into tried after filling up the test buffer. This rate limits an attacker attempting to launch an eclipse attack. # Risk mitigation: - To prevent this functionality from being used as a DoS vector, we limit the number of addresses which are to be tested to ten. If we have more than ten addresses to test, we drop new addresses being added to tried if they would evict an address. Since the feeler thread only creates one new connection every 2 minutes the additional network overhead is limited. - An address in tried gains immunity from tests for 4 hours after it has been tested or successfully connected to. # Tests: This change includes additional addrman unittests which test this behavior. I ran an instance of this change with a much smaller tried table (2 buckets of 64 addresses) so that collisions were much more likely and observed evictions. ``` 2016-10-27 07:20:26 Swapping 208.12.64.252:8333 for 68.62.95.247:8333 in tried table 2016-10-27 07:20:26 Moving 208.12.64.252:8333 to tried ``` I documented tests we ran against similar earlier versions of this change in dashpay#6355. # Security Benefit This is was originally posted in PR bitcoin#8282 see [this comment for full details](bitcoin#8282 (comment)). To determine the security benefit of these larger numbers of IPs in the tried table I modeled the attack presented in [Eclipse Attacks on Bitcoin’s Peer-to-Peer Network](https://eprint.iacr.org/2015/263). ![attackergraph40000-10-1000short-line](https://cloud.githubusercontent.com/assets/274814/17366828/372af458-595b-11e6-81e5-2c9f97282305.png) **Default node:** 595 attacker IPs for ~50% attack success. **Default node + test-before-evict:** 620 attacker IPs for ~50% attack success. **Feeler node:** 5540 attacker IPs for ~50% attack success. **Feeler node + test-before-evict:** 8600 attacker IPs for ~50% attack success. The node running feeler connections has 10 times as many online IP addresses in its tried table making an attack 10 times harder (i.e. requiring the an attacker require 10 times as many IP addresses in different /16s). Adding test-before-evict increases resistance of the node by an additional 3000 attacker IP addresses. Below I graph the attack over even greater attacker resources (i.e. more attacker controled IP addresses). Note that test-before-evict maintains some security far longer even against an attacker with 50,000 IPs. If this node had a larger tried table test-before-evict could greatly boost a nodes resistance to eclipse attacks. ![attacker graph long view](https://cloud.githubusercontent.com/assets/274814/17367108/96f46d64-595c-11e6-91cd-edba160598e7.png) Tree-SHA512: fdad4d26aadeaad9bcdc71929b3eb4e1f855b3ee3541fbfbe25dca8d7d0a1667815402db0cb4319db6bd3fcd32d67b5bbc0e12045c4252d62d6239b7d77c4395
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
e68172e Add test-before-evict discipline to addrman (Ethan Heilman) Pull request description: This change implement countermeasures 3 (test-before-evict) suggested in our paper: ["Eclipse Attacks on Bitcoin’s Peer-to-Peer Network"](http://cs-people.bu.edu/heilman/eclipse/). # Design: A collision occurs when an address, addr1, is being moved to the tried table from the new table, but maps to a position in the tried table which already contains an address (addr2). The current behavior is that addr1 would evict addr2 from the tried table. This change ensures that during a collision, addr1 is not inserted into tried but instead inserted into a buffer (setTriedCollisions). The to-be-evicted address, addr2, is then tested by [a feeler connection](bitcoin#8282). If addr2 is found to be online, we remove addr1 from the buffer and addr2 is not evicted, on the other hand if addr2 is found be offline it is replaced by addr1. An additional small advantage of this change is that, as no more than ten addresses can be in the test buffer at once, and addresses are only cleared one at a time from the test buffer (at 2 minute intervals), thus an attacker is forced to wait at least two minutes to insert a new address into tried after filling up the test buffer. This rate limits an attacker attempting to launch an eclipse attack. # Risk mitigation: - To prevent this functionality from being used as a DoS vector, we limit the number of addresses which are to be tested to ten. If we have more than ten addresses to test, we drop new addresses being added to tried if they would evict an address. Since the feeler thread only creates one new connection every 2 minutes the additional network overhead is limited. - An address in tried gains immunity from tests for 4 hours after it has been tested or successfully connected to. # Tests: This change includes additional addrman unittests which test this behavior. I ran an instance of this change with a much smaller tried table (2 buckets of 64 addresses) so that collisions were much more likely and observed evictions. ``` 2016-10-27 07:20:26 Swapping 208.12.64.252:8333 for 68.62.95.247:8333 in tried table 2016-10-27 07:20:26 Moving 208.12.64.252:8333 to tried ``` I documented tests we ran against similar earlier versions of this change in dashpay#6355. # Security Benefit This is was originally posted in PR bitcoin#8282 see [this comment for full details](bitcoin#8282 (comment)). To determine the security benefit of these larger numbers of IPs in the tried table I modeled the attack presented in [Eclipse Attacks on Bitcoin’s Peer-to-Peer Network](https://eprint.iacr.org/2015/263). ![attackergraph40000-10-1000short-line](https://cloud.githubusercontent.com/assets/274814/17366828/372af458-595b-11e6-81e5-2c9f97282305.png) **Default node:** 595 attacker IPs for ~50% attack success. **Default node + test-before-evict:** 620 attacker IPs for ~50% attack success. **Feeler node:** 5540 attacker IPs for ~50% attack success. **Feeler node + test-before-evict:** 8600 attacker IPs for ~50% attack success. The node running feeler connections has 10 times as many online IP addresses in its tried table making an attack 10 times harder (i.e. requiring the an attacker require 10 times as many IP addresses in different /16s). Adding test-before-evict increases resistance of the node by an additional 3000 attacker IP addresses. Below I graph the attack over even greater attacker resources (i.e. more attacker controled IP addresses). Note that test-before-evict maintains some security far longer even against an attacker with 50,000 IPs. If this node had a larger tried table test-before-evict could greatly boost a nodes resistance to eclipse attacks. ![attacker graph long view](https://cloud.githubusercontent.com/assets/274814/17367108/96f46d64-595c-11e6-91cd-edba160598e7.png) Tree-SHA512: fdad4d26aadeaad9bcdc71929b3eb4e1f855b3ee3541fbfbe25dca8d7d0a1667815402db0cb4319db6bd3fcd32d67b5bbc0e12045c4252d62d6239b7d77c4395
These changes implement countermeasures 3 (feeler connections) suggested in our paper: "Eclipse Attacks on Bitcoin’s Peer-to-Peer Network".
Design:
We observe that a node's resistance to eclipse attacks grows as the number of online addresses in the tried table grows. To increase the number of online addresses in the tried table the following logic is implemented in net.cpp's ThreadOpenConnections:
Only one feeler connection is attempted at any one time and feeler connections are only attempted after all outgoing connections slots of filled.
Advantages:
Risk mitigation:
Test plan:
This change was suggested as Countermeasure 4 in
Eclipse Attacks on Bitcoin’s Peer-to-Peer Network,
Ethan Heilman, Alison Kendler, Aviv Zohar, Sharon Goldberg.
ePrint Archive Report 2015/263. March 2015.