STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)
obsoleted by
- rfc-5389 — Session Traversal Utilities for NAT (STUN)
Extracted elements (30)
A stateless STUN server can satisfy all username/password requirements by encoding the USERNAME as a prefix, rounded-time, clientIP, and an HMAC over those fields using a private key, then computing the PASSWORD as HMAC(USERNAME, another-private-key). This embeds the source IP of the Shared Secret Request in the USERNAME so the server can construct REFLECTED-FROM without storing state.
STUN requires no modifications to existing NAT devices and works through an arbitrary number of tandem NATs, making it deployable without cooperation from network operators—addressing the core limitation of MIDCOM, which requires NAT upgrades and a control relationship.
A STUN server MUST be prepared to receive Binding Requests on four address/port combinations: (A1,P1), (A2,P1), (A1,P2), and (A2,P2), where A1/P1 is the primary address/port and A2/P2 are advertised via CHANGED-ADDRESS.
Clients MUST continue to listen for Binding Responses for 10 seconds after the first response. If additional responses with different message types or different MAPPED-ADDRESSes arrive, or if more than twice as many responses as requests are received, the client MUST NOT use the MAPPED-ADDRESS from any of those responses and SHOULD alert the user.
Clients SHOULD retransmit Binding Requests starting at 100 ms, doubling each interval until reaching 1600 ms, then retransmitting at 1600 ms intervals for a total of 9 transmissions; if no response is received 1600 ms after the final retransmission (9500 ms total), the transaction is considered failed.
If a client that sent a MESSAGE-INTEGRITY attribute receives a Binding Response without one, it MUST discard the response. If the computed HMAC differs from the one in the response, the client MUST discard the response and SHOULD alert the user about a possible attack.
If the server encounters any attribute with a type value <= 0x7fff that it does not understand, it MUST generate a Binding Error Response (or Shared Secret Error Response) with ERROR-CODE 420 and MUST include an UNKNOWN-ATTRIBUTES attribute listing the unrecognized mandatory attributes.
Shared Secret Requests MUST be received on a TLS connection; if not, the server MUST generate a Shared Secret Error Response with ERROR-CODE 433. Client TLS authentication MUST NOT be performed to avoid computational DoS attacks.
The Binding Request transaction ID MUST be uniformly and randomly distributed between 0 and 2^128 − 1; any two non-identical requests sent to different servers or from different source addresses/ports MUST carry different transaction IDs.
The client MUST verify the TLS server's identity when obtaining a shared secret, following the procedures of RFC 2818 Section 3.1, treating the domain name or IP address used in discovery as the URI host portion.
The PASSWORD attribute MUST contain at least 128 bits of randomness, MUST be unguessable, and MUST be a cryptographically random function of the username; the probability of assigning the same password to two different usernames MUST be vanishingly small.
The server MUST add a MAPPED-ADDRESS attribute to every Binding Response, set to the source IP address and port observed in the Binding Request. SOURCE-ADDRESS and CHANGED-ADDRESS attributes MUST also be added.
The server MUST issue each USERNAME a validity period of at least 10 minutes (meaning it can compute the corresponding password) and MUST invalidate the username after 30 minutes; additionally, it MUST hand out a different username for each distinct Shared Secret Request (distinguished by transaction ID).
The TLS ciphersuite TLS_RSA_WITH_AES_128_CBC_SHA SHOULD be used for Shared Secret Requests; the server SHOULD present a site certificate.
NAT type discovery uses three sequential Binding Request tests: Test I (plain request) reveals whether a NAT exists and the public mapping; Test II (change-IP + change-port flags) distinguishes full-cone from other types; Test III (change-port only) distinguishes restricted cone from port-restricted cone. Symmetric NAT is identified when Test I repeated to the CHANGED-ADDRESS server yields a different MAPPED-ADDRESS.
STUN defines 11 attribute types: MAPPED-ADDRESS (0x0001), RESPONSE-ADDRESS (0x0002), CHANGE-REQUEST (0x0003), SOURCE-ADDRESS (0x0004), CHANGED-ADDRESS (0x0005), USERNAME (0x0006), PASSWORD (0x0007), MESSAGE-INTEGRITY (0x0008), ERROR-CODE (0x0009), UNKNOWN-ATTRIBUTES (0x000a), and REFLECTED-FROM (0x000b).
STUN defines six message types: Binding Request (0x0001), Binding Response (0x0101), Binding Error Response (0x0111), Shared Secret Request (0x0002), Shared Secret Response (0x0102), and Shared Secret Error Response (0x0112).
STUN server discovery uses DNS SRV records (RFC 2782) with service name 'stun', protocol 'udp' for Binding Requests or 'tcp' for Shared Secret Requests; if no SRV records are found, an A record lookup is performed against the configured domain name.
The REFLECTED-FROM attribute is present in Binding Responses only when the request contained RESPONSE-ADDRESS; it contains the source IP address and port of the requester (or the origin of the shared-secret request) to provide traceability and prevent STUN being used as a DoS reflector.
STUN is assigned the well-known port 3478 for both TCP (Shared Secret Requests) and UDP (Binding Requests). Administrators SHOULD use this port in DNS SRV records but MAY use other ports.
STUN servers are vulnerable to DNS-based attacks (fake SRV records redirecting clients to a rogue server), rogue router/NAT attacks (rewriting the source address of STUN requests to control the returned MAPPED-ADDRESS), and MITM attacks; the countermeasure for all these is integrity protection via HMAC over requests and responses using a TLS-negotiated shared secret.
STUN servers SHOULD limit the number of simultaneous TLS connections (using LRU eviction) and the number of stored shared secrets to mitigate resource exhaustion attacks launched via the Shared Secret Request mechanism.
The four primary attacks on STUN (DDoS amplification, client silencing, identity assumption, and eavesdropping) all require an attacker to inject a Binding Response with a forged MAPPED-ADDRESS. All such attacks require the attacker to know the 128-bit random transaction ID, which necessitates eavesdropping on or intercepting STUN requests.
All STUN messages begin with a 20-byte header containing a 16-bit Message Type field, a 16-bit Message Length field (excluding the header), and a 128-bit Transaction ID used to correlate requests and responses.
STUN attributes are TLV-encoded with a 16-bit Type, 16-bit Length (value length in bytes), and variable-length Value. Attributes with type <= 0x7fff are mandatory to understand; those > 0x7fff are optional and may be ignored.
The CHANGE-REQUEST attribute is 32 bits with two meaningful flag bits: bit A ('change IP') requests the server respond from a different IP address, and bit B ('change port') requests response from a different port; all other bits are zero.
The ERROR-CODE attribute encodes a 3-digit response code by separating the hundreds digit (Class, 1–6) from the remainder (Number, 0–99), followed by a variable-length UTF-8 Reason Phrase whose byte length MUST be a multiple of 4.
The MAPPED-ADDRESS attribute encodes an 8-bit address family (always 0x01 for IPv4), a 16-bit port in network byte order, and a 32-bit IPv4 address; the first 8 bits are ignored for alignment purposes.
The MESSAGE-INTEGRITY attribute contains a 20-byte HMAC-SHA1 computed over the STUN message (including header) up to but not including the MESSAGE-INTEGRITY attribute itself, zero-padded to a multiple of 64 bytes; it MUST be the last attribute in any message.
The UNKNOWN-ATTRIBUTES attribute contains a list of 16-bit attribute type values that were not understood; if the count is odd, one attribute type MUST be repeated so the total length is a multiple of 4 bytes.