Rethink autonat v2 amplification attack prevention
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 1.8k
- Forks
- 320
- Avg merge
- 11d 15h
- Merged PRs (30d)
- 1
Description
This features enables the following attack:
- Contact a large number of autonat v2 servers.
- Give them the target's address to connect to
- When requested for data: provide the data slowly:
* The stream timeout is 1 minute
* In the period, with a 1Gbps connection, you can send 60Gb ~= 6GB
* Maximum dial data requirement is 100kB
* So, in theory, you can run this with 60_000 peers in parallel.
* The servers have a random wait of up to 3 seconds precisely for this scenario. So in theory we can have 20k connections a second for 3 seconds to the target.
- We can make a bunch of implementation improvements to reduce the harm here. The simplest ones being: Only wait 10 seconds for the dial data, and wait for 5 seconds before dialing. That would reduce the max new connection rate to 2k / second, which is very manageable.
- The ideal solution is to introduce rate limits for new connections.
- There's another problem with this feature related to implementation difficulty:
- The primary use for this feature is to allow both IPv4 and IPv6 addresses to be tested without worrying about whether we have a v4 or a v6 connection. So you can ask a v4 peer to test your v6 address. This requires correctly reporting an error in case the server has no v6 connectivity, which is majority of servers.
- I'm not sure if the rust implementation correctly handles this case. @umgefahren please correct me if I'm wrong here.
* See discussion around this comment: https://github.com/umgefahren/rust-libp2p/pull/1#issuecomment-2168354437- I'm also not sure if we can rely on other implementations to correctly handle this. They might just make a dial, fail, and report unreachable.
- If we have to ensure that we check v6 addresses with a v6 peer, it might be better to just disable this feature.
@MarcoPolo @Stebalien @umgefahren thoughts?
Originally posted by @sukunrt in https://github.com/libp2p/specs/pull/538#discussion_r1781405889
Avoiding a cryptographic handshake in the dial back stream will make this attack useless. All you'll get are a couple of packets from the server. Moreover, we want to check reachability for the tuple (IP4/IP6, TCP/UDP), not issues with the transport handshake implementation. For UDP, this can be implemented with a scheme similar to the one used by QUIC with Retry Packet. The server can send a UDP packet with a random 64 bit number which is echoed back by the client. We can design a similar lightweight protocol over TCP.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the autonat v2 discussion in this issue and the linked rust-libp2p pull request comment, then review the design in specs pull request 538. Done means the specification has an agreed approach that addresses amplification, defines reachability checks for IP4/IP6 and TCP/UDP, and explains behavior when the probing peer lacks the required connectivity.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100