Session Traversal Utilities for NAT (STUN)
obsoleted by
- rfc-8489 — Session Traversal Utilities for NAT (STUN)
obsoletes
- rfc-3489 — STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)
updated by
Extracted elements (30)
Placing the magic cookie 0x2112A442 in the 32 bits formerly used as part of RFC 3489's 128-bit transaction ID achieves backwards-compatible detection of RFC 5389 clients without changing the overall message structure, allowing servers to infer support for XOR-MAPPED-ADDRESS and other new attributes.
STUN is intentionally a tool rather than a complete NAT traversal solution, reversing the RFC 3489 approach. Classic STUN's NAT classification algorithm was found faulty (many NATs did not fit the defined types), and it could not determine whether a learned address would actually be reachable by a peer. Complete solutions such as ICE incorporate STUN as one component.
XOR-MAPPED-ADDRESS was introduced because some NATs apply misguided ALG functions that rewrite binary payloads resembling IP addresses, corrupting MAPPED-ADDRESS values and breaking HMAC message-integrity checks. XOR obfuscation with the magic cookie prevents NATs from recognizing and rewriting the reflexive address.
A server detects RFC 3489 clients by the absence of 0x2112A442 in the magic cookie field. When detected, the server SHOULD echo the magic cookie value from the request back in the response and insert MAPPED-ADDRESS instead of XOR-MAPPED-ADDRESS. RFC 3489-compatible implementations SHOULD NOT be used where STUN is multiplexed with other protocols.
For STUN over TCP/TLS-over-TCP, if no response is received within Ti seconds (SHOULD default to 39.5 s) after the SYN, the transaction times out. A TCP connection failure or reset before a response is received also causes the transaction to fail.
In the long-term credential mechanism, if a request lacks MESSAGE-INTEGRITY the server MUST respond with error 401 including REALM and NONCE. If the NONCE is stale, the server MUST respond with error 438 (Stale Nonce) including a new NONCE and REALM.
In the short-term credential mechanism, a request or indication MUST include both USERNAME and MESSAGE-INTEGRITY. If either is absent in a request, the server MUST reject it with error 400 (Bad Request); if absent in an indication, the agent MUST silently discard it.
The default STUN port is 3478 for both UDP and TCP; the default TLS port is 5349. DNS SRV service names are 'stun' (plain) and 'stuns' (TLS). The port in DNS MUST reflect the port on which the server is actually listening; administrators SHOULD publish SRV records.
The transaction ID MUST be uniformly and randomly chosen from 0..2^96-1 and SHOULD be cryptographically random. A new transaction ID MUST be chosen for new transactions; retransmissions reuse the same ID. Success and error responses MUST carry the same transaction ID as their corresponding request.
Unknown comprehension-optional attributes MUST be ignored. Unknown comprehension-required attributes in a request cause the server to reply with error 420 (Unknown Attribute) including an UNKNOWN-ATTRIBUTES attribute. Unknown comprehension-required attributes in a success or indication response cause the response or indication to be discarded.
When retrying after a 401 (Unauthorized) response, the client MUST NOT retry if it is not changing the USERNAME, REALM, or password from the previous attempt. On a 438 (Stale Nonce) response, the client MUST retry using the new NONCE supplied in the response.
When sending STUN over UDP, the client SHOULD retransmit with exponential backoff beginning at RTO (initial value SHOULD be configurable, SHOULD be >500 ms, default 500 ms for fixed-line). The client retransmits up to Rc times (default 7) and waits Rm*RTO (default Rm=16) after the last request before declaring failure.
When STUN runs standalone over TLS-over-TCP, TLS_RSA_WITH_AES_128_CBC_SHA MUST be implemented at minimum. The client MUST verify the server certificate and identity per RFC 2818 Section 3.1; if the certificate is invalid or does not identify the correct party, the client MUST NOT proceed with the STUN transaction.
The ALTERNATE-SERVER mechanism lets a server redirect a client by responding with error 300 (Try Alternate) and an ALTERNATE-SERVER attribute. If the client has already tried the redirected server within the last five minutes, it MUST ignore the redirection to prevent infinite redirect loops.
The FINGERPRINT attribute contains CRC-32 of the STUN message (up to but excluding FINGERPRINT itself) XOR'd with 0x5354554e. When present, FINGERPRINT MUST be the last attribute in the message, appearing after MESSAGE-INTEGRITY.
The long-term credential mechanism uses a digest challenge/response: the client sends an initial unauthenticated request; the server rejects it with 401 providing REALM and NONCE; the client retries with USERNAME, REALM, NONCE, and MESSAGE-INTEGRITY. Nonces may be invalidated by the server to provide additional security.
The magic cookie field MUST contain 0x2112A442 in network byte order. It occupies 32 bits formerly part of RFC 3489's 128-bit transaction ID, allowing servers to distinguish RFC 5389 from RFC 3489 clients and aiding protocol demultiplexing.
The MAPPED-ADDRESS attribute encodes a reflexive transport address as an 8-bit address family, 16-bit port, and 32-bit (IPv4) or 128-bit (IPv6) address in network byte order. It is retained only for backwards compatibility with RFC 3489 clients.
The MESSAGE-INTEGRITY attribute contains a 20-byte HMAC-SHA1 over the STUN message up to and including MESSAGE-INTEGRITY itself. For long-term credentials the key is MD5(username:realm:SASLprep(password)); for short-term credentials it is SASLprep(password).
The USERNAME attribute is a variable-length UTF-8 value of less than 513 bytes, processed with SASLprep. It identifies the username/password combination used for message-integrity checks and is required by both short-term and long-term credential mechanisms.
The XOR-MAPPED-ADDRESS attribute encodes the reflexive transport address XOR'd with the magic cookie (IPv4) or with the concatenation of magic cookie and 96-bit transaction ID (IPv6). X-Port is the mapped port XOR'd with the most significant 16 bits of the magic cookie.
IANA maintains a STUN Attribute Registry spanning 0x0000–0xFFFF, split into comprehension-required (0x0000–0x7FFF) and comprehension-optional (0x8000–0xFFFF) ranges. Initial entries include MAPPED-ADDRESS (0x0001), USERNAME (0x0006), MESSAGE-INTEGRITY (0x0008), ERROR-CODE (0x0009), XOR-MAPPED-ADDRESS (0x0020), FINGERPRINT (0x8028), and others.
IANA maintains a STUN Error Code Registry. This document defines: 300 (Try Alternate), 400 (Bad Request), 401 (Unauthorized), 420 (Unknown Attribute), 438 (Stale Nonce), and 500 (Server Error). New error codes in the 300–399 and 400–499 ranges require IETF review.
IANA maintains a STUN Methods Registry. This document registers one method: Binding (0x001). Values 0x000–0x07F require IETF review; 0x080–0x0FF are designated expert review. New methods MUST indicate which message classes (request, indication, success response, error response) are permitted.
An attacker can use STUN as a DDoS amplifier (Attack I) by sending Binding requests with a victim's IP as the source address, directing server responses at the victim. Requiring authentication prevents unauthenticated amplification but is not always practical for public servers.
Outside attackers can inject or modify STUN messages to cause clients to learn incorrect reflexive addresses, silence clients, or amplify a DDoS against a third party by spoofing source addresses in Binding requests. Message integrity (HMAC-SHA1) and TLS mitigate injection; each STUN usage must assess which attacks apply.
RFC 5389 includes a hash agility plan: MESSAGE-INTEGRITY currently uses HMAC-SHA1 (with an MD5-derived key for long-term credentials). If SHA-1 is found cryptographically broken, a new attribute will be defined replacing MESSAGE-INTEGRITY with a stronger hash algorithm.
All STUN messages start with a 20-byte header: 16-bit message type, 16-bit message length, 32-bit magic cookie (0x2112A442), and 96-bit transaction ID. The most significant 2 bits MUST be zeroes, enabling demultiplexing from other protocols sharing the same port.
Each STUN attribute is TLV-encoded: 16-bit type, 16-bit length (value bytes before padding), variable-length value padded to a 32-bit boundary. Attributes with type 0x0000–0x7FFF are comprehension-required; 0x8000–0xFFFF are comprehension-optional.
The 14-bit message type field interleaves a 12-bit method (M11–M0) and 2-bit class (C1–C0). Class encodings: 0b00=request, 0b01=indication, 0b10=success response, 0b11=error response. A Binding request encodes to 0x0001; a Binding success response to 0x0101.