From 7b2bfa817cb0f55f754c6457afc1ddee11f3cd2b Mon Sep 17 00:00:00 2001 From: sukun Date: Mon, 1 May 2023 12:59:03 +0530 Subject: [PATCH] allow autonatv2 servers to dial all ips --- autonat/autonat-v2.md | 71 +++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/autonat/autonat-v2.md b/autonat/autonat-v2.md index 98f938ea9..8013a2737 100644 --- a/autonat/autonat-v2.md +++ b/autonat/autonat-v2.md @@ -44,6 +44,10 @@ Compared to `autonat v1` there are two major differences testing reachability for an individual address 2. `autonat v2` provides a mechanism for nodes to verify whether the peer actually successfully dialled an address. +3. `autonat v2` provides a mechanism for nodes to dial an ip address different +from the requesting node's observed ip address without risking amplification +attacks. `autonat v1` disallowed such dials to prevent amplification attacks. + ## AutoNAT V2 Protocol @@ -62,10 +66,19 @@ of priority for verfication. Upon receiving this message the peer selects the first candidate from the list of candidates that it is capable of dialing. The peer MUST NOT dial any -candidate other than this selected candidate. It dials the selected candidate's -address, opens a stream with Protocol ID `/libp2p/autonat/2.0.0/attempt` and -sends a `DialAttempt` message with the candidate nonce. The peer MUST close this -stream after sending the `DialAttempt` message. +candidate other than this selected candidate. If this selected candidate address +has an ip address different from the requesting node's observed ip address, peer +initiates the Amplification attack prevention mechanism (see [Amplification +Attack Prevention](#amplification-attack-prevention) ). On completion, the peer +proceeds to the next step. If the selected address has the same ip address as +the requesting node's observed ip address, peer directly proceeds to the next +step skipping Amplification Attack prevention steps. + + +The peer dials the selected candidate's address, opens a stream with Protocol ID +`/libp2p/autonat/2.0.0/attempt` and sends a `DialAttempt` message with the +candidate nonce. The peer MUST close this stream after sending the `DialAttempt` +message. Upon completion of the dial attempt, the peer sends a `DialResponse` message to the initiator node on the `/libp2p/autonat/2.0.0/dial` stream with the index(0 @@ -107,26 +120,24 @@ peer that prevented it from completing the request. Implementations MUST discard responses with status codes they do not understand -### Consideration for DDOS Prevention +### Amplification Attack Prevention -In order to prevent attacks like the one described in [RFC 3489, Section -12.1.1](https://www.rfc-editor.org/rfc/rfc3489#section-12.1.1) (see excerpt -below), implementations MUST NOT dial any multiaddress unless it is based on the -IP address the requesting node is observed as. This restriction as well implies -that implementations MUST NOT accept dial requests via relayed connections as -one can not validate the IP address of the requesting node. +When a client asks a server to dial an address that is not the clients observed +ip address, the server asks the client to send him some non trivial amount of +bytes as a cost to dial a different ip address. To make amplification attacks +unattractive, the number of bytes is decided such that it's sufficiently larger +than a new connection handshake cost. -> RFC 3489 12.1.1 Attack I: DDOS Against a Target -> -> In this case, the attacker provides a large number of clients with the same -> faked MAPPED-ADDRESS that points to the intended target. This will trick all -> the STUN clients into thinking that their addresses are equal to that of the -> target. The clients then hand out that address in order to receive traffic on -> it (for example, in SIP or H.323 messages). However, all of that traffic -> becomes focused at the intended target. The attack can provide substantial -> amplification, especially when used with clients that are using STUN to enable -> multimedia applications. +On receiving a `DialRequest`, the server selects the first address it is capable +of dialing. If this selected address has a ip different from the clients +observed ip, the server sends a `DialDataRequest` message with `numBytes` set to +a sufficiently large value on the `/libp2p/autonat/2.0.0/dial-request` stream +Upon receiving a `DialDataRequest` message, the client decides whether to accept +or reject the cost of dial. If the client rejects the cost, the client resets +the stream and the `DialRequest` is considered complete. If the client accepts +the cost, the client starts transferring `numBytes` bytes to the server. The +server on receiving `numBytes` bytes proceeds to dial the candidate address. ## Implementation Suggestions @@ -154,7 +165,7 @@ bytes, encoded as an unsigned variable length integer as defined by the All RPC messages on stream `/libp2p/autonat/2.0.0/dial` are of type `DialMessage`. A `DialRequest` message is sent as a `DialMessage` with the `dialRequest` field set and the `type` field set to `DIAL_REQUEST`. -`DialResponse` is handled similarly. +`DialResponse` and `DialDataRequest` are handled similarly. On stream `/libp2p/autonat/2.0.0/attempt`, there is a single message type `AttemptMessage` @@ -164,13 +175,15 @@ syntax = "proto3"; message DialMessage { enum Type { - DIAL_REQUEST = 0; - DIAL_RESPONSE = 1; + DIAL_REQUEST = 0; + DIAL_RESPONSE = 1; + DIAL_DATA_REQUEST = 2; } Type type = 1; DialRequest dialRequest = 2; DialResponse dialResponse = 3; + DialDataRequest dialDataRequest = 4; } message Candidate { @@ -182,6 +195,10 @@ message DialRequest { repeated Candidate candidates = 1; } +message DialDataRequest { + uint64 numBytes = 1; +} + message DialResponse { enum ResponseStatus { OK = 0; @@ -190,10 +207,10 @@ message DialResponse { E_TRANSPORT_NOT_SUPPORTED = 102; E_BAD_REQUEST = 200; E_INTERNAL_ERROR = 300; - } + } - ResponseStatus status = 1; - int32 addrIdx = 2; + ResponseStatus status = 1; + int32 addrIdx = 2; } message AttemptMessage {