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

Rethink autonat v2 amplification attack prevention #640

Open
sukunrt opened this issue Nov 6, 2024 · 0 comments
Open

Rethink autonat v2 amplification attack prevention #640

sukunrt opened this issue Nov 6, 2024 · 0 comments

Comments

@sukunrt
Copy link
Member

sukunrt commented Nov 6, 2024

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: feat(autonatv2): Implement autonat v2 umgefahren/rust-libp2p#1 (comment)
    • 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 #538 (comment)

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Triage
Development

No branches or pull requests

1 participant