Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)
obsoletes
Extracted elements (32)
Permissions mimic RFC 4787 address-restricted NAT filtering and use the same 5-minute lifetime as compliant NATs, specifically to address enterprise IT concerns that TURN could be used to bypass corporate firewall security policies.
TURN is designed to run as a userspace application without special OS privileges to simplify deployment and allow integration into peer-to-peer applications. A consequence is that Diffserv, TTL, and ECN fields may not be preserved across the relay, and there is no end-to-end IP fragmentation.
TURN supports TCP and TLS-over-TCP between client and server because some enterprise firewalls block UDP entirely. TCP's three-way handshake and explicit teardown give firewalls clearer signals about intended connections than stateless UDP, so those firewalls permit TCP while blocking UDP.
TURN uses a distinct Refresh method rather than reusing Allocate for keepalives so that the client is explicitly notified if the allocation has vanished on the server. Using Allocate for refresh would risk silently creating a new allocation instead of detecting loss of the original.
Dual-stack TURN clients MUST implement Happy Eyeballs (RFC 8305): querying both A and AAAA records and racing connections on both address families. For UDP, the client sends unauthenticated Allocate requests to both families and uses the first returning a 401; for DTLS, the first completed handshake wins and the other is terminated with close_notify.
TURN supports IPv4-to-IPv6, IPv6-to-IPv6, and IPv6-to-IPv4 packet translation at the relay. If a server performing IPv4-to-IPv6 translation cannot access the DF bit state in the IPv4 header, it MUST reject Allocate requests that include a DONT-FRAGMENT attribute.
A TURN server MUST support UDP transport between the client and server, and SHOULD support TCP, TLS-over-TCP, and DTLS-over-UDP. The 'turns' URI scheme MUST be used when TURN runs over TLS-over-TCP or DTLS-over-UDP; the 'turn' scheme MUST be used otherwise. Default ports are 3478 (UDP/TCP) and 5349 (TLS/DTLS).
All requests after the initial Allocate MUST use the same username as that used to create the allocation. If an authenticated non-Allocate request identifies an existing allocation but uses a different username, the server MUST reject it with a 441 (Wrong Credentials) error to prevent allocation hijacking.
Clients MUST NOT include both REQUESTED-ADDRESS-FAMILY and ADDITIONAL-ADDRESS-FAMILY attributes in the same Allocate request. Neither attribute may appear alongside a RESERVATION-TOKEN attribute, since the reserved address is already determined and its family cannot be further constrained.
For any TURN message other than an Allocate request, if the 5-tuple does not identify an existing allocation, the message MUST be rejected with a 437 (Allocation Mismatch) error if it is a request, or silently ignored if it is an indication or ChannelData message. A client receiving 437 on a non-Allocate MUST assume the allocation no longer exists.
The client MUST include a REQUESTED-TRANSPORT attribute in every Allocate request. If absent or malformed, the server MUST reject with 400 (Bad Request); if the specified protocol is unsupported, the server MUST reject with 442 (Unsupported Transport Protocol). In this specification, the only valid transport is UDP (protocol number 17).
The server MUST NOT store passwords in plaintext; it MUST store only the key value, which is a cryptographic hash over the username, realm, and password as specified in RFC 8489 Section 16.1.3.
The server SHOULD generate a fresh random nonce for each new Allocate attempt and SHOULD expire the nonce at least once per hour during the allocation's lifetime, following the randomness recommendations in RFC 4086, to prevent replay attacks.
The TURN server SHOULD allocate relay ports only from the dynamic/private port range 49152–65535 and SHOULD NOT allocate from the well-known port range 0–1023, to prevent clients from using TURN to expose standard services and to avoid conflicts with the OS and other applications.
TURN servers and clients MUST implement the STUN long-term credential mechanism defined in RFC 8489. If the server requires authentication, Allocate requests MUST be authenticated via the long-term credential mechanism or the STUN Third-Party Authorization extension (RFC 7635).
A Channel binding associates a 16-bit channel number (range 0x4000–0x7FFF) with a specific peer transport address. Channel bindings last 10 minutes unless refreshed by sending another ChannelBind request. They enable use of the more compact ChannelData message instead of 36-byte Send/Data indications.
A Permission consists of a peer IP address and a lifetime. The server only relays inbound UDP datagrams whose source IP matches an installed permission; datagrams from non-permitted peers are silently discarded. Permissions expire after 5 minutes if not refreshed, mirroring RFC 4787 NAT address-restricted filtering behavior.
An Allocation is the core TURN server state structure, consisting of: relayed transport address(es), the 5-tuple, authentication information (username, realm, nonce, key hash), time-to-expiry per relayed transport address, a list of permissions, and a list of channel-to-peer bindings. The relayed transport address MUST be unique across all allocations.
The 5-tuple (client IP address, client port, server IP address, server port, and transport protocol) uniquely identifies both the client-to-server communication stream and the allocation on the server. At the server, the client's server-reflexive address replaces the host transport address in the tuple.
The Send mechanism transfers application data via Send indications (client to server) and Data indications (server to client). A Send indication carries an XOR-PEER-ADDRESS attribute identifying the target peer's server-reflexive transport address and a DATA attribute holding the payload. The server extracts the payload and forwards it as a UDP datagram.
This document registers six STUN methods in the IANA STUN Methods Registry: Allocate (0x003), Refresh (0x004), Send (0x006), Data (0x007), CreatePermission (0x008), and ChannelBind (0x009).
This document registers the following STUN error response codes: 403 (Forbidden), 437 (Allocation Mismatch), 440 (Address Family not Supported), 441 (Wrong Credentials), 442 (Unsupported Transport Protocol), 486 (Allocation Quota Reached), and 508 (Insufficient Capacity).
This document registers thirteen STUN attributes: CHANNEL-NUMBER (0x000C), LIFETIME (0x000D), XOR-PEER-ADDRESS (0x0012), DATA (0x0013), XOR-RELAYED-ADDRESS (0x0016), REQUESTED-ADDRESS-FAMILY (0x0017), EVEN-PORT (0x0018), REQUESTED-TRANSPORT (0x0019), DONT-FRAGMENT (0x001A), RESERVATION-TOKEN (0x0022), ADDITIONAL-ADDRESS-FAMILY (0x8000), ADDRESS-ERROR-CODE (0x8001), and ICMP (0x8004).
Send and Data indications are never authenticated because STUN's long-term credential mechanism does not support authenticating indications. An on-path attacker can therefore inject bogus Send indications. The permission requirement (peer IP must be pre-authorized) provides partial mitigation; full end-to-end security requires application-level encryption.
Servers SHOULD reject Allocate requests that would relay traffic to IANA-reserved or locally significant IP addresses—including RFC 1918 private ranges, loopback, and link-local—to prevent TURN from being used as a proxy to attack internal networks behind the TURN server.
The Tunnel Amplification Attack uses TURN to amplify traffic by sending encapsulated packets through the relay, where the inner packet contains a spoofed source address. The permission system partially mitigates this by requiring prior installation of a permission for each peer IP before the server relays traffic from that peer.
The TURN Loop Attack causes a server to relay traffic destined for another TURN allocation, creating a traffic amplification loop. Servers MUST verify that the peer address specified in XOR-PEER-ADDRESS is not the server's own relayed transport address to prevent this attack.
The ADDITIONAL-ADDRESS-FAMILY attribute is a 32-bit field: the first 8 bits specify the additional address family (value 0x02 for IPv6), and the remaining 24 bits are RFFU. Including it in an Allocate request signals the server to allocate both one IPv4 and one IPv6 relay address in a single transaction.
The CHANNEL-NUMBER attribute is a 32-bit field: the upper 16 bits carry the channel number and the lower 16 bits are RFFU and MUST be set to zero on transmission and ignored on reception.
The ChannelData message has a 4-byte header: a 16-bit channel number followed by a 16-bit length field giving the byte count of the data payload. Unlike other TURN messages, it does not use the STUN header, making it substantially more compact than Send/Data indications for high-volume data exchange.
The ICMP attribute is included in Data indications when the server relays an ICMP error to the client. It carries the ICMP type (8 bits), ICMP code (8 bits), and additional ICMP-type-specific data. ICMP forwarding always uses Data indications even when channel bindings are in use for UDP data.
The REQUESTED-TRANSPORT attribute is a 32-bit field: the first 8 bits specify the IANA protocol number for the desired server-to-peer transport (17 for UDP), and the remaining 24 bits are RFFU and MUST be zero. This attribute is mandatory in Allocate requests.